// USTechs Validation Javascript
// 2007

// Recent edits:
// 2007 May 14   JED : some use made of 'unrequired'
// 2007 March 22 JED : support for Hotels, newest registration solution
// 2007 March 16 JED 
// 2007 March 01 JED 

// 1) Validation helper functions
// 2) Miscellaneous helper functions
// 3) Internal helper functions
// 4) Validation functions
// 5) Page management

// Validation Helper functions

function setup_settings() {
    window.ust = window.ust || {};
    window.ust.settings = window.ust.settings || {};
    window.ust.settings.popup_types = window.ust.settings.popup_types || { none: 0, normal: 1, highlight: 2, ustwarn: 4 };
    window.ust.settings.error_popup_type = window.ust.settings.error_popup_type || (window.ust.settings.popup_types.highlight); //default.
}
function fitcontent(div) {
    return;
    //assuming that the inner is text only...
    var orgText = $(div).text();
    //
    var orgH = $(div).height();
    var orgW = $(div).width();
    $(div).hide();
    $(div).text("&nbsp;");
    var newH = $(div).height();
    var newW = $(div).width();
    while (orgH > newH) {
        $(div).width(orgW++);
        orgH = $(div).height();
    }
    orgW--;
    //
    $(div).text(orgText);
    $(div).width(orgW);
    $(div).show();
}

//added by AT 2/21/08
function BindVisibilityCheckBox_Value (hider, hidee, hide)
{
    if (hider != undefined && hidee != undefined)
    {
        hider.hidee = hidee;
        hider.hide = hide;
        hider.checking = function ()
        {
            if (this.checked==true)
            {
                //alert ('checked'); 
                if (this.hide)
                {
                    this.hidee.style.display = "";
                } 
                else
                {
                    this.hidee.style.display = "none";
                }            
            } 
            else
            {
                //alert ('not checked'); 
                if (this.hide)
                {
                    this.hidee.style.display = "none";
                }
                else
                {
                    this.hidee.style.display = "";
                } 
            }   
        };
        hider.onclick = function()
        {        
            this.checking();
            PrepareRequirednessBind(this.hidee);
        }        
        hider.checking();
    }  
}

//added by AT 2/21/08
function KnitBindVisibilityValue (hider, hidee, fnptr, hide)
{
    if (hider != undefined && hidee != undefined)
   {
        BindVisibility_Value (hider, hidee, fnptr, hide);
   } 
}

//added by AT 2/21/08
function KnitBindVisibilityRadioButton (group, hidee, button, hide)
{
    if (group != undefined && hidee != undefined && button != undefined)
    {
        BindVisibility_RadioButton(group, hidee, button, hide); 
    } 
}

function BindOther_DifferentField(DropDown, AttrText, AttrDiv) {
    if (!DropDown || !AttrText || !AttrDiv) return;
    
    // Set up the Other-hiding    
    DropDown.any_change = function () {
        if (this.options[this.selectedIndex].text == "Other") {
            AttrDiv.style.display="";
            AttrText.mark();
        } else {
            AttrText.value="";
            AttrDiv.style.display="none";
        }
    };

    //Set the validation
    AttrText.validate = function () {    
        return DropDown.options[DropDown.selectedIndex].text != "Other" ? true : this.value != "";
    };
}

function BindOther_DummyField (DropDown, OtherText, OtherDiv) {
    if (!DropDown || !OtherText || !OtherDiv) return;

    //Seed the dropdown from the other text
    DropDown.value = OtherText.value;
    if (DropDown.value != OtherText.value) {
        DropDown.value = "Other";
    }
    
    //Set up the other-hiding
    DropDown.any_change = function () {
        if (this.value == "Other") {
            if (!loading) OtherText.value="";
            OtherText.mark();
            OtherDiv.style.display="";
        } else {
            OtherText.value=this.value;
            OtherDiv.style.display="none";
        }
    };
    
    //Set the validation function
    OtherText.validate = function () {
        return DropDown.value != "Other" ? true : this.value != "";
    };
}

function Bind_Passwords (password, passwordConfirm)
{
    if (!password || !passwordConfirm) return;

    password.any_change = function () {
        passwordConfirm.mark();
    };

    passwordConfirm.validate = function () {
        return (password.validate() && this.value == password.value);
    };
}

