function puzzle(){

    this.go = 0;    

    this.cellSize= 19;
    this.cellGap = 9;
    this.rowcount = 7;
    this.colcount = 7;
    this.noSq = this.rowcount * this.colcount;

    this.theGrid = new Array();
    this.squares = new Array('sq1.jpg','sq2.jpg','sq3.jpg','sq4.jpg','sq5.jpg','sq6.jpg','sq7.jpg','sq8.jpg');
    this.blanks = new Array();
    this.blankscoords = new Array();
    this.noBl = 7;
    
    this.acceleration = 5;
    this.speed = 5;
    this.timeout = 10;
    this.delay = 1;

    this.origpos = new Array();
    this.slidetimeout = null;

    function initGrid(){

        // Init this.blanks
        var countblanks = 0
        while (countblanks < this.noBl){
            var rannum = Math.floor(Math.random()*this.noSq);
            this.blanks[rannum] = 1;
            countblanks++;
        }
        
        var gridEl = document.getElementById('gridArea');
        gridEl.innerHTML = "";
        var sqNo = 0;
        var elNo = 0;
        while (this.theGrid.length < this.rowcount){
            var row = new Array();
            while (row.length < this.colcount){
                if (this.blanks[elNo] == 1){
                    var element = document.createElement('div');
                    element.id = 'sq-'+this.theGrid.length+'-'+row.length;
                    element.style.width = this.cellSize+ 'px';
                    element.style.height = this.cellSize+ 'px';
                    var newL = this.cellGap + (row.length * (this.cellSize+ this.cellGap));
                    var newT = this.cellGap + (this.theGrid.length * (this.cellSize+ this.cellGap));
                    element.style.left = newL + 'px';
                    element.style.top = newT + 'px';
                    element.style.display = 'block';
                    this.blankscoords.push(new Array(row.length,this.theGrid.length));
                }
                else{
                    var element = document.createElement('img');
                    element.id = 'sq-'+this.theGrid.length+'-'+row.length;
                    element.style.width = this.cellSize+ 'px';
                    element.style.height = this.cellSize+ 'px';
                    var newL = this.cellGap + (row.length * (this.cellSize+ this.cellGap));
                    var newT = this.cellGap + (this.theGrid.length * (this.cellSize+ this.cellGap));
                    element.style.left = newL + 'px';
                    element.style.top = newT + 'px';
                    element.style.display = 'block';
                    element.src = 'images/'+this.squares[sqNo];
                }
                elNo++;
                sqNo++;
                if (sqNo == this.squares.length) sqNo = 0;
                gridEl.appendChild(element);
                row.push(element);
            }
            this.theGrid.push(row);
        }
        
        var gh = this.cellGap + (this.rowcount * (this.cellSize+ this.cellGap));
        var gw = this.cellGap + (this.colcount * (this.cellSize+ this.cellGap));
        document.getElementById('startstop').style.width = gw + 'px';
        document.getElementById('loadingpuzzle').style.display = "none";
        gridEl.style.width = gw + 'px';
        gridEl.style.height = gh + 'px';
    }
    
    this.initGrid = initGrid;
}

function startPuz(puz,thelink){
    if (puz.go == 0){
        thelink.style.backgroundImage = "url('images/icon_stop_40x40.png')";
        puz.go = 1;
        startSliding(puz);
    }
    else{
        thelink.style.backgroundImage = "";
        puz.go = 0;
    }
}

function stopPuz(puz){
    $('startstop').style.backgroundImage = "";

    puz.go = 0;    

    puz.theGrid = new Array();
    puz.squares = new Array('sq1.jpg','sq2.jpg','sq3.jpg','sq4.jpg','sq5.jpg','sq6.jpg','sq7.jpg','sq8.jpg');
    puz.blanks = new Array();
    puz.blankscoords = new Array();
    
    puz.origpos = new Array();
    puz.slidetimeout = null;
}

function isBlank(element){ return element.tagName == 'DIV'; }

function startSliding(puz){
    var ranblank = Math.floor(Math.random()*(puz.blankscoords.length));
    var rancol = puz.blankscoords[ranblank][0];
    var ranrow = puz.blankscoords[ranblank][1];
    var rancol2 = 0;
    var ranrow2 = 0;
    
    var blank = puz.theGrid[ranrow][rancol];
    
    if (ranrow == puz.rowcount - 1)                     ranrow2 = ranrow - 1;
    else if (ranrow == 0)                               ranrow2 = ranrow + 1;
    else if (Math.floor(Math.random()*100) % 2 == 0)   ranrow2 = ranrow + 1;
    else                                                 ranrow2 = ranrow - 1;
    
    if (rancol == puz.colcount - 1)                      rancol2 = rancol - 1;
    else if (rancol == 0)                                rancol2 = rancol + 1;
    else if (Math.floor(Math.random()*100) % 2 == 0)    rancol2 = rancol + 1;
    else                                                  rancol2 = rancol - 1;
    
    var udlr = (Math.floor(Math.random()*100));
    if (udlr > 50) ranrow2 = ranrow;
    else rancol2 = rancol;
    
//    alert(puz.blankscoords.length+"\n"+puz.blankscoords+"\n\nBlank: "+rancol+","+ranrow+"\nPic: "+rancol2+","+ranrow2);

    var element = puz.theGrid[ranrow2][rancol2];

    if (isBlank(element)) startSliding(puz);
    else {
        swapPos(puz,element.id,blank.id);

        var swapTemp = puz.theGrid[ranrow][rancol];
        puz.theGrid[ranrow][rancol] = puz.theGrid[ranrow2][rancol2]
        puz.theGrid[ranrow2][rancol2] = swapTemp;

        puz.blankscoords[ranblank] = new Array(rancol2,ranrow2);
    }
}

function swapPos(puz,id1,id2){
    if (puz.slidetimeout == null){
        var el1 = document.getElementById(id1);
        var el2 = document.getElementById(id2);
        
        puz.origpos[0] = el1.offsetLeft;
        puz.origpos[1] = el1.offsetTop;
        
        swapping(puz,el1,el2);
    }
}

function swapping(puz,element1,element2){
    var l1 = element1.offsetLeft;
    var l2 = element2.offsetLeft;
    var t1 = element1.offsetTop;
    var t2 = element2.offsetTop;    
    
    if (t1 < t2){
        var newT = t1 + puz.speed + (Math.floor((t2 - t1) / puz.acceleration));
        element1.style.top = (newT > t2) ? t2 + 'px' : newT + 'px';
    }
    else if (t1 > t2){
        var newT = t1 - puz.speed - (Math.floor((t1 - t2) / puz.acceleration));
        element1.style.top = (newT < t2) ? t2 + 'px' : newT + 'px';
    }
    
    if (l1 < l2){
        var newL = l1 + puz.speed + (Math.floor((l2 - l1) / puz.acceleration));
        element1.style.left = (newL > l2) ? l2 + 'px' : newL + 'px';
    }
    else if (l1 > l2){
        var newL = l1 - puz.speed - (Math.floor((l1 - l2) / puz.acceleration));
        element1.style.left = (newL < l2) ? l2 + 'px' : newL + 'px';
    }
    
    if (l1 == l2 && t1 == t2){
    
        element2.style.left = puz.origpos[0] + 'px';
        element2.style.top = puz.origpos[1] + 'px';
        puz.slidetimeout = null;

        if (puz.go == 1) startSliding(puz);
    }
    else puz.slidetimeout = setTimeout(function(){ swapping(puz,element1,element2); },puz.timeout);
}
