function Start() {
    $('#startButton').click(function () { StartClicked(); return false; });
    $('#increaseLevel').click(function () { increaseLevel(); return false });
    $('#decreaseLevel').click(function () { decreaseLevel(); return false });
    Initialize();
}

function ShuffleSelectableTiles() {
    setNextTubeSection('#firstSelection');
    setNextTubeSection('#secondSelection');
    setNextTubeSection('#thirdSelection');
}

function StartClicked() {
    Attempted();
    $('#status').html("");
    $('.tube').css('background-image', "");
    $('.tube').addClass("canDropOn");
    $('#bar').css('width', '0px');   
    setTimeout('IncreaseBar()', getBarSpeed());
    $('.selection').mousedown(function (index) { DragSelection(this); return false; });
    $('#startButton').unbind('click');
}

function IncreaseBar() {
    width = pixelToInt($('#bar').css('width'));
    if (width >= 135) {
        if (DoExitsMatchEntrances(9) === true) { EndGame(true); }
        else { EndGame(false); }
        return;
    }
    if ($('#bar').data('completePath') === true) {
        $('#bar').css('width', (width + 1) + "px");
        setTimeout('IncreaseBar()', getBarSpeed());
        return;
    }        
    if (width % 15 === 1 && width > 1) {
        var divOn = Math.floor(width / 15);
        $(intToDivToDropOn(divOn - 1)).removeClass("canDropOn");
        if (DoExitsMatchEntrances(divOn) === false) {
            EndGame(false);
            return;
        }        
    }
    $('#bar').css('width', (width + 1) + "px");
    CheckForAndHandleCompletePath();
    setTimeout('IncreaseBar()', getBarSpeed());
}

function DoExitsMatchEntrances(divNumberToCheck) {
    var entrances = getEntrancesOfDivNumber(divNumberToCheck);
    if (entrances === undefined || entrances === null)
        return false;
    var exits = getExitsOfDivNumber(divNumberToCheck - 1);
    if (entrances.length != exits.length)
        return false;
    for (i = 0; i < entrances.length; ++i) {
        if (entrances[i] != exits[i])
            return false;
    }
    return true;
}

function EndGame(win) {
    $('.selection').unbind('mousedown');
    $('#startButton').click(StartClicked);
    $('.tube').removeClass("canDropOn");
    $('#bar').data('completePath', false);
    clearEntrancesOnTubeSections();
    clearExitsOnTubeSections();
    if (win) {
        Won();
        $('#status').html("Win!");
        increaseLevel();
    }
    else {
        $('#status').html("Lose!");
    }
    ShuffleSelectableTiles();
}

function CheckForAndHandleCompletePath() {
    for (divNumber = 1; divNumber <= 9; divNumber = divNumber + 1) {
        if (DoExitsMatchEntrances(divNumber) === false)
            return;
    }
    $('#bar').data('completePath', true);
    $('.tube').removeClass("canDropOn");
}

function getExitsOfDivNumber(divNumber) {
    if (divNumber === 0)
        return [1];
    return getExitsOnTubeSection(intToDivToDropOn(divNumber - 1)); // 0 index for tubeSections in intToDivToDropOn
}

function getEntrancesOfDivNumber(divNumber) {
    if (divNumber === 9)
        return [1];

    return getEntrancesOnTubeSection(intToDivToDropOn(divNumber - 1)); // 0 index for tubeSections in intToDivToDropOn
}

function DragSelection(selectionToDrag) {
    setSnappedTo("");
    $(selectionToDrag).mouseup(function () { DropSelection(selectionToDrag); });
    var left = $(selectionToDrag).offset().left;
    var top = $(selectionToDrag).offset().top;
    $("body").append("<div id='beingDragged'></div>");
    setSpotSelectedForDragging($(selectionToDrag).attr('id'));
    copyInfoForDrop(selectionToDrag, '#beingDragged');
    $('#beingDragged').css("left", left);
    $('#beingDragged').css('top', top);
    $(selectionToDrag).css('background-image', "");
    $(document).mousemove(function (eventInfo) { MouseMovingForSelectionDrag(eventInfo); return false; });
    $('#beingDragged').mouseup(function () { DropSelection(selectionToDrag); });
}