function BindVisibility_Value (hider, hidee, fn, hide) {
    if (fn)
        BindVisibility_Condition (hider, hidee, function() {return fn.call(hider);}, hide);
    else
        BindVisibility_Condition (hider, hidee, function() {return this.value!="";}, hide);
    
    if (!hider.mark) {
        // for a non-required dropdown or textbox
        hider.onchange=CallMark();
        hider.mark=function() {this.any_change();};
        hider.mark();
    }
}

function BindVisibility_RadioButton (hider, hidee, radiobutton, hide) {    
    if (radiobutton) {
        BindVisibility_Condition (hider, hidee, function() {return radiobutton.checked;}, hide);
        
        if (!hider.mark) {
            // for a non-required radio-button list
            var rtrue=function(){return true;};
            var nothing=function(){};
            hider.mark=function() {this.any_change();};
            PrepareRadioButtonList (hider.id, nothing, rtrue, rtrue);
            hider.mark();
        }
    } else {        
        BindVisibility_Condition (hider, hidee, function() {return this.checked;}, hide);
        
        if (!hider.mark) {
            //for a non-required checkbox
            hider.mark=function () {this.any_change();};
            hider.onclick = CallMark();
            hider.mark();
        }
    }
}

function BindVisibility_Condition (hider, hidee, condition, hide) {    
    if (hide==undefined || hide) {
        hidee.change_require = function (vis) {
            if (vis) {
                hidee.style.display = "";
            } else {
                hidee.style.display = "none";
                if (jQuery != undefined) {
                    $(hidee).find("INPUT[type='text']").val("");
                    $(hidee).find("INPUT:checked").each(function () {
                        if (this.type == 'radio' || this.type == 'checkbox') {
                            this.checked = false;
                        }
                    });
                    $(hidee).find("SELECT").val("");
                    $(hidee).find("TEXTAREA").val("");
                }
            }
        }
    } else {
        hidee.change_require = function ( vis ) {
            if ( vis ) {
                hidee.className = "";            
            } else {    
                hidee.className = "unrequired";                    
            }
        }    
    }
    
    var hide_hidee = PrepareRequirednessBind (hidee);
    var old_any_change = hider.any_change;
    
    hider.any_change = function () {
        if (old_any_change) old_any_change.call(this);
        hide_hidee.call(this, condition.call(this, hidee))
    };
}

// added 2007 Mar 01 JED
function PrepareRequirednessBind (hidee) {
    ForEachLeaf (hidee, function(x) {if (x.validate && !x.oldval) {x.oldval=x.validate;}});
    
    var always = function(){return true;};
    hidee.setreq = function ( vis ) {
        var oldload=loading;
        loading=true;
        if (vis) {
            ForEachLeaf (hidee, function (x) {
                if (x.oldval) {x.validate=x.oldval; x.mark();}
            });
            if (hidee.change_require) hidee.change_require(vis);
        } else {
            if (hidee.change_require) hidee.change_require(vis);
            ForEachLeaf (hidee, function (x) {
                if (x.oldval) {x.validate=always; x.mark();}
            });
        }
        loading=oldload;
    }
    
    return hidee.setreq;
}

function SyncText(bind)
{
    return function () {
        bind.value = this.value;
        bind.mark();
    }
}

// Miscellaneous helper functions

function foldl_array ( a, f, i ) {
    i=a[0];    
    for (var j = 1; j < a.length; j++) {
        i = f(i, a[j]);
    }
        
    return i;
}

function test ( f, message ) {
    var msg = !message ? "" : "(" + message + ") ";
    
    return function ( ) {        
        if (!f.apply)
            var i = f(arguments[0]);
        else
            var i = f.apply(this, arguments);
        
        
        if (i==undefined || i==null) {
            alert (msg + foldl_array(arguments, function (a, b) {return a + ', ' + b}) + " -> " + i);
        }
        return i;
    }
}

// Internal helper functions

function ForEachLeaf ( obj, act ) {
    var i=0, t;
    while (t=obj.childNodes[i]) {
        ForEachLeaf (t, act);
        i++;
    }
    act(obj);
}

// Validation functions

function BindMonthYearSelector ( month, year ) {
    year.validate = function () {return month.validate();};
    year.mark = function () {
        if (this.any_change!=undefined) this.any_change();
        month.mark();
    };
    year.onchange = CallMark();
    year.complain = function () { } ;
}

function CallMark ( ) {
    return function () {
        this.mark();
    }
}

