// 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



//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";                    
            }
        }
    } 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 ) {       
    var bind=document.getElementById(bind_id);
    
    return function () {
        if (this.any_change != undefined) this.any_change();
        if (!testUnrequired(bind)) {
            if (this.validate()) {
                bind.style.display = "none" ;
                if (this.valid_change!=undefined) this.valid_change();
            } else {
                bind.style.display = "";
                if (this.invalid_change!=undefined) this.invalid_change();
            }
        }
    }
}

function ValidateComplain ( text ) {
    return function () {
        this.disabled = false;
        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);
    ctrl.onchange=CallMark( );
    ctrl.validate = ValidateValue(regex);
}

function PrepareCheckBox (ctrl, text, chev) {
    ctrl.complain=ValidateComplain(text);
    ctrl.mark=MarkChange(chev);
    ctrl.onclick=CallMark( );
    ctrl.validate = ValidateCheckBox();
}

function PrepareButtonMaster (ctrl, text, chev, validate_all, validate_each) {
    ctrl.complain=ValidateComplain(text);
    ctrl.mark=MarkChange(chev);
    ctrl.child_change=CallMark( );
    ctrl.validate = validate_all(ctrl.id);
    
    PrepareRadioButtonList (ctrl.id, validate_each);
}

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 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 () { };

function add_onload ( fn ) {
    var old = client_onload;
    
    client_onload= function () { old(); fn(); };
}

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;
    
    client_onload();
    marks_preset();

    //ADDED BY PP 09/26/2011
    client_afterload();

    loading = false;
}

function validation_onsubmit () {    
    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;
	}
}