function MouseMovingForSelectionDrag(mouseMoveInfo) {
    $('#beingDragged').css("left", mouseMoveInfo.pageX - 8);
    $('#beingDragged').css("top", mouseMoveInfo.pageY - 7);

    var minLeft = $('#first').offset().left;
    var maxLeft = $('#eigth').offset().left + pixelToInt($('#eigth').css('width'));
    var minTop = $('#first').offset().top;
    var maxTop = minTop + pixelToInt($('#first').css('height'));
    var draggedLeft = mouseMoveInfo.pageX;
    var draggedTop = mouseMoveInfo.pageY;

    var divSnappedTo = getSnappedTo();
    if (draggedLeft < minLeft || draggedLeft > maxLeft ||
        draggedTop < minTop || draggedTop > maxTop) {        
        if (divSnappedTo !== "") {
            $('#beingDragged').css('background-image', $(divSnappedTo).css('background-image'));
            $(divSnappedTo).css('background-image', getOldBackground(divSnappedTo));
            setSnappedTo("");
        } 
        return false;
    }

    var divNumberToSnapTo = Math.floor((draggedLeft - minLeft) / 15);
    var divToSnapTo = intToDivToDropOn(divNumberToSnapTo);
    if (divToSnapTo === divSnappedTo)
        return false;
    if ($(divToSnapTo).hasClass("canDropOn") === true) {
        if (divSnappedTo === "") {
            setOldBackground(divToSnapTo, $(divToSnapTo).css('background-image'));
            $(divToSnapTo).css('background-image', $('#beingDragged').css('background-image'));
            $('#beingDragged').css('background-image', "");
        }
        else {
            var oldBackground = getOldBackground(divSnappedTo);
            setOldBackground(divToSnapTo, $(divToSnapTo).css('background-image'));
            $(divToSnapTo).css('background-image', $(divSnappedTo).css('background-image'));
            $(divSnappedTo).css('background-image', oldBackground);
        }
        setSnappedTo(divToSnapTo);
    }
    else if (divSnappedTo !== "") {
        $('#beingDragged').css('background-image', $(divSnappedTo).css('background-image'));
        $(divSnappedTo).css('background-image', getOldBackground(divSnappedTo));
        setSnappedTo("");
    }
    return false;
}

function DropSelection(selectionDropped) {
    $(document).unbind('mousemove');
    var divDroppingOn = getSnappedTo()
    if (divDroppingOn === "") {
        $('#'.concat(getSpotSelectedForDragging())).css('background-image', $('#beingDragged').css('background-image'));
    }
    else {
        $('#beingDragged').css('background-image', $(divDroppingOn).css('background-image'));
        copyInfoForDrop('#beingDragged', divDroppingOn);
        setNextTubeSection('#'.concat(getSpotSelectedForDragging()));
    }
    $('#beingDragged').remove();
    return false;
}

function pixelToInt(stringInPixels) {
    return parseInt(stringInPixels.replace("px", ""));
}

function intToDivToDropOn(divNumber) {
    var divs = ["#first", "#second", "#third", "#fourth", "#fifth", "#sixth", "#seventh", "#eigth"];
    return divs[divNumber];
}

function setNextTubeSection(divToSet) {
    var index = getRandomNumber(getLevel());
    $(divToSet).css('background-image', CreateBackgroundImageStyle(getImages()[index]));
    setEntrancesOnTubeSection(divToSet, getAllEntrances()[index]);
    setExitsOnTubeSection(divToSet, getAllExits()[index]);
}

function getRandomNumber(level) {
    var number = Math.floor(Math.random() * 100);
    var lastRandom = $('#game').data('lastRandom');
    var imageIndex = getImageIndexFromRandomNumber(level, number);
    if (lastRandom === imageIndex) {
        number = Math.floor(Math.random() * 100);
        imageIndex = getImageIndexFromRandomNumber(level, number);
    }
    $('#game').data('lastRandom', imageIndex);
    return imageIndex;
}

