
var puzzles;
var lastDraggedPuzzle;
var freeSpace;

function FifteenPuzzles(){
    puzzles = new Array();
    this.init = init;
    this.makeDraggable = makeDraggable;
    this.makeDroppable = makeDroppable;
    this.scramble = scramble;
    this.sort = sort;
}

function Puzzle(number, x, y, isDraggable, position){
    this.number = number;
    this.x = x;
    this.y = y;
    this.isDraggable = isDraggable;
    this.position = position;

}

function FreeSpace(x, y, position){
    this.x = x;
    this.y = y;
    this.position = position;
}

function init(){
    for (var i = 1; i <= 16; i++){
        var box_x = 0;
        var x;
        if (i < 5){
            x = box_x + (i - 1) * 50;
        } else if (5 <= i && i < 9){
            x = box_x + (i - 5) * 50;
        } else if (9 <= i  && i < 13){
            x = box_x + (i - 9) * 50;
        } else if (13 <= i  && i <= 16){
            x = box_x + (i - 13) * 50;
        }
        var box_y = 0;
        var y;
        if (i < 5){
            y = box_y;
        } else if (5 <= i  && i < 9){
            y = box_y + 50;
        } else if (9 <= i  && i < 13){
            y = box_y + 100;
        } else if (13 <= i  && i <= 16){
            y = box_y + 150;
        }
        var puzzle;
        if (i == 16){
            freeSpace = new FreeSpace(x, y, i);
        }else{
            puzzle = new Puzzle(i, x, y, false, i);
            puzzles[i] = puzzle;
        }
        if (i == 16){
            appendFreeSpace(freeSpace.x, freeSpace.y);
        }else{
            appendPuzzle(puzzle.x, puzzle.y, puzzle.number);
        }
    }


}


//find puzzles near freespace to make draggable
function makeDraggable(){
    for (var i = 1; i < 16; i++){
        if (freeSpace.x == puzzles[i].x || freeSpace.y == puzzles[i].y){
            if (puzzles[i].position == freeSpace.position - 1){
                makeRightDraggable(puzzles[i]);
            } else if (puzzles[i].position == freeSpace.position + 1){
                makeLeftDraggable(puzzles[i]);
            } else if (puzzles[i].position == freeSpace.position + 4){
                makeUpDraggable(puzzles[i]);
            } else if (puzzles[i].position == freeSpace.position - 4){
                makeDownDraggable(puzzles[i]);
            }
        }
    }
}


function makeUpDraggable(puzzle){
    //alert("puzzle " + puzzle.number + " must be draggable");
    var draggablePuzzle = new YAHOO.util.DD('puzzleId' + puzzle.number, 'puzzles', {
        isTarget : false
    });
    draggablePuzzle.startDrag = function (x, y){
        lastDraggedPuzzle = puzzle;
    }
    draggablePuzzle.onDragDrop = function (e, target){
        dragDropCommon();
    }
    draggablePuzzle.setXConstraint(0, 0);
    draggablePuzzle.setYConstraint(50, 0, 5);
     
}

function makeDownDraggable(puzzle){
    //alert("puzzle " + puzzle.number + " must be draggable");
    var draggablePuzzle = new YAHOO.util.DD('puzzleId' + puzzle.number, 'puzzles', {
        isTarget : false
    });
    draggablePuzzle.startDrag = function (x, y){
        lastDraggedPuzzle = puzzle;
    }
    draggablePuzzle.onDragDrop = function (e, target){
        dragDropCommon();
    }
    draggablePuzzle.setXConstraint(0, 0);
    draggablePuzzle.setYConstraint(0, 50, 5);
    
}

function makeLeftDraggable(puzzle){
    //alert("puzzle " + puzzle.number + " must be draggable");
    var draggablePuzzle = new YAHOO.util.DD('puzzleId' + puzzle.number, 'puzzles', {
        isTarget : false
    });
    draggablePuzzle.startDrag = function (x, y){
        lastDraggedPuzzle = puzzle;
    }
    draggablePuzzle.onDragDrop = function (e, target){
        dragDropCommon();
    }
    draggablePuzzle.setXConstraint(50, 0, 5);
    draggablePuzzle.setYConstraint(0, 0);
    
}