function MarkChange ( bind_id, text) {       
    var bind=document.getElementById(bind_id);

    return function () {
        if (this.any_change != undefined) this.any_change();
        if (this.validate()) {
            if (bind) {
                bind.style.display = "none";
                var validationerrorpanel = document.getElementById("validationerrorpanel");
                var validationerrormessage = document.getElementById("validationerrormessage");
                if (jQuery && validationerrormessage && validationerrorpanel) {
                    if ($(validationerrorpanel).attr("ctrl") != '') {
                        if ($(validationerrorpanel).attr("ctrl") == this.id) {
                            $(validationerrorpanel).hide();
                            $(validationerrorpanel).attr("ctrl", "");
                        }
                    }
                }
            }
            if (this.valid_change != undefined) this.valid_change();
        } else {
            if (bind) {
                bind.style.display = "";
                if (jQuery != undefined) {
                    $(bind).html(text);
                    fitcontent(bind);
                }
            }
            if (this.invalid_change != undefined) this.invalid_change();
        }
    }
}

function ValidateComplain ( text ) {
    return function () {
        this.disabled = false;
        //check for required elements and jQuery library first....
        //if not found, then use the "traditional way of displaying error..."
        var validationerrorpanel = document.getElementById("validationerrorpanel");
        var validationerrormessage = document.getElementById("validationerrormessage");
        /*
        error_popup_type:
        0x0: none - no errors indicated.
        0x1: normal window alert.
        0x2: highlight.
        0x4: ust warn alert box.

        */
        //        if (window.ust == undefined) {
        //            window.ust = {};
        //        }
        //        if (window.ust.settings == undefined) {
        //            window.ust.settings = {};
        //        }
        //        if (window.ust.settings.popup_types == undefined) {
        //            window.ust.settings.popup_types = {none:0,normal:1,highlight:2,ustwarn:4};
        //        }
        //        if (window.ust.settings.error_popup_type == undefined) {
        //            window.ust.settings.error_popup_type = window.ust.settings.popup_types.highlight | window.ust.settings.popup_types.ustwarn;
        //        }
        if ((window.ust.settings.error_popup_type) != 0) {
            if (jQuery != undefined) {
                if ((window.ust.settings.error_popup_type & window.ust.settings.popup_types.highlight) == window.ust.settings.popup_types.highlight) {
                    if (validationerrormessage && validationerrorpanel) {
                        var ctrl = this;
                        $(validationerrorpanel).show();
                        $(validationerrormessage).show();
                        $(validationerrormessage).html('Your submission did not meet all of the requirements. Please review and update the highlighted fields below to submit this page.');
                        $(validationerrorpanel).attr("ctrl", this.id);
                        $(validationerrormessage).click(function () {
                            if (ctrl.tagName == 'SPAN' || ctrl.tagName == 'DIV') {
                                $(ctrl).find("INPUT").focus();
                            }
                            $(ctrl).focus();
                        });
                        this.focus();
                        var top = $(validationerrorpanel).offset().top;
                        top = top - 10;
                        if (top >= 0)
                            $("html, body").animate({ scrollTop: top }, "slow");
                        else
                            location.href = "#Top";
                    }
                }
                //
                if ((window.ust.settings.error_popup_type & window.ust.settings.popup_types.ustwarn) == window.ust.settings.popup_types.ustwarn) {
                    $.fn.ustWarn("alert", { message: text });
                }

                if ((window.ust.settings.error_popup_type & window.ust.settings.popup_types.normal) == window.ust.settings.popup_types.normal) {
                    this.focus();
                    alert(text);
                    this.focus();
                }
            }
            else { //old method....
                this.focus();
                alert(text);
                this.focus();
            }
        }
    }
}

function testUnrequired ( ctrl ) {
    while (ctrl) {
        if ((/unrequired/i).test(ctrl.className)) return true;
        if (ctrl.style) {
            if ((/none/i).test(ctrl.style.display)) return true;
            if ((/hidden/i).test(ctrl.style.visibility)) return true;
        }
        ctrl = ctrl.parentNode;
    }
    return false;
}

function ValidateRadioButtons ( button ) {
    var b = document.getElementsByName(button.name);

    function t() {return this.checked}
    function m() {button.mark();};
    
    for (var i=0; i < b.length; i++) {
        b[i].test = t;
        b[i].onclick = m;
    }
    
    return function () {
        var c;
        for (var i=0; i < b.length; i++) {
            if ((c=b[i].test()) != false) return c;
        }
        return false;
    }
}

