/*global $:false, data, VLE */

var DataObject = (function () {
    function DataObject() {
        this.allowedAttempts = 2;
        this.attempts = 0;
        this.element = [];
    }

    DataObject.prototype.reset = function (length) {
        while (this.element.length > 0) {
            this.element.pop();
        }
        var i;
        for (i = 0; i < length; ++i) {
            this.element[i] = null;
        }
    };
    return DataObject;
}());

var dataObject = new DataObject();

var selection = null;
var selectForDeletion = null;

function getText(html) {
    return $('<div></div>').html(html).text();
}

function saveDataToVLE() {
    var temp = {
        allowedAttempts: 2,
        attempts: 0,
        element: []
    };

    temp.allowedAttempts = JSON.stringify(dataObject.allowedAttempts);
    temp.attempts = JSON.stringify(dataObject.attempts);
    temp.element = JSON.stringify(dataObject.element);

    VLE.set_server_data(true, temp, function () {
        console.log("set_server_data was successful");
    }, function (msg) {
        console.log("set_server_data has failed");
        if (msg != null) {
            console.log(msg);
        }
    });
}

function retrieveDataFromVLE() {
    var array = [];
    array.push("allowedAttempts");
    array.push("attempts");
    array.push("element");

    dataObject.reset(data.choices.length);

    VLE.get_server_data(true, array, function (savedData) {
        dataObject.allowedAttempts = JSON.parse(savedData.allowedAttempts);
        dataObject.attempts = JSON.parse(savedData.attempts);
        dataObject.element = JSON.parse(savedData.element);

        if (savedData.element.length > 0) {
            var i;
            var text;
            for (i = 0; i < dataObject.element.length; ++i) {
                if (dataObject.element[i] !== null) {
                    $("#choices").find("span").each(function (index, element) {
                        text = getText(element.innerHTML);
                        text = text.replace(',', '');
                        if (dataObject.element[i].text[0] === text) {
                            $(element).appendTo("#" + dataObject.element[i].text[1]);
                        }
                    });
                }
            }

            var correct;
            var $td = $("td");
            $td.find("span").each(function (index, element) {
                correct = false;
                for (i = 0; i < data.answers.length; ++i) {
                    text = getText(element.innerHTML);
                    text = text.replace(',', '');
                    text = text.replace('.', '');

                    if (text === data.answers[i].text[0] && element.parentNode.id === data.answers[i].text[1]) {
                        dataObject.element[index] = {text: [text, element.parentNode.id]};
                        $(element).addClass("green-border").draggable("disable").css('cursor', 'default');
                        correct = true;
                        break;
                    }
                }
                if (!correct) {
                    if (dataObject.attempts >= dataObject.allowedAttempts) {
                        $(element).addClass("red-border").draggable("disable").css('cursor', 'default');
                    } else {
                        $(element).appendTo("#choices");
                    }
                }
            });

        }
    }, function (msg) {
        console.log("Failed to get server data.");
        if (msg != null) {
            console.log(msg);
        }
    });
}