function getImageIndexFromRandomNumber(level, randomNumber) {
    var probabilities = [
        [16, 29, 42, 55, 68, 84, 100, 0, 0, 0],
        [16, 29, 42, 55, 68, 84, 100, 0, 0, 0],
        [16, 29, 42, 55, 68, 84, 100, 100, 100, 100],
        [10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
        [10, 19, 28, 37, 46, 56, 66, 77, 89, 100],
        [9, 17, 25, 33, 41, 50, 59, 73, 87, 100],
    ];
    for (i = 0; i < probabilities[level].length; i = i + 1) {
        if (randomNumber < probabilities[level][i])
            return i;
    }
    return 0;
}

function Initialize() {
    var images = ["Content/1.png", "Content/2.png", "Content/3.png", "Content/4.png", "Content/5.png", "Content/6.png", "Content/7.png", "Content/8.png", "Content/9.png", "Content/10.png"];
    var entrances = [
        [1],
        [0],
        [2],
        [1],
        [1],
        [0],
        [2],
        [1],
        [0, 2],
        [0, 2]
    ];
    var exits = [
        [1],
        [0],
        [2],
        [0],
        [2],
        [1],
        [1],
        [0, 2],
        [1],
        [0, 2]
    ]
    increaseLevel();
    setImages(images);
    setAllEntrances(entrances);
    setAllExits(exits);
    ShuffleSelectableTiles();
}

function GetSpeedForLevel(level) {
    var speedLevel = [300, 250, 200, 250, 225, 200];
    return speedLevel[level];
}

function copyInfoForDrop(fromDiv, toDiv) {
    $(toDiv).css('background-image', $(fromDiv).css('background-image'));
    setEntrancesOnTubeSection(toDiv, getEntrancesOnTubeSection(fromDiv));
    setExitsOnTubeSection(toDiv, getExitsOnTubeSection(fromDiv));
}

function CreateBackgroundImageStyle(imagePath) {
    return "url(" + imagePath + ")";
}

function setSpotSelectedForDragging(spotID) {
    $('#beingDragged').data("selectedSpot", spotID);
}

function getSpotSelectedForDragging() {
    return $('#beingDragged').data("selectedSpot");
}

function setImages(imagesData) {
    $('#game').data("images", imagesData);
}

function getImages() {
    return $('#game').data("images");
}

function setAllEntrances(entranceData) {
    $('#game').data("entrances", entranceData);
}

function getAllEntrances() {
    return $('#game').data("entrances");
}

function setEntrancesOnTubeSection(sectionToSet, entrances) {
    $(sectionToSet).data("entrances", entrances);
}

function getEntrancesOnTubeSection(sectionToGet) {
    return $(sectionToGet).data("entrances");
}

function clearEntrancesOnTubeSections() {
    $(".tube").each(function (index, section) { $(section).data("entrances", ""); });
}

function setAllExits(exitData) {
    $('#game').data("exits", exitData);
}

function getAllExits() {
    return $('#game').data("exits");
}

function setExitsOnTubeSection(sectionToSet, exits) {
    $(sectionToSet).data("exits", exits);
}

function getExitsOnTubeSection(sectionToGet) {
    return $(sectionToGet).data("exits");
}

function clearExitsOnTubeSections() {
    $('.tube').each(function (index, section) { $(section).data('exits', ""); });
}

function getBarSpeed() {
    if ($('#bar').data('completePath') === true)
        return 10;
    return GetSpeedForLevel(getLevel());
}

function setSnappedTo(divId) {
    $('#game').data('snapped', divId);
}

function getSnappedTo() {
    return $('#game').data('snapped');
}

function setOldBackground(div, oldBackground) {
    $(div).data('oldBackground', oldBackground);
}

function getOldBackground(div) {
    return $(div).data('oldBackground');
}

function getLevel() {
    return $('#game').data('level');
}

function increaseLevel() {
    var level = getLevel();
    if (level === undefined || level === null)
        level = 0;
    else if (level < 5)
        level = level + 1;
    $('#game').data('level', level);
    $('#level').html('Level: ' + (level + 1));
}

function decreaseLevel() {
    var level = getLevel();
    if (level > 0)
        level = level - 1;
    $('#game').data('level', level);
    $('#level').html('Level: ' + (level + 1));
}

function Attempted() {
    $.post("gameFunctions.php", { gameNumber : "2", process: "attempt" });
}

function Won() {
    $.post("gameFunctions.php", { gameNumber : "2", process: "won"});
}