function ValidateValue (regex) {
    if (regex != null) {
        return function () {
	        var match=regex.exec(this.value);
	        return (match!=null && this.value == match[0]);
        }
    }
		
    return function () {
        return this.value != "";
    }
}


function ValidateCheckBox () {
    return function () {
        return this.checked;
    }
}

function ValidateCustomJS (JS) {
    if (typeof(JS) == 'function') return function() {        
        return JS();
    };
    
    // we can add support for novel forms here!
    return function() {return false;};
}


// A ghost is any control that validation does not understand
function PrepareGhost (ctrl, text, chev) {
    ctrl.complain=ValidateComplain(text);
    ctrl.mark=MarkChange(chev);
}

function PrepareValue (ctrl, text, chev, regex) {
    ctrl.complain=ValidateComplain(text);
    ctrl.mark=MarkChange(chev,text);
    ctrl.onchange=CallMark( );
    ctrl.validate = ValidateValue(regex);
}

function PrepareCheckBox (ctrl, text, chev) {
    ctrl.complain=ValidateComplain(text);
    ctrl.mark=MarkChange(chev,text);
    ctrl.onclick=CallMark( );
    ctrl.validate = ValidateCheckBox();
}

function PrepareButtonMaster (ctrl, text, chev, validate_all, validate_each) {
    ctrl.complain=ValidateComplain(text);
    ctrl.mark=MarkChange(chev,text);
    ctrl.child_change=CallMark( );
    ctrl.validate = validate_all(ctrl.id);
    
    PrepareRadioButtonList (ctrl.id, validate_each);
}

function PrepareCheckBoxesGroup(ctrl, text, chev, validate_all,validate_each) {
    ctrl.complain = ValidateComplain(text);
    ctrl.mark = MarkChange(chev, text);
    ctrl.child_change = CallMark();
    ctrl.validate = validate_all(ctrl.id);

    PrepareCheckBoxesList(ctrl.id, validate_each);
}

function ValidateCheckBoxGroupRequireOne(id) {

    return function () {

        var container = document.getElementById(id);
        if (!container) return true;

        var checked = false;

        var checkboxes = container.getElementsByTagName("INPUT");
        for (var i = 0; i < checkboxes.length; i++) {
            var option = checkboxes[i];
            if (option.type != 'checkbox') continue;
            //
            if (option.validate()) {
                checked = true;
                break;
            }
        }
        return checked;
    }
}

function PrepareCheckBoxesList(containerid, validate_each) {
    var table = document.getElementById(containerid);


    var each_mark = function () {
        if (this.any_change != undefined) this.any_change();
        table.mark();
    }

    var checkboxes = table.getElementsByTagName("INPUT");
    for (var i = 0; i < checkboxes.length; i++) {
        var option = checkboxes[i];
        if (option.type == 'checkbox') {
            option.validate = function () { return this.checked; };
            option.mark = each_mark;
            option.onclick = CallMark();
        }
    }
}

function PrepareRadioButtonList (radioID, validate_each) {
    var i=0;
    var option;
    
    var table=document.getElementById( radioID );
    
    
    var each_mark = function () {
        if (this.any_change!=undefined) this.any_change();
        table.mark();
    }
           
    while (option=document.getElementById( radioID + "_" + i)) {
        option.validate = validate_each;
        option.mark     = each_mark;
        option.onclick  = CallMark();        
        
        i++;
    }
}

function ValidateRadioRequireOne (radioID) {
    return function () {         
        var i=0;
        var checked=false;
        var option;

        while (option=document.getElementById( radioID + "_" + i)) {
	        checked |= option.validate();	        
	        i++;
        }
        
        return checked;
    }
}

function ValidateRadioRequireAll (radioID) {
    return function () {
        var i=0;
        var checked=true;
        var option;
        
        while (option=document.getElementById( radioID + "_" + i)) {
	        checked &= option.validate();
	        i++;
        }
        
        return checked;
    }
}

function PrepareButtonMasterEx(ctrl, text, chev, validate_all, validate_each) {
    ctrl.complain = ValidateComplain(text);
    ctrl.mark = MarkChange(chev, text);
    ctrl.child_change = CallMark();
    ctrl.validate = validate_all(ctrl.id);

    PrepareRadioButtonListEx(ctrl.id, validate_each);
}