function shuffleArray(array) {
    var i, j, temp;
    for (i = array.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    return array;
}

function showFeedback(message) {
    $("#feedback").remove();
    $("#content").append("<div id='feedback'><p>" + message + "</p></div>");
}

function getFeedbackMessage(count, attemptsLeft,text) {
    console.log(count, attemptsLeft,text);
    var message = "";
    if(text==""){
        message = "<br/>Please enter a value!";
    }else {
        if (count == data.answers.length) {
            message = data.feedback[0].text;
        }
        else if (count < data.answers.length && attemptsLeft) {
                message = data.feedback[1].text;

            } else {
                message = data.feedback[2].text;

        }

    }
    return message;
}

function reveal() {
    dataObject.reset(data.choices.length);

    var $td = $("td.dropzone");
    $td.find("span").each(function (index, element) {
        $(element).appendTo("#choices");
    });

    var $choices = $("#choices");
    $choices.find("span").removeClass("green-border").removeClass("red-border");

    var text;
    var i;
    for (i = 0; i < data.answers.length; ++i) {
        $choices.find("span").each(function (index, element) {
            text = getText(element.innerHTML);
            if (text === data.answers[i].text[0]) {
                $(element).appendTo("#" + data.answers[i].text[1]);
                dataObject.element[i] = {text: [text, element.parentNode.id]};
            }
        });
    }


    $choices.find("span").draggable({ disabled: true }).css('cursor', 'default');
    $choices.droppable("disable");

    $td.find("span").draggable({ disabled: true }).css('cursor', 'default');
    $td.droppable("disable");
    $("#submit").button("disable");

    saveDataToVLE();
}

function submit() {

    var text="", correct, count = 0, attemptsLeft;

    var i;
    var $td = $("td");
    $td.find("span").each(function (index, element) {
        correct = false;
        for (i = 0; i < data.answers.length; ++i) {
            text = getText(element.innerHTML);
            if (text === data.answers[i].text[0] && element.parentNode.id === data.answers[i].text[1]) {
                dataObject.element[index] = {text: [text, element.parentNode.id]};
                $(element).addClass("green-border").draggable("disable").css('cursor', 'default');
                correct = true;
                count++;
                break;
            }

        }
        if (!correct) {
            if (dataObject.attempts == dataObject.allowedAttempts) {
                $(element).addClass("red-border").draggable("disable").css('cursor', 'default');

                $("#submit").button("disable");
            } else {

                $(element).appendTo("#choices");
            }
        }

    });

    if(text != ""){
        dataObject.attempts++;
    }

    if (dataObject.attempts == dataObject.allowedAttempts) {
        $("#choices").find("span").draggable("disable").css('cursor', 'default');
        //$td.droppable("disable").css('cursor', 'default');
        reveal();
        attemptsLeft = false;
        $("#submit").button("disable");

    } else {
        attemptsLeft = true;
        if (count === data.answers.length) {
            $("#choices").find("span").draggable("disable").css('cursor', 'default');
            //$td.droppable("disable").css('cursor', 'default');
            $("#submit").button("disable");

        }
    }
    var message = getFeedbackMessage(count, attemptsLeft, text);
    showFeedback(message);

    saveDataToVLE();
}

function reset() {
    dataObject.attempts = 0;
    dataObject.reset(data.choices.length);
    showFeedback("");

    var $td = $("td.dropzone");
    $td.find("span").each(function (index, element) {
        $(element).appendTo("#choices");
    });

    var choices = data.choices;
    shuffleArray(choices);

    var $choices = $("#choices");
    $choices.find("span").each(function (index, element) {
        element.innerHTML = choices[index].text;
    });

    $choices.find("span").removeClass("green-border").removeClass("red-border").draggable("enable").css('cursor', 'pointer');
    $choices.droppable("enable");
    $td.droppable("enable");
    $("#submit").button("enable");
    $("#submit").off("click").val("Submit").show().click(function () {
        submit();
    });

    saveDataToVLE();
}

$(function () {
    var $content = $("#content");
    $content.append("<div id='choices'/>");

    var choices = data.choices;
    shuffleArray(choices);

    var $choices = $("#choices");

    var i;
    for (i = 0; i < data.choices.length; ++i) {
        $choices.append("<span>" + choices[i].text + "</span>");
    }

    $content.append("<div style='margin-top: 10px'><table/></div>");

    for (i = 0; i < data.rowHeaders.length; ++i) {
        var rowHead = data.rowHeaders;
        $("table").append("<tr id='tr"+i+"'><td class='rowHead'>" + rowHead[i].text + "</td><td id='td" + i + "' tabIndex='1' class='dropzone'>");
    }

    $content.append("<input id='submit' class='btn' type='button' value='Submit'/>");
    $content.append("<input id='reset' class='btn' type='button' value='Reset'/>");

    $choices.find("span").draggable({
        revert: "invalid",
        zIndex: 100,
        refreshPositions: true,
        containment: "#content",
        drag: function (e, ui) {
            ui.helper.addClass("selected");
        },
        stop: function (e, ui) {
            ui.helper.removeClass("selected");
        }
    }).sortable();

    $choices.droppable({
        drop: function (e, ui) {
            ui.draggable.detach().css({top: 0, left: 0}).appendTo(this);
        }
    });

    $choices.on("click", function () {
        if (selection !== null && !$(selection).hasClass("ui-draggable-disabled") &&
            !$(selectForDeletion).parent().hasClass("ui-droppable-disabled")) {
            $(selectForDeletion).appendTo("#choices");

            $("td").removeClass("selected");
            $(selectForDeletion).addClass("selected");

            selection = selectForDeletion;
            selectForDeletion = null;
        }
    });

    $choices.find("span").on("click", function (e) {
        if (this.parentNode.nodeName != "td" && this.parentNode.nodeName != "TD") {
            e.stopPropagation();
            $("td").removeClass("selected");

            if ($(this).hasClass("selected")) {
                $(this).removeClass("selected");
                selection = null;
            } else {
                var $divs = $choices.find("span");

                if ($divs.hasClass("selected")) {
                    $divs.removeClass("selected");
                }

                $(this).addClass("selected");
                selection = this;
                selectForDeletion = this;
            }
        }
    });

    var $td = $("td.dropzone");

    $td.droppable({
        hoverClass: "hover",
        tolerance: "pointer",
        drop: function (e, ui) {
            ui.draggable.detach().css({top: 0, left: 0}).appendTo(this);

            $choices.find("span").removeClass("selected");
            $(this).focus();
            selectForDeletion = this.children[0];

        }
    });

    $td.on("click", function () {
        if (selection != null) {
            if (!$(this).hasClass("ui-droppable-disabled")) {
                $(selection).detach().removeClass("selected").css({top: 0, left: 0}).appendTo(this);
                selectForDeletion = selection;
                selection = null;
            }
        }

        $choices.find("span").removeClass("selected");
    });

    $td.on("click", "span", function (e) {
        var $parent = $(this).parent();

        if (selection != null) {
            if (!$parent.hasClass("ui-droppable-disabled")) {
                if ($parent.children.length > 0) {
                    $parent.children(0).appendTo("#choices");
                }

                $(selection).detach().removeClass("selected").css({top: 0, left: 0}).appendTo($parent[0]);
                selectForDeletion = selection;
            }
        } else {
            selectForDeletion = this;
        }

        $choices.find("span").removeClass("selected");
        $parent.focus();

        e.stopPropagation();
    });

    $("html").on("keyup", function (e) {
        var id = e.target.id;
        var $first,
            parent,
            i;

        if (e.which == 9) {
            $choices.find("span").first().addClass("selected");
        } else if (e.which == 13 || e.which == 32) {
            if ((e.target.nodeName == "TD" || e.target.nodeName == "td") && !$(e.target).hasClass("ui-droppable-disabled")) {
                $first = $choices.find("span").first();
                $first.appendTo("#" + id);
                selectForDeletion = $first[0];

                $first.removeClass("selected");
                $first = $choices.find("span").first();
                selection = $first[0];
                $first.addClass("selected");
            } else if (selection != null) {
                parent = $(selection).parent()[0];
                if ((parent.nodeName == "TD" || parent.nodeName == "td") && !$(parent).hasClass("ui-droppable-disabled")) {

                    $(selection).appendTo("#choices");
                    $first = $choices.find("span").first();
                    $first.appendTo(parent);
                    selectForDeletion = selection;
                    selection = $first[0];
                }
            }
        } else if (e.which == 46 || e.which == 8) {
            if ((e.target.nodeName == "TD" || e.target.nodeName == "td") && !$(e.target).hasClass("ui-droppable-disabled")) {
                e.preventDefault();
                if (e.target.children.length > 0) {
                    for (i = 0; i < e.target.children.length; ++i) {
                        if (!$(e.target.children[i]).hasClass("ui-draggable-disabled")) {
                            $(e.target.children[i]).appendTo("#choices");

                            $first = $choices.find("span").first();
                            selection = $first[i];
                            $first.addClass("selected");
                            break;
                        }
                    }
                }
            } else if (selectForDeletion != null) {
                e.preventDefault();
                parent = $(selectForDeletion).parent()[0];
                if ((parent.nodeName == "TD" || parent.nodeName == "td") && !$(parent).hasClass("ui-droppable-disabled")) {
                    $(selectForDeletion).appendTo("#choices");
                    selectForDeletion = null;

                    $first = $choices.find("span").first();
                    selection = $first[0];
                    $first.addClass("selected");
                }
            }
        }
    });

    $("#submit").button().click(function () {
        submit();
    });

    $("#reset").button().click(function () {
        reset();
    });

    retrieveDataFromVLE();
});