

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);
        }
    }
    $('#box').css('height', '200');


}


//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){
                jQMakeRightDraggable(puzzles[i]);
            } else if (puzzles[i].position == freeSpace.position + 1){
                jQMakeLeftDraggable(puzzles[i]);
            } else if (puzzles[i].position == freeSpace.position + 4){
                jQMakeUpDraggable(puzzles[i]);
            } else if (puzzles[i].position == freeSpace.position - 4){
                jQMakeDownDraggable(puzzles[i]);
            }
        }
    }
}

function jQMakeUpDraggable(puzzle){
    $('#puzzleId' + puzzle.number).draggable({
        axis: 'y',
        containment: [puzzle.x - 100, puzzle.y + 50, puzzle.x + 100, puzzle.y + 100],
        stop: function(event, ui) {
            lastDraggedPuzzle = puzzle;
        },
        start: function(event, ui) {
            lastDraggedPuzzle = puzzle;
        }
    });
}

function jQMakeDownDraggable(puzzle){
    // alert("puzzle " + puzzle.number + " must be draggable");
    $('#puzzleId' + puzzle.number).draggable({
        axis: 'y',
        containment: [puzzle.x - 100, puzzle.y + 100, puzzle.x + 100, puzzle.y + 150],
        stop: function(event, ui) {
            lastDraggedPuzzle = puzzle;
        },
        start: function(event, ui) {
            lastDraggedPuzzle = puzzle;
        }
    });
}

function jQMakeLeftDraggable(puzzle){
    //alert("puzzle " + puzzle.number + " must be draggable");
    $('#puzzleId' + puzzle.number).draggable({
        axis: 'x',
        containment: [puzzle.x + 50, puzzle.y - 100, puzzle.x + 50, puzzle.y + 100],
        stop: function(event, ui) {
            lastDraggedPuzzle = puzzle;
        },
        start: function(event, ui) {
            lastDraggedPuzzle = puzzle;
        }
    });
}

function jQMakeRightDraggable(puzzle){
    //alert("puzzle " + puzzle.number + " must be draggable");
    $('#puzzleId' + puzzle.number).draggable({
        axis: 'x',
        containment: [puzzle.x + 100, puzzle.y - 100, puzzle.x + 150, puzzle.y + 100],
        stop: function(event, ui) {
            lastDraggedPuzzle = puzzle;
        },
        start: function(event, ui) {
            lastDraggedPuzzle = puzzle;
        }

    });
}


function makeDroppable(){
    $('#freeSpaceId').droppable({
        drop: function() {
            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
            $("#box > *").draggable('destroy');
            $("#box > *").droppable('destroy');
            $('#freeSpaceId').remove();
            appendFreeSpace(freeSpace.x, freeSpace.y);
          
            $('#puzzleId' + lastDraggedPuzzle.number).remove();
            appendPuzzle(lastDraggedPuzzle.x, lastDraggedPuzzle.y, lastDraggedPuzzle.number);
            makeDraggable();
            makeDroppable();
        }
    });

}


function scramble(){
    $("#box > *").draggable('destroy');
    $("#box > *").droppable('destroy');
    $('#freeSpaceId').remove();
    $('.puzzle').remove();
    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(){
    $("#box > *").draggable('destroy');
    $("#box > *").droppable('destroy');
    $('#freeSpaceId').remove();
    $('.puzzle').remove();
    puzzles = new Array();
    this.init();
    this.makeDraggable();
    this.makeDroppable();
}

function appendPuzzle(x, y, number){
    $('#box').append('<div class="puzzle" id="puzzleId'
        + number
        + '"'
        +'" style="position:absolute; '
        + 'left:' + x + 'px; top:' + y +'px;'
        +'">'
        + number
        + '</div>');
}

function appendFreeSpace(x, y){
    $('#box').append('<div class="freeSpace" id="freeSpaceId'
        + '"'
        +'" style="position:absolute; '
        + 'left:' + x + 'px; top:' + y +'px;'
        +'">'
        + '</div>');
}