function PrepareRadioButtonListEx(radioID, validate_each) {
    var i = 0;
    var option;

    var table = document.getElementById(radioID);


    var each_mark = function () {
        if (this.any_change != undefined) this.any_change();
        table.mark();
    }

    var inputs = table.getElementsByTagName("INPUT");
    var buttons = [];
    for (var x = 0; x < inputs.length; x++) {
        if (inputs[x].type == 'radio') {
            buttons.push(inputs[x]);
        }
    }

    if (buttons.length <= 0) return;

    while (option = buttons[i]) {
        option.validate = validate_each;
        option.mark = each_mark;
        option.onclick = (function (oldclick) {
            return function () {
                if (oldclick) {
                    if (typeof (oldclick) == 'function') {
                        oldclick.call(this);
                    }
                }
                CallMark();
            }
        })(option.onclick);
        i++;
    }
}
function ValidateRadioRequireOneEx(id) {
    return function () {
        var i = 0;
        var checked = false;
        var option;
        var container = document.getElementById(id);
        if (!container) return true;
        var inputs = container.getElementsByTagName("INPUT");
        var buttons = [];
        for (var x = 0; x < inputs.length; x++) {
            if (inputs[x].type == 'radio') {
                buttons.push(inputs[x]);
            }
        }
        if (buttons.length <= 0) return checked;

        while (option = buttons[i]) {
            checked |= option.validate();
            i++;
        }
        if (checked == false) {
            buttons[0].focus();
        }
        return checked;
    }
}

function CauseToFail(ctrl) {
    if (testUnrequired(ctrl)) return false;
    
    var c=ctrl.validate();
    if (c!=true) {
        ctrl.complain(c);
        return true;
    }
    return false;
}

// Page management

function getform () {
	// Get the ASP.NET form
	var theForm = document.forms['aspnetForm'];
	if(!theForm){theForm = document.aspnetForm;}
	
	return theForm;
}


var client_onload = function(){};
var client_onsubmit = function(){return true;};
var client_afterload = function () { };
var firstclass_onsubmit = function () { return true; };

function add_onload ( fn ) {
    var old = client_onload;
    
    client_onload= function () { old(); fn(); };
}

function add_firstclass_onsubmit(fn){
    var old = firstclass_onsubmit;

    firstclass_onsubmit = function () { if (!old()) return false; var f = fn(); return f == undefined || f; }
}

function add_onsubmit ( fn ) {
    var old = client_onsubmit;
    
    client_onsubmit= function () {if (!old()) return false; var f=fn(); return f==undefined || f;}
}

function add_afterload(fn) {
    var old = client_afterload;

    client_afterload = function () { old(); fn(); };
}

var loading;
function validation_onload () {
    loading=true;
    //
    setup_settings();
    //
    client_onload();
    marks_preset();

    //ADDED BY PP 09/26/2011
    client_afterload();

    loading = false;
}

function validation_onsubmit() {
    if (!firstclass_onsubmit()) {
        loading = true;
        if (typeof (marks_preset2) == 'function') {
            marks_preset2();
        }
        loading = false;
        return false;
    }  
    if (!CheckForm()) {
    
        loading=true;
        marks_preset();
        loading=false;
        
        return false;
    }
    
    return client_onsubmit();    
}

function cancel_validation () {
    validation_onsubmit = function () {
        return client_onsubmit();
    }
}

function IsAtoZ(c)
{
	return (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')));
}

function IndexOfAny(s, startingChars, startIndex)
{
	var i = -1;
	for (var arrayIndex in startingChars) {
		var c = startingChars[arrayIndex];
		var j = s.indexOf(c, startIndex);
		if (j >= 0)
		{
			if (i < 0 || j < i) i = j;
		}
	}
	return i;
}

function IsDangerousString(s)
{
	//var matchIndex = 0;
	var startIndex = 0;
	var startingChars = [ '<', '&' ];
	
	while (true)
	{
		var num2 = IndexOfAny(s, startingChars, startIndex);
		if (num2 < 0)
		{
			return false;
		}
		if (num2 == (s.Length - 1))
		{
			return false;
		}
		//matchIndex = num2;
		var ch = s[num2];
		if (ch != '&')
		{
			if ((ch == '<') && ((IsAtoZ(s[num2 + 1]) || (s[num2 + 1] == '!')) || ((s[num2 + 1] == '/') || (s[num2 + 1] == '?'))))
			{
				return true;
			}
		}
		else if (s[num2 + 1] == '#')
		{
			return true;
		}
		startIndex = num2 + 1;
	}
}