function makeRightDraggable(puzzle){
    //alert("puzzle " + puzzle.number + " must be draggable");
    var draggablePuzzle = new YAHOO.util.DD('puzzleId' + puzzle.number, 'puzzles', {
        isTarget : false
    });
    draggablePuzzle.startDrag = function (x, y){
        lastDraggedPuzzle = puzzle;
    }
    draggablePuzzle.onDragDrop = function (e, target){
        dragDropCommon();
    }
    draggablePuzzle.setXConstraint(0, 50, 5);
    draggablePuzzle.setYConstraint(0, 0);
     


}


function makeDroppable(){
    var droppableFreeSpace = new YAHOO.util.DDTarget('freeSpaceId', 'puzzles');
}


function scramble(){
    var box = new YAHOO.util.Element('box');
    while (box.hasChildNodes()) {
        box.removeChild(box.get('firstChild'));
    }
    var xTemp = freeSpace.x;
    var yTemp = freeSpace.y;
    var positionTemp = freeSpace.position;

    var n = Math.ceil(Math.random() * 15);
    var randomPuzzle = puzzles[n];
    freeSpace.x = randomPuzzle.x;
    freeSpace.y = randomPuzzle.y;
    freeSpace.position = randomPuzzle.position;

    randomPuzzle.x = xTemp;
    randomPuzzle.y = yTemp;
    randomPuzzle.position = positionTemp;

    appendFreeSpace(freeSpace.x, freeSpace.y);

    for (var i = 0; i < 20; i++){
        var randomPuzzle1 = puzzles[Math.ceil(Math.random() * 15)];
        var randomPuzzle2 = puzzles[Math.ceil(Math.random() * 15)];

        xTemp = randomPuzzle1.x;
        yTemp = randomPuzzle1.y;
        positionTemp = randomPuzzle1.position;

        randomPuzzle1.x = randomPuzzle2.x;
        randomPuzzle1.y = randomPuzzle2.y;
        randomPuzzle1.position = randomPuzzle2.position;

        randomPuzzle2.x = xTemp;
        randomPuzzle2.y = yTemp;
        randomPuzzle2.position =positionTemp;
    }

    for (i = 1; i < 16; i ++){
        appendPuzzle(puzzles[i].x, puzzles[i].y, puzzles[i].number);
    }
    this.makeDraggable();
    this.makeDroppable();

}

function sort(){
    var box = new YAHOO.util.Element('box');
    while (box.hasChildNodes()) {
        box.removeChild(box.get('firstChild'));
    }
    puzzles = new Array();
    this.init();
    this.makeDraggable();
    this.makeDroppable();
}

function appendPuzzle(x, y, number){
    var box = new YAHOO.util.Element('box');
    var puzzle = document.createElement('div');
    puzzle.id = 'puzzleId' + number;
    puzzle.innerHTML = number;
    puzzle.className = 'puzzle';
    puzzle.setAttribute('style', 'position:absolute; left:' + x + 'px; top:' + y +'px;')
    box.appendChild(puzzle);
}

function appendFreeSpace(x, y){
    var box = new YAHOO.util.Element('box');
    var freeSpace = document.createElement('div');
    freeSpace.id = 'freeSpaceId';
    freeSpace.className = 'freeSpace';
    freeSpace.setAttribute('style', 'position:absolute; left:' + x + 'px; top:' + y +'px;')
    box.appendChild(freeSpace);
}

function dragDropCommon(){
    //alert ('dragDropCommon');
    var xTemp = freeSpace.x;
    var yTemp = freeSpace.y;
    var positionTemp = freeSpace.position;


    freeSpace.x = lastDraggedPuzzle.x;
    freeSpace.y = lastDraggedPuzzle.y;
    freeSpace.position = lastDraggedPuzzle.position;

    lastDraggedPuzzle.x = xTemp;
    lastDraggedPuzzle.y = yTemp;
    lastDraggedPuzzle.position = positionTemp;

    puzzles[lastDraggedPuzzle.number] = lastDraggedPuzzle;
    //destroy all draggable and dropable
    var box = new YAHOO.util.Element('box');
    box.removeChild(new YAHOO.util.Element('freeSpaceId'));
    appendFreeSpace(freeSpace.x, freeSpace.y);

    box.removeChild(new YAHOO.util.Element('puzzleId' + lastDraggedPuzzle.number));
    appendPuzzle(lastDraggedPuzzle.x, lastDraggedPuzzle.y, lastDraggedPuzzle.number);
    makeDraggable();
    makeDroppable();
}


