﻿(function ($) {

    function showValidationCallout(ctrl, val) {
        var $val = $(val);
        var my = $val.data("position-my") || "left top";
        var at = $val.data("position-at") || "right top";
        var offset = $val.data("position-offset") || "10 -10";
        var collision = $val.data("position-collision") || "flip fit";
        $val.closest(".callout").show().position({
            "my": my,
            "at": at,
            "of": ctrl,
            "offset": offset,
            "collision": collision
        });
    }

    function highlightInputs(ctrl) {
        var $ctrl = $(ctrl);
        if (AllValidatorsValid(ctrl.Validators)) {
            $ctrl.removeClass("validationErrorInput");
        } else {
            if (!$ctrl.hasClass("validationErrorInput")) {
                $ctrl.addClass("validationErrorInput");
            }
        }
    }

    // Overrides ValidatorUpdateDisplay in WebUIValidation.js to show/hide validation callout.
    var __ValidatorUpdateDisplay = window.ValidatorUpdateDisplay;
    window.ValidatorUpdateDisplay = function (val) {

        // call existing implementation to show/hide validation error message
        __ValidatorUpdateDisplay(val);

        var ctrl = document.getElementById(val.controltovalidate);

        // highlight input for current validator
        highlightInputs(ctrl);

        // if this is a compare validator, also highlight control to compare
        if (val.controltocompare) {
            var linked = document.getElementById(val.controltocompare);
            highlightInputs(linked);
        }

        // callout
        if (val.isvalid) {
            $(val).closest(".callout").hide();
        } else {
            // show error callout for input that has focus
            if ($(ctrl).is(":focus")) {
                showValidationCallout(ctrl, val);
            }
        }
    };

    function onFocus(ev) {

        var ctrl = this;

        // hide all callouts
        $(window.Page_Validators).closest(".callout").hide();

        // set input highlight
        highlightInputs(ctrl);

        $.each(ctrl.Validators, function (index, val) {
            if (!val.isvalid) {
                showValidationCallout(ctrl, val);
                // show only first error callout
                return false;
            }
        });
    }

    function onBlur(ev) {
        // hide all callouts
        $(window.Page_Validators).closest(".callout").each(function (index, callout) {
            if (!$(callout).data("keepOpen")) {
                $(callout).hide();
            }
        });
    }

    $(document).ready(function () {

        var inputIds = {};
        var validators = window.Page_Validators || [];
        $.each(validators, function (index, val) {

            // focus input on error
            val.focusOnError = "t";

            // reparent validator to callout container
            var $callout = $("<div/>").addClass("callout").addClass("validatorCallout").hide();
            $("<div/>").addClass("validatorCalloutPointer").appendTo($callout);
            $callout.append(val).appendTo(document.body);
            // hookup focus event on input controls to show validation callout
            var inputId = val.controltovalidate;
            if (!(inputId in inputIds)) {
                $("#" + inputId).focus(onFocus).blur(onBlur);
            }

        });

    });

})(jQuery);


