function Module(row, col, rows, cols, price, originalClass, includedInAllIn, selectedColor, selectedTextColor, title) {
    this.row = row;
    this.col = col;
    this.rows = rows;
    this.cols = cols;
    this.originalClass = originalClass;
    this.currentClass = originalClass;
    this.price = price;
    this.isIncludedInAllIn = includedInAllIn;
    this.selectedColor = selectedColor;
    this.selectedTextColor = selectedTextColor;
    this.title = title;
}
Module.prototype.isLunch = function() {
    return this.title == "Lunch";
};
Module.prototype.isDisabled = function() {
    return this.currentClass == "volzet";
};
Module.prototype.isSelected = function() {
    return this.currentClass == "gekozen";
};
Module.prototype.isHighlighted = function() {
    return this.currentClass == "highlight";
};
Module.prototype.isBlocked = function() {
    for (var i = this.row; i < this.row + this.rows; i++) {
        for (var j = 0; j < modules[i].length; j++) {
            var other = modules[i][j];
            if (this.col != other.col && other.isSelected()) {
                return true;
            }
        }
    }
    return false;
};
Module.prototype.toggleHighlight = function(node) {
    if (this.isHighlighted()) {
        this.currentClass = this.originalClass;
        $(node).attr("class", this.originalClass).css("backgroundColor", "").css("color", "");
    } else if (!this.isDisabled() && !this.isSelected()) {
        this.currentClass = "highlight";
        $(node).attr("class", "highlight").css("backgroundColor", this.selectedColor).css("color", this.selectedTextColor);
    }
};
Module.prototype.toggleSelect = function(node) {
    if (this.isSelected()) {
        this.unselectModule(node);
    } else if (!this.isDisabled()) {
        this.selectModule(node);
    }
};
Module.prototype.selectModule = function(node) {
    if (this.isSelected()) return;
    this.currentClass = "gekozen";
    $(node).attr("class", "gekozen").css("backgroundColor", this.selectedColor).css("color", this.selectedTextColor);
    updateTotaal(totaal + this.price);
    $("#slot_" + this.row).val("module_" + this.row + "_" + this.col);
    for (var i = this.row; i < this.row + this.rows; i++) {
        for (var j = 0; j < modules[i].length; j++) {
            var other = modules[i][j];
            if (this.col != other.col) {
                var otherNode = $("#module_" + other.row + "_" + other.col);
                other.disableModule(otherNode);
            }
        }
    }
};
Module.prototype.unselectModule = function(node) {
    if (!this.isSelected()) return;
    this.currentClass = "highlight";
    $(node).attr("class", "highlight").css("backgroundColor", "").css("color", "");
    $("#slot_" + this.row).val("");
    updateTotaal(totaal - this.price);
    for (var i = this.row; i < this.row + this.rows; i++) {
        for (var j = 0; j < modules[i].length; j++) {
            var other = modules[i][j];
            if (this.col != other.col && !other.isBlocked()) {
                var otherNode = $("#module_" + other.row + "_" + other.col);
                other.enableModule(otherNode);
            }
        }
    }
};
Module.prototype.disableModule = function(node) {
    this.currentClass = "volzet";
    $(node).attr("class", this.currentClass);
};
Module.prototype.enableModule = function(node) {
    this.currentClass = this.originalClass;
    $(node).attr("class", this.currentClass);
};

function select(row, col) {
    var module = $("#module_" + row + "_" + col);
    var m = modules[row][col];
    m.toggleSelect(module);
}

function updateTotaal(newTotal) {
    if (!$("#allin").prop("checked")) {
        totaal = newTotal;
        $("#totaal").html(totaal.toFixed(2) + " &euro;");
        if (checkAllinSuggestion()) {
            $('#allInDialog').dialog('open');
        }
    }
}

function checkAllinSuggestion() {
    return (totaal > allInPrice && !allInReminderShown);
}

function highlight(row, col) {
    var module = $("#module_" + row + "_" + col);
    var m = modules[row][col];
    m.toggleHighlight(module);
}

function toggleCD() {
    if ($("#cd").prop("checked")) {
        updateTotaal(totaal + cdPrice);
    } else {
        updateTotaal(totaal - cdPrice);
    }
}

function toggleAllIn() {
    if ($("#allin").prop("checked")) {
        selectAllIn();
    } else {
        unselectAll();
        $("#cd").prop("disabled",false).prop("checked",false);
        updateTotaal(0);
    }
}

function selectAllIn() {
    $('#allin').prop("checked",true);
    $("#cd").prop("checked",true).prop("disabled",true);
    for (var i = 0; i < modules.length; i++) {
        for (var j = 0; j < modules[i].length; j++) {
            var mod = modules[i][j];
            if (mod.isIncludedInAllIn && !mod.isSelected()) {
                var node = $("#module_" + mod.row + "_" + mod.col);
                mod.selectModule(node);
            }
        }
    }
    totaal = allInPrice;
    $("#totaal").html(allInPrice.toFixed(2) + " &euro;");
}

function disableAllInReminder() {
    allInReminderShown = true;
}

function unselectAll() {
    for (var i = 0; i < modules.length; i++) {
        for (var j = 0; j < modules[i].length; j++) {
            var mod = modules[i][j];
            if (mod.isSelected()) {
                var node = $("#module_" + mod.row + "_" + mod.col);
                mod.unselectModule(node);
                mod.currentClass = "";
                $(node).attr("class", mod.currentClass);
            }
        }
    }
}

function toggleNietBTWPlichtig() {
    if ($("#nietbtwplichtig").prop("checked")) {
        $("#btwnummer").required = false;
    } else {
        $("#btwnummer").required = true;
    }
}

function allinWithoutSelectedModule() {
    if (!$("#allin").prop("checked")) {
        return false;
    }
    for (var i = 0; i < modules.length; i++) {
        for (var j = 0; j < modules[i].length; j++) {
            var mod = modules[i][j];
            if (!mod.isIncludedInAllIn && mod.isSelected()) {
                return false;
            }
        }
    }
    return true;
}

function showNoModulesDialog() {
    $('#noModulesDialog').dialog('open');
}

function noAllinAndNoLunch() {
    if ($("#allin").prop("checked")) {
        return false;
    }
    for (var i = 0; i < modules.length; i++) {
        for (var j = 0; j < modules[i].length; j++) {
            var mod = modules[i][j];
            if (mod.isLunch()) {
                return !mod.isSelected();
            }
        }
    }
    return false;
}

function showLunchDialog() {
    $('#lunchDialog').dialog('open');
}

function selectLunch(checked) {
    for (var i = 0; i < modules.length; i++) {
        for (var j = 0; j < modules[i].length; j++) {
            var mod = modules[i][j];
            if (mod.isLunch()) {
                var node = $("#module_" + mod.row + "_" + mod.col);
                if (checked) {
                    mod.selectModule(node);
                } else {
                    mod.unselectModule(node);
                }
            }
        }
    }
    $("#cd").prop("disabled",false);
}

