var maxNumber = 9;
var tFixedClass = "numb";
var poss = false;
var curSqNum;
var buttonStr;
var curDigit = 1;
var sx = 3;
var sy = 3;
var sxy = 9;
var smax = 81;
var V = new Object();

function widthFromPixels() {
    var width = 0;
    for (var i=0;i<arguments.length;i++) {
        var float = parseFloat(arguments[i]);
        if (!isNaN(float)) {
            width = width + Math.ceil(float);
        }
    }
    return width;
}

function setWidths() {
    // Grid
    //alert($(".ksq").css("width") + $(".ksq").css("border-left-width") + $(".ksq").css("border-right-width"));
    var ksqWidth = widthFromPixels($(".ksq").css("width"),$(".ksq").css("border-left-width"),$(".ksq").css("border-right-width"));
    if ($("#S1").hasClass("sq")) {
        var sqWidth = ksqWidth + widthFromPixels($(".sq").css("padding-left"),$(".sq").css("padding-right"),$(".sq").css("border-left-width"),$(".sq").css("border-right-width"));
    } else {
        var sqWidth = ksqWidth + widthFromPixels($(".isq").css("padding-left"),$(".isq").css("padding-right"),$(".isq").css("border-left-width"),$(".isq").css("border-right-width"));
    }
    var gridWidth = sx - 1 + (sxy * sqWidth) + widthFromPixels($("#grid").css("border-left-width"),$("#grid").css("border-right-width"));
    //alert("ksqWidth:"+ksqWidth+" sqWidth:"+sqWidth+" gridWidth:"+gridWidth);
        
    // Buttons
    var numButtons = jStrDigits.length + 1;
    var buttonWidth = widthFromPixels($(".dsq").css("width"),$(".dsq").css("border-left-width"),$(".dsq").css("border-right-width"));
    var digitWidth = numButtons * buttonWidth + widthFromPixels($("#din").css("border-left-width"),$("#din").css("border-right-width"));
    var outerWidth = gridWidth;
    if (digitWidth > gridWidth) {
        outerWidth = digitWidth;
    }
    $("#edge").css("width",gridWidth+"px");
    $(".outer").css("width",outerWidth+"px");
    $("#digits").css("width",digitWidth+"px");
    //$("#digits").fadeIn(1000);    
}

function resizeTo(width) {
    var gridBorders = widthFromPixels($("#grid").css("border-left-width"),$("#grid").css("border-right-width"));
    var ksqBorders = widthFromPixels($(".ksq").css("border-left-width"),$(".ksq").css("border-right-width"));
    if ($("#S1").hasClass("sq")) {
        var sqBorders = widthFromPixels($(".sq").css("padding-left"),$(".sq").css("padding-right"),$(".sq").css("border-left-width"),$(".sq").css("border-right-width"));
    } else {
        var sqBorders = widthFromPixels($(".isq").css("padding-left"),$(".isq").css("padding-right"),$(".isq").css("border-left-width"),$(".isq").css("border-right-width"));
    }
    var size = Math.floor( (width - gridBorders)/sxy - sqBorders - ksqBorders);
    
    var numButtons = jStrDigits.length + 1;
    var dsqBorders = widthFromPixels($(".dsq").css("border-left-width"),$(".dsq").css("border-right-width"));
    var digitBorders = widthFromPixels($("#din").css("border-left-width"),$("#din").css("border-right-width"));
    var sizeFromDigits = Math.floor( (width - digitBorders) / numButtons - dsqBorders);
    if (sizeFromDigits < size) {
        size = sizeFromDigits;
    }
    setSizes(size);
}

function setSizes(newSize) {
    $(".ksq").css("width",newSize+"px").css("height",newSize+"px");
    $(".dsq").css("width",newSize+"px").css("height",newSize+"px").css("font-size",(newSize-2)+"px");
    $(".ksum").css("font-size",Math.ceil(newSize/2)+"px");
    $(".poss").css("width",newSize+"px").css("height",newSize+"px").css("font-size",Math.ceil(newSize/2)+"px");
    $(".num").css("width",newSize+"px").css("font-size",(newSize-1)+"px");
    $(".numb").css("width",newSize+"px").css("font-size",(newSize-1)+"px");
    setWidths(); 
}

function makeBigger() {
    var size = parseInt($(".ksq").css("width"));
    if (size < 30) {
        var newSize = Math.floor(1.25 * size);
        setSizes(newSize);
    }
}

function makeSmaller() {
    var size = parseInt($(".ksq").css("width"));
    if (size > 12) {
        var newSize = Math.floor(0.8 * size);
        setSizes(newSize);
    }
}

function togglePoss() {
    poss = !poss;
    var el = GetObj('poss');
    if (el != null) {
        if (poss) {
            el.style.fontSize = '8px';
        } else {
            el.style.fontSize = '16px';
        }
    }
}

function GetObj(id){
    if (document.getElementById) {return document.getElementById(id);}
    else if (document.all) {return document.all[id];}
    else if (document.layers){return document.layers[id];}
    else {return null}
}

function doWheel(e){
    if (!e) var e = window.event;
    var delta = 0;
    if (e.wheelDelta) { /* IE/Opera. */
        delta = e.wheelDelta/120;
    } else if (e.detail) { /** Mozilla case. */
        delta = -e.detail/3;
    }
    
    // Get button number
    var buttonIndex = buttonStr.indexOf(curDigit);
    
    // Now handle delta
    if (delta > 0) {
        if (buttonIndex < sxy) {
            selectDigit(buttonStr.charAt(buttonIndex + 1));
        }
    } else if (delta < 0) {
        if (buttonIndex > 0) {
            selectDigit(buttonStr.charAt(buttonIndex - 1));
        }
    }
}

function doKeyUp(e){
    if (!e) var e = window.event;
    if (e.keyCode) code = e.keyCode;
    else if (e.which) code = e.which;     
    var char = String.fromCharCode(code);
    
    if (jStrDigits.indexOf(char) > -1) {
        selectDigit(char);  
    } else if (char == " ") {
        selectDigit('');
    }
    //alert('Character was ' + character + " Alt:" + e.altKey + " Shift:" + e.shiftKey + " Ctrl:" + e.ctrlKey);
}

function doButtonClick(e){
    if (!e) var e = window.event;
    selectDigit(getDigitFromButtonId(this.id));
}

function getDigitFromButtonId(id){
    var digit = '';
    if (id != "bs") {
        digit = id.substring(1, id.length);
    }
    return digit
}

function getButtonIdFromDigit(digit){
    var id = "bs";
    if (digit != "") {
        id = "b" + digit;
    }
    return id
}

function selectDigit(digit){
    if (digit == 's') {
        digit = '';
    }
    curDigit = digit;
    var el;
    el = GetObj('poss');
    if (el != null) {
        el.innerHTML = digit;   
    }  
    for (i=0;i<buttonStr.length;i++) {
        var char = buttonStr.charAt(i);
        var id = 'b' + char;
        var element = GetObj(id);
        el = GetObj(id);
        if (el != null) {
            el.style.backgroundColor="#ffffff";
        }
    }
    el = GetObj(getButtonIdFromDigit(digit));
    if (el != null) {
        el.style.backgroundColor="#ffffc0";
    }
}

function doSquareClick(e){
    if (!e) var e = window.event;
    var sq = getSquareFromId(this.id);
    if (sq != null) {
        var tid = "T"+getSquareNumFromId(this.id);
        if (!$("#"+tid).hasClass(tFixedClass)) {
            if (poss || e.shiftKey || e.ctrlKey) {
                setSquarePoss(sq);
            } else {
                setSquareNum(sq);
            }
        }
    }
}

function getSquareFromId(id){
    var sqId = "T" + id.substring(1, id.length);
    return GetObj(sqId);
}

function getPossIdFromId(id){
    return "P" + id.substring(1, id.length);
}

function getSquareNumFromId(id){
    return id.substring(1, id.length);
}

function setSquareNum(sq){
    if (sq != null) {
        if ($('#'+sq.id).html() != curDigit || !$('#'+sq.id).hasClass("num")) {
            $('#'+sq.id).html(curDigit);
        } else {
            $('#'+sq.id).html("");
        }
        var possId = getPossIdFromId(sq.id);
        $('#'+possId).html("");
        $('#'+possId).data("poss","");
        vSet(getSquareNumFromId(sq.id),sq.innerHTML)
    }
}

