/*
 * The Kuali Financial System, a comprehensive financial management system for higher education.
 *
 * Copyright 2005-2016 The Kuali Foundation
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * Runs the validation script if the validator is already setup, otherwise adds a handler
 * to the document which will run once when the 'validationSetup' event is fired
 *
 * @param scriptFunction
 */
function runValidationScript(scriptFunction) {
    if (pageValidatorReady) {
        scriptFunction();
    }
    else {
        jq(document).bind('validationSetup', function (event) {
            jq(this).unbind(event);
            scriptFunction();
        });
    }
}

//checks to see if any fields depend on the field being validated, if they do calls validate
//on them as well which will either add errors or remove them
//Note: with the way that validation work the field must have been previously validated (ie validated)
function dependsOnCheck(element, nameArray) {
    var name;
    if (jq(element).is("option")) {
        name = jq(element).parent().attr('name');
    }
    else {
        name = jq(element).attr('name');
    }
    name = escapeName(name);
    jq("[name='" + name + "']").trigger("checkReq");
    nameArray.push(name);


    jq(".dependsOn-" + name).each(function () {

        var elementName;
        if (jq(this).is("option")) {
            elementName = jq(this).parent().attr('name');
        }
        else {
            elementName = jq(this).attr('name');
        }
        elementName = escapeName(elementName);

        if (jq(this).hasClass("valid") || jq(this).hasClass("error")) {
            jq.watermark.hide(this);
            var valid = jq(this).valid();
            jq(this).attr("aria-invalid", !valid);
            jq.watermark.show(this);
            var namePresent = jq.inArray(elementName, nameArray);
            if (namePresent == undefined || namePresent == -1) {
                dependsOnCheck(this, nameArray);
            }
        }
    });
}

/**
 * Sets up a req indicator check for the controlName, when it changes, checks to see if it satisfies
 * some booleanFunction and then shows an indicator on the now required field (identified by requiredName).
 * If not satisfied, removes the indicator
 *
 * @param controlName
 * @param requiredName
 * @param booleanFunction
 */
function setupShowReqIndicatorCheck(controlName, requiredName, booleanFunction) {
    if (jq("[name='" + escapeName(controlName) + "']").length) {

        var id = jq("[name='" + escapeName(requiredName) + "']").attr("id");
        var indicator;
        if (id) {
            var label = jq("#" + id + "_label_span");
            if (label.length) {
                indicator = label.find(".required");
            }
        }

        //check right now if it satisfies the condition, only if an indicator is not shown
        //(indicators that are shown stay shown for this check, as the server or another check must have shown them)
        if (indicator != null && indicator.length && indicator.is(':hidden')) {
            checkForRequiredness(controlName, requiredName, booleanFunction, indicator);
        }

        //also check condition when corresponding control is changed
        jq("[name='" + escapeName(controlName) + "']").change(function () {
            checkForRequiredness(controlName, requiredName, booleanFunction, indicator);
        });

        jq("[name='" + escapeName(controlName) + "']").bind("checkReq", function () {
            checkForRequiredness(controlName, requiredName, booleanFunction, indicator);
        });
    }
}

function checkForRequiredness(controlName, requiredName, booleanFunction, indicator) {
    if (indicator != null && indicator.length) {
        if (booleanFunction()) {
            indicator.show();
            jq("[name='" + escapeName(requiredName) + "']").attr("aria-required", "true");
        }
        else {
            indicator.hide();
            jq("[name='" + escapeName(requiredName) + "']").attr("aria-required", "false");
        }
    }
}

//checks to see if the fields with names specified in the name array contain a value
//if they do - returns the total if the num of fields matched
function mustOccurTotal(nameArray, min, max) {
    var total = 0;
    for (i = 0; i < nameArray.length; i++) {
        if (coerceValue(nameArray[i])) {
            total++;
        }
    }

    return total;

}

//checks to see if the fields with names specified in the name array contain a value
//if they do - returns 1 if the num of fields with values are between min/max
//this function is used to for mustoccur constraints nested in others
function mustOccurCheck(total, min, max) {

    if (total >= min && total <= max) {
        return 1;
    }
    else {
        return 0;
    }
}