function setSquarePoss(sq){
    if (sq != null) {
        vSet(getSquareNumFromId(sq.id),"");
        sq.innerHTML = "";
        
        var possId = getPossIdFromId(sq.id);
        var possStr = $("#"+possId).data("poss");
        if (possStr == undefined) {
            possStr = "";
        }
        
        var newStr = "";
        var index = possStr.indexOf(curDigit);
        if (index == -1) {
            // Add Number
            var done = false;
            for (i=0;i<possStr.length;i++) {
                var char = possStr.charAt(i);
                if (!done && char > curDigit) {
                    newStr = newStr + curDigit;
                    done = true;
                }
                newStr = newStr + char;
            }
            if (!done) {
                newStr = newStr + curDigit;
            }
        } else {
            // Remove number
            var lines = new Array();
            lines = possStr.split("\n");
            for (i=0;i<possStr.length;i++) {
                var char = possStr.charAt(i);
                if (char != curDigit) {
                    newStr = newStr + char;
                }
            }
        }
        // Now format and set html
        var htmlStr = "";
        if (newStr.length > 6) {
            htmlStr = newStr.substring(0,3) + "<br/>" + newStr.substring(3,6);
        } else if (newStr.length > 4) {
            htmlStr = newStr.substring(0,3) + "<br/>" + newStr.substring(3);
        } else if (newStr.length > 2) {
            htmlStr = newStr.substring(0,2) + "<br/>" + newStr.substring(2);
        } else {
            htmlStr = newStr;
        }
        $("#"+possId).data("poss",newStr);
        $("#"+possId).html(htmlStr);    
    }
}

function showFinished() {
    $(".ok").animate({color:"#00C000"},1000);
    $(".wrong").animate({color:"#FF0000"},1000).animate({color:"#808080"},1000);
}

function showCheck() {
    $(".wrong").animate({color:"#FF0000"},1000).animate({color:"#808080"},1000);
}

function gridReset() {
    $(".poss").html("");
    $(".ok").css("color","#808080");
    $(".wrong").css("color","#808080");
    vInit();
}

function gridSolve() {
    $(".poss").html("");
    var sqNum = 1
    for (i=0;i<jStrAnswer.length;i++) {
        var char = jStrAnswer.charAt(i);
        $("#T"+sqNum).html(char);
        V["sq"+sqNum] = char;
        sqNum++;
    }
}

function vCheck() {
    var isOk = true;
    var sqNum = 1;
    for (i=0;i<jStrAnswer.length;i++) {
        var char = jStrAnswer.charAt(i);
        if (vGet(sqNum) != "" && vGet(sqNum) != char) {
            isOk = false;
        }
        sqNum++;
    }
    return isOk;
}

function vShow() {
    var vStr = "";
    var count = 0;
    for (i in V) {
        count++;
        if (V[i] != "" && V[i] != "s") {
            vStr = vStr + V[i];
        } else {
            vStr = vStr + ".";
        }
        if (count%sxy == 0) {
            vStr = vStr + "\n";
        }
    }
    return vStr;
}

function vCount() {
    var count = 0
    for (i in V) {
        if (V[i] != "" && V[i] != "s") {
            count++;
        }
    }
    return count;
}

function vGet(sqNum) {
    return V["sq"+sqNum];
}

function vSet(sqNum,val) {
    V["sq"+sqNum] = val;
    // Add classes
    $("#S" + sqNum).removeClass("empty ok wrong");
    $("#T" + sqNum).removeClass("empty ok wrong");
    $("#D" + sqNum).removeClass("empty ok wrong");
    $("#K" + sqNum).removeClass("empty ok wrong");
    if (val == "" || val == "s") {
        //$("#S" + sqNum).addClass("empty");
        $("#T" + sqNum).addClass("empty");
        //$("#D" + sqNum).addClass("empty");
        //$("#K" + sqNum).addClass("empty");
    } else if (val == jStrAnswer.charAt(sqNum - 1)) {
        //$("#S" + sqNum).addClass("ok");
        $("#T" + sqNum).addClass("ok");
        //$("#D" + sqNum).addClass("ok");
        //$("#K" + sqNum).addClass("ok");
    } else {
        //$("#S" + sqNum).addClass("wrong");
        $("#T" + sqNum).addClass("wrong");
        //$("#D" + sqNum).addClass("wrong");
        //$("#K" + sqNum).addClass("wrong");
    }
    // Check for finish
    if (vCount() == smax) {
        if (vCheck()) {
            showFinished();
        } else {
            showCheck();
        }
    }
}

function vInit() {
    var sqNum = 1;
    for (i=0;i<jStrPuzzle.length;i++) {
        var char = jStrPuzzle.charAt(i);
        if (char == "s") {
            V["sq"+sqNum] = "";
            $("#T"+sqNum).html("");
            //$("#S" + sqNum).addClass("empty");
            $("#T" + sqNum).addClass("empty");
            //$("#D" + sqNum).addClass("empty");
            //$("#K" + sqNum).addClass("empty");
        } else {
            V["sq"+sqNum] = char;
            $("#T"+sqNum).html(char);        
            //$("#S" + sqNum).addClass("fixed");
            $("#T" + sqNum).addClass("fixed");
            //$("#D" + sqNum).addClass("fixed");
            //$("#K" + sqNum).addClass("fixed");
        }
        sqNum++;
    }
}

function Init() {
    setWidths();
    vInit();
        
    // Button event handlers
    buttonStr = 's' + jStrDigits;
    for (i=0;i<buttonStr.length;i++) {
        var char = buttonStr.charAt(i);
        var id = 'b' + char;
        var element = GetObj(id);
        if (element != null) {
            element.onmouseover = function () {this.style.borderColor='#ffffc0'}
            element.onmouseout = function () {this.style.borderColor='#000000'}
            element.onclick = doButtonClick;
            if (element.captureEvents) element.captureEvents(Event.CLICK);
        }        
    }

    curDigit = buttonStr.charAt(1);
    selectDigit(curDigit);

    // Keyboard event handlers
    document.onkeyup = doKeyUp;
    
    // MouseWheel
    /** IE/Opera. */
    window.onmousewheel = document.onmousewheel = doWheel;    
    if (window.addEventListener) {
        /** DOMMouseScroll is for mozilla. */
        window.addEventListener('DOMMouseScroll', doWheel, false);
    }
    // Squares
    var prefix = new Array();
    prefix[0] = "T";
    prefix[1] = "D";
    prefix[2] = "K";
    prefix[3] = "P";
    for (var x in prefix)
    {
        for (var i=0;i<=smax;i++) {
            var id = prefix[x] + i;
            var element = GetObj(id);
            if (element != null) {
                //element.onmouseover = function () {this.style.backgroundColor='#ffffc0'}
                //element.onmouseout = function () {this.style.backgroundColor='#ffffff'}
                element.onclick = doSquareClick;
                if (element.captureEvents) element.captureEvents(Event.CLICK);
            }
        }
    }
}

function scalePopup() {
    var size = 36;
    $("#popin").css("font-size",size+"px");
    while(size > 10 &&
          ( $("#popin").outerWidth() > $("#popup").innerWidth() ||
            $("#popin").outerHeight() > $("#popup").innerHeight() )
          ) {
        var size = size - 2;
        $("#popin").css("font-size",size+"px");
    }
}

function hidePopup() {
    scalePopup();
    $("#popup").fadeOut(1000);   
}

function showPopup() {
    $("#popup").fadeIn("slow");
    scalePopup();
}

function saveState() {
    var numKey = jStrId + "-n";
    var penKey = jStrId + "-p";
    $.cookie(numKey, 'nums', { expires: 7 });
    $.cookie(penKey, 'poss', { expires: 7 });
}

function loadState() {
    var numKey = jStrId + "-n";
    var penKey = jStrId + "-p";
    alert("$.cookie(numKey)");
}

function SudokuInit(x,y) {
    sx = x;
    sy = y;
    sxy = sx * sy;
    smax = sxy * sxy;
    Init();
    hidePopup();
}

