/*
 *  Javascript Global Functions
 *  -----------------------------------------------------------------------------------------------   
*/

/*
start
Navitaire Specific jquery selector extensions
*/
// Add this code anywhere you want (after jQuery has been loaded). 
// Edit it to add your own expressions. 
jQuery.extend(jQuery.expr[':'], { 

    submitable: "!a.disabled&&(a.selected||a.checked||(a.nodeName.toUpperCase()=='TEXTAREA')||(a.nodeName.toUpperCase()=='INPUT'&&(a.type=='text'||a.type=='hidden'||a.type=='password')))",  
    nothidden: "a.type&&a.type!='hidden'"
});
/*
Navitaire Specific jquery selector extensions
end
*/

/*global SKYSALES */

SKYSALES = {};

//A pointer to the active resource object instance
SKYSALES.Resource = {};

//A static helper class
SKYSALES.Util = {};

//A namespace for class definitions
SKYSALES.Class = {};

//Return the main resource instance, this object is instantiated in the common.xslt
SKYSALES.Util.getResource = function ()
{
    return SKYSALES.Resource;
};

$(function(){
    document['SkySales'] = document.forms['SkySales'];
});

/*
function showHint(obj)
{
    Common.Hint.showHint(obj);
}

function showHintWithReference(obj, referenceId)
{
    Common.Hint.showHint(obj, obj.hint, null, null, referenceId);
}

function hideHint(obj)
{
    Common.Hint.hideHint(obj);
}
*/

function showStatus(message)
{
    if(message == null)
        message = '';
    window.status=message;
    return true;
}

var Common = function ()
{
    var thisCommon = this;
    thisCommon.allInputObjects = null;
    
    thisCommon.ready = function()
    {
        $(document).ready
        (
            function()
            {
                thisCommon.addKeyDownEvents();
                thisCommon.addSetAndEraseEvents();
                var hint = new Hint();
                hint.addHintEvents();
            }
        )
    }
    
    thisCommon.getAllInputObjects = function()
    {
        if (this.allInputObjects == null)
        {
            this.allInputObjects = $(':input');
        }
        return this.allInputObjects;
    }
    
    thisCommon.addSetAndEraseEvents = function()
    {
        thisCommon.getAllInputObjects().each
        (
            function(index)
            {   
                if (this.requiredempty == null)
                {
                    this.requiredempty = this.getAttribute('requiredempty');
                }
                if (this.requiredempty != null)
                {
                    $(this).focus
                    (
                        function()
                        {
                            thisCommon.eraseElement(this, this.requiredempty);
                        }
                    );
                    
                    $(this).blur
                    (
                        function()
                        {
                            thisCommon.setElement(this, this.requiredempty);
                        }
                    );
                }
            }
        );
    }
    
    thisCommon.eraseElement = function(element, defaultValue)
    {
        if (element.value.toLowerCase() == defaultValue.toLowerCase())
        {
            element.value = "";
        }
    }
    
    thisCommon.setElement = function(element, defaultValue)
    {
        if (element.value == "")
        {
            element.value = defaultValue;
        }
    }

    thisCommon.stopSubmit = function ()
    {
        // Remove the submit event so that you can click the submit button
        $('form').unbind('submit', thisCommon.stopSubmit);
        return false;
    };
    
    thisCommon.addKeyDownEvents = function ()
    {
        var keyFunction = function (e)
        {
            if (e.keyCode === 13)
            {
                // Stop the enter key in opera
                $('form').submit(thisCommon.stopSubmit);
                return false;
            }
            return true;
        };
        $(':input').keydown(keyFunction);
    };

}

Common.addEvent = function(obj, eventString, functionRef)
{
    $(obj).bind(eventString, functionRef);
}

var Dhtml = function()
{
    var thisDhtml = this;
    
    thisDhtml.getX = function(obj)
    {
        var pos = 0;
        if (obj.x)
        {
            pos += obj.x;
        }
        else if (obj.offsetParent)
        {
            while (obj.offsetParent)
            {
                pos += obj.offsetLeft;
                obj	= obj.offsetParent;
            }
        }
        return pos;
    }
    
    thisDhtml.getY = function(obj)
    {
        var count = 0;
        var pos = 0;
        if (obj.y)
        {
            pos += obj.y;
        }
        else if (obj)
        {
             while (obj)
             {		
                pos += obj.offsetTop;
                obj = obj.offsetParent;
            }
        }
        return pos;
    }
    
}

var Hint = function()
{
    var thisHint = this;
    thisHint.addHintEvents = function()
    {
        common.getAllInputObjects().each
        (
            function(index)
            {   
                if (this.hint == null)
                {
                    this.hint = this.getAttribute('hint');
                }
                if (this.hint != null)
                {
                    if (this.tagName.toLowerCase() == 'input')
                    {
                        thisHint.addHintFocusEvents(this);
                    }
                    else
                    {
                        thisHint.addHintHoverEvents(this);
                    }
                }
            }
        );
    }

    thisHint.addHintFocusEvents = function(obj, hintText)
    {
        $(obj).focus
        (
            function()
            {
                thisHint.showHint(obj, hintText);
            }
        );
        $(obj).blur
        (
            function()
            {
                thisHint.hideHint(obj, hintText);
            }
        );
    }

    thisHint.addHintHoverEvents = function(obj, hintText)
    {
        $(obj).hover
        (
            function()
            {
                thisHint.showHint(obj, hintText);
            },
            function()
            {
                thisHint.hideHint(obj, hintText);
            }
        );
    }

    thisHint.getHintDivId = function()
    {
        return "cssHint";
    }

    thisHint.showHint = function(obj, hintHtml, xOffset, yOffset, referenceId)
    {
        var jQueryObj = $(obj);
        var hintDivId = thisHint.getHintDivId();
        var jQueryHintDiv = $('#' + hintDivId);
        var x = 0;
        var y = 0;
        var defaultXOffset = 0;
        var defaultYOffset = 0;
        
        if (xOffset == null)
        {
            xOffset = obj.hintxoffset;
        }
        if (yOffset == null)
        {
            yOffset = obj.hintyoffset;
        }
        
        if (referenceId == null)
        {
            referenceId = obj.hintReferenceid;
        }
        var referenceObject = $('#' + referenceId).get(0);
        
        var dhtml = new Dhtml();
        if (referenceObject == null)
        {
            x = dhtml.getX(obj);
            y = dhtml.getY(obj);
            if (xOffset == null)
            {
		        x += obj.offsetWidth + 5;
            }
        }
        else
        {
            x = dhtml.getX(referenceObject);
            y = dhtml.getY(referenceObject);
            if (xOffset == null)
            {
		        x += referenceObject.offsetWidth + 5;
            }
        }
    	
        if (hintHtml == null)
        {
            if (obj.hint != null)
            {
	            hintHtml = obj.hint;
            }
        }
        //alert(hintHtml);
        jQueryHintDiv.html(hintHtml);
        jQueryHintDiv.show();
        xOffset	= (xOffset != null) ? xOffset : defaultXOffset;
        yOffset	= (yOffset != null) ? yOffset : defaultYOffset;
        var leftX = parseInt(xOffset) + parseInt(x);
        var leftY = parseInt(yOffset) + parseInt(y);
        jQueryHintDiv.css('left', leftX + 'px');
        jQueryHintDiv.css('top', leftY + 'px');
    }

    thisHint.hideHint = function(obj)
    {
        var hintDivId = thisHint.getHintDivId();
        $('#' + hintDivId).hide();
    }
}


var errorsHeader = 'Please correct the following.\n\n';

function Validate(form, controlID, errorsHeader, regexElementIdFilter)
{
	// set up properties
	this.form = form;
	this.namespace = controlID;
	this.errors = '';
	this.setfocus = null;
	this.errorsHeader = errorsHeader;
	this.namedErrors = new Array();
	if (regexElementIdFilter)
	{
		this.regexElementIdFilter = regexElementIdFilter;
	}
	// set up attributes
	this.requiredAttribute = 'required';
	this.requiredEmptyAttribute = 'requiredempty';
	this.validationTypeAttribute = 'validationtype';
	this.regexAttribute = 'regex';
	this.minLengthAttribute = 'minlength';
	this.numericMinLengthAttribute = 'numericminlength';
	this.maxLengthAttribute = 'maxlength';
	this.numericMaxLengthAttribute = 'numericmaxlength';
	this.minValueAttribute = 'minvalue';
	this.maxValueAttribute = 'maxvalue';
	this.equalsAttribute = 'equals';
	
	// set up error handling attributes
	this.defaultErrorAttribute = 'error';
	this.requiredErrorAttribute = 'requirederror';
	this.validationTypeErrorAttribute = 'validationtypeerror';
	this.regexErrorAttribute = 'regexerror';
	this.minLengthErrorAttribute = 'minlengtherror';
	this.maxLengthErrorAttribute = 'maxlengtherror';
	this.minValueErrorAttribute = 'minvalueerror';
	this.maxValueErrorAttribute = 'maxvalueerror';
	this.equalsErrorAttribute = 'equalserror';
	
	// set up error handling default errors
	this.defaultError = '{label} is invalid.';
	this.defaultRequiredError = '{label} is required.';
	this.defaultValidationTypeError = '{label} is invalid.';
	this.defaultRegexError = '{label} is invalid.';
	this.defaultMinLengthError = '{label} is too short in length.';
	this.defaultMaxLengthError = '{label} is too long in length.';
	this.defaultMinValueError = '{label} must be greater than {minValue}.';
	this.defaultMaxValueError = '{label} must be less than {maxValue}.';
	this.defaultEqualsError = '{label} is not equal to {equals}';
	this.defaultNotEqualsError = '{label} cannot equal {equals}';
	
	this.defaultValidationErrorClass = 'validationError';
	this.defaultValidationErrorLabelClass = 'validationErrorLabel';
	
	// add methods to object
	this.run = run;
	this.runBySelector = runBySelector;
	this.validateSingleElement = validateSingleElement;
	this.outputErrors = outputErrors;
	this.checkFocus = checkFocus;
	this.setError = setError;
	this.cleanAttributeForErrorDisplay = cleanAttributeForErrorDisplay;
	this.validateRequired = validateRequired;
	this.validateType = validateType;
	this.validateRegex = validateRegex;
	this.validateMinLength = validateMinLength;
	this.validateMaxLength = validateMaxLength;
	this.validateMinValue = validateMinValue;
	this.validateMaxValue = validateMaxValue;
	this.validateEquals = validateEquals;
	this.isExemptFromValidation = isExemptFromValidation;
	
	// add validation type methods
	this.setValidateTypeError = setValidateTypeError;
	this.validateAmount = validateAmount;
	this.validateDate = validateDate;
	this.validateMod10 = validateMod10;
	this.validateNumeric = validateNumeric;
	
	//this.nonePattern = '^\.*$';
	this.stringPattern = '^.+$';	
	this.upperCaseStringPattern = '^[A-Z]([A-Z)|\s)*$';
	this.numericPattern = '^\\d+$';
	this.numericStripper = /\D/g;
	this.alphaNumericPattern = '^\\w+$';
	
	var amountSeparators = '(\\.|,)';
	this.amountPattern = '^(\\d+(' + amountSeparators + '\\d+)*)$';
	
	this.dateYearPattern = '^\\d{4}$';
	this.dateMonthPattern = '^\\d{2}$';
	this.dateDayPattern = '^\\d{2}$';
	
    this.emailPattern = '^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)(([\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$';
}

function checkKeyPressed(evt, input)
{
  evt = (evt) ? evt : (window.event) ? event : null;
  if (evt)
  {
    var charCode = (evt.charCode) ? evt.charCode :
                   ((evt.keyCode) ? evt.keyCode :
                   ((evt.which) ? evt.which : 0));
    if (charCode == 13) 
    {
        input.click();
        
    }
  }    
}

function run(prefix)
{
    var nodeArray = $('#SkySales').find(':input').get();
	// run validation on the form elements
	for (var i = 0; i < nodeArray.length; i++)
	{
		var e = nodeArray[i];
		
		if (!this.isExemptFromValidation(e))
		{
			this.validateSingleElement(e);
		}
	}
	
    return this.outputErrors(prefix);
}

function runBySelector(selectorString)
{
    var nodeArray = $(selectorString).find(':input').get();
	// run validation on the form elements
	for (var i = 0; i < nodeArray.length; i++)
	{
	    var node = nodeArray[i];
		this.validateSingleElement(node);
	}
	return false;
}

function isExemptFromValidation(e)
{
	if (e.id.indexOf(this.namespace) != 0)
	{
		return true;
	}
	
	if ((this.regexElementIdFilter) && (!e.id.match(this.regexElementIdFilter)))
	{
		return true;
	} 
	
	return false;
} 

function outputErrors(prefix)
{
	// if there is an error output it
	if(this.errors)
	{
		//alert(this.errorsHeader + this.errors);
		if( $('#'+prefix+'_error').length )
	        $('#'+prefix+'_error').html(this.errors+"<br/>");
	    else
		    $("#error-wrapper").html("<br/>" + this.errors);
    		
	    if (this.setfocus)
	    {
		    this.setfocus.focus();
	    }		
		return false;
	}
	else
	{
	    if( $('#'+prefix+'_error').length )
	        $('#'+prefix+'_error').html("");
	    else
		    $("#error-wrapper").html("");
	}
		
	return true;
}

function validateSingleElement(e)
{
    $(e).removeClass(this.defaultValidationErrorClass);
    $("label[@for=" + e.id + "]").eq(0).removeClass(this.defaultValidationErrorLabelClass);
    
    this.validateRequired(e);
	// only validate the rest if they actually have something
	var value = getValue(e);
    if (this.errors.length < 1 && value && 0 < value.length)
    {
	    this.validateType(e);
	    this.validateRegex(e);
	    this.validateMinLength(e);
	    this.validateMaxLength(e);
	    this.validateMinValue(e);
	    this.validateMaxValue(e);
	    this.validateEquals(e);
    }
}

function checkFocus(e)
{
	if (!this.setfocus)
	{
		this.setfocus = e;
	}
}

function validateRequired(e)
{
    var requiredAttribute = this.requiredAttribute;
    var requiredEmptyAttribute = this.requiredEmptyAttribute;
    var required = eval('(e.' + requiredAttribute + ');');
    var requiredEmptyString = eval('(e.' + requiredEmptyAttribute + ');');
    
    if (required == null)
    {
        required = e.getAttribute(requiredAttribute);
    }
    if (requiredEmptyString == null)
    {
        requiredEmptyString = e.getAttribute(this.requiredEmptyAttribute);
    }
    
    if (required != null)
    {
        required = required.toString();
        required = required.toLowerCase();
        if (requiredEmptyString != null)
        {
            requiredEmptyString = requiredEmptyString.toLowerCase();
        }
        
        if (required == 'true')
        {
            var value = getValue(e);
            if (value != null)
            {
                if((value.length < 1) || (value.toLowerCase() == requiredEmptyString))
	            {
		            this.setError(e, this.requiredErrorAttribute, this.defaultRequiredError);
	            }
	        }
	    }
	}
}

function getValue(e)
{
    if(e)
    {
        if (e.type == 'radio')
        {
            if (e.getAttribute('name').length > 0)
            {
                var arrayOfRadioButtons = document.getElementsByName(e.getAttribute('name'));
                for (var i = 0; i < arrayOfRadioButtons.length; i++)
                {
                    if (arrayOfRadioButtons[i].checked == true)
                    {
                        return arrayOfRadioButtons[i].value;
                    }
                }
            }
            return '';
        }
        else if (e.type == 'checkbox')
        {
            if (e.checked == true)
            {
                return e.value;
            }
        }
        else 
        {
            return e.value;
        }
    }
    return '';
}

function validateType(e)
{
    var type = eval('(e.' + this.validationTypeAttribute + ');');
    if (type == null)
    {
        type = e.getAttribute(this.validationTypeAttribute);
    }
	//var type = e.getAttribute(this.validationTypeAttribute);
	var value = getValue(e);
	
	if (type) 
	{
	    type = type.toLowerCase();
		if ((type == 'address') && (!value.match(this.stringPattern)))
		{
			this.setValidateTypeError(e);
		}
		else if ((type == 'alphanumeric') && (!value.match(this.alphaNumericPattern)))
		{
			this.setValidateTypeError(e);
		}
		else if ((type == 'amount') && (!this.validateAmount(value)))
		{
			this.setValidateTypeError(e);
		}
		else if ((type == 'country') && (!value.match(this.stringPattern)))
		{
			this.setValidateTypeError(e);
		}
		else if ((type == 'email') && (!value.match(this.emailPattern)))
		{
			this.setValidateTypeError(e);
		}
		else if ((type == 'mod10') && (!this.validateMod10(value)))
		{
			this.setValidateTypeError(e);
		}
		else if ((type == 'name') && (!value.match(this.stringPattern)))
		{
			this.setValidateTypeError(e);
		}
		else if ((type == 'numeric') && (!this.validateNumeric(value)))
		{
			this.setValidateTypeError(e);
		}
		else if ((type.indexOf('date') == 0) && (!this.validateDate(e, type, value)))
		{
			this.setValidateTypeError(e);
		}
		else if ((type == 'state') && (!value.match(this.stringPattern)))
		{
			this.setValidateTypeError(e);
		}
		else if ((type == 'string') && (!value.match(this.stringPattern)))
		{
			this.setValidateTypeError(e);
		}
		else if ((type == 'uppercasestring') && (!value.match(this.upperCaseStringPattern)))
		{
			this.setValidateTypeError(e);
		}
		else if ((type == 'zip') && (!value.match(this.stringPattern)))
		{
			this.setValidateTypeError(e);
		}
	}
}

function validateRegex(e)
{
    var regex = eval('(e.' + this.regexAttribute + ');');
    if (regex == null)
    {
        regex = e.getAttribute(this.regexAttribute);
    }
    //var regex = e.getAttribute(this.regexAttribute);
	var value = getValue(e);
	if ((regex) && (!value.match(regex)))
	{
		this.setError(e, this.regexErrorAttribute, this.defaultRegexError);
	}
}

function validateMinLength(e)
{
    var length = eval('(e.' + this.minLengthAttribute + ');');
    var numericLength = eval('(e.' + this.numericMinLengthAttribute + ');');
    if (length == null)
    {
        length = e.getAttribute(this.minLengthAttribute);
    }
    if (numericLength = null)
    {
        numericLength = e.getAttribute(this.numericMinLengthAttribute);
    }
	//var length = e.getAttribute(this.minLengthAttribute);
	//var numericLength = e.getAttribute(this.numericMinLengthAttribute);
	var value = getValue(e);
	
	if ((0 < length) && (value.length < length))
	{
		this.setError(e, this.minLengthErrorAttribute, this.defaultMinLengthError);
	}
	else if ((0 < numericLength)  && (0 < value.length) && (value.replace(this.numericStripper, '').length < numericLength))
	{
		this.setError(e, this.minLengthErrorAttribute, this.defaultMinLengthError);
	}
}

function validateMaxLength(e)
{
    var length = eval('(e.' + this.maxLengthAttribute + ');');
    var numericLength = eval('(e.' + this.numericMaxLengthAttribute + ');');
    if (length == null)
    {
        length = e.getAttribute(this.maxLengthAttribute);
    }
    if (numericLength = null)
    {
        numericLength = e.getAttribute(this.numericMaxLengthAttribute);
    }
	//var length = e.getAttribute(this.maxLengthAttribute);
	//var numericLength = e.getAttribute(this.numericMaxLengthAttribute);
	var value = getValue(e);
				
	if ((0 < length) && (length < value.length))
	{
		this.setError(e, this.maxLengthErrorAttribute, this.defaultMaxLengthError);
	}
	else if ((0 < numericLength)  && (0 < value.length) && (numericLength < value.replace(this.numericStripper, '').length))
	{
		this.setError(e, this.maxLengthErrorAttribute, this.defaultMaxLengthError);
	} 
}

function validateMinValue(e)
{
    var min = eval('(e.' + this.minValueAttribute + ');');
    if (min == null)
    {
        min = e.getAttribute(this.minValueAttribute);
    }
	//var min = e.getAttribute(this.minValueAttribute);
	
	if ((min != null) && (0 < min.length))
	{
	    var value = getValue(e);
	    
		if ((5 < min.length) && (min.substring(0, 5) == '&gt;='))
		{
			if (value < parseFloat(min.substring(5, min.length)))
			{
				this.setError(e, this.minValueErrorAttribute, this.defaultMinValueError);
			}
		}
		else if ((4 < min.length) && (min.substring(0, 4) == '&gt;'))
		{
			if (value <= parseFloat(min.substring(4, min.length)))
			{
				this.setError(e, this.minValueErrorAttribute, this.defaultMinValueError);
			}
		}
		else if (value < parseFloat(min))
		{
			this.setError(e, this.minValueErrorAttribute, this.defaultMinValueError);
		}
	}
}

function validateMaxValue(e)
{
    var max = eval('(e.' + this.maxValueAttribute + ');');
    if (max == null)
    {
        max = e.getAttribute(this.maxValueAttribute);
    }
	//var max = e.getAttribute(this.maxValueAttribute);
	
	if ((max != null) && (0 < max.length))
	{
	    var value = getValue(e);
	    
		if ((5 < max.length) && (max.substring(0, 5) == '&lt;='))
		{
			if (value > parseFloat(max.substring(5, max.length)))
			{
				this.setError(e, this.maxValueErrorAttribute, this.defaultMaxValueError);
			}
		}
		else if ((4 < max.length) && (max.substring(0, 4) == '&lt;'))
		{
			if (value >= parseFloat(max.substring(4, max.length)))
			{
				this.setError(e, this.maxValueErrorAttribute, this.defaultMaxValueError);
			}
		}
		else if (parseFloat(value) > max)
		{
			this.setError(e, this.maxValueErrorAttribute, this.defaultMaxValueError);
		}
	}
}

function validateEquals(e)
{
	// eventually this should be equipped to do string
	// comparison as well as other element comparisons
	
	var equal = eval('(e.' + this.equalsAttribute + ');');
	if (equal == null)
	{
	    equal = e.getAttribute(this.equalsAttribute);
	}
	//var equal = e.getAttribute(this.equalsAttribute);
	
	if ((equal != null) && (0 < equal.length))
	{
	    var value = getValue(e);
	    
		if ((2 < equal.length) && (equal.substring(0, 2) == '!='))
		{
			if (value == equal.substring(2, equal.length))
			{
				this.setError(e, this.equalsErrorAttribute, this.defaultEqualsError);
			}
		}
		else if ((2 < equal.length) && (equal.substring(0, 2) == '=='))
		{
			if (value != equal.substring(2, equal.length))
			{
				this.setError(e, this.equalsErrorAttribute, this.defaultEqualsError);
			}
		}
		else if (equal.charAt(0) == '=')
		{
			if (value != equal.substring(1, equal.length))
			{
				this.setError(e, this.equalsErrorAttribute, this.defaultEqualsError);
			}
		}
		else if (value != equal)
		{
			this.setError(e, this.equalsErrorAttribute, this.defaultEqualsError);
		}
	}
}

function setValidateTypeError(e)
{
	this.setError(e, this.validationTypeErrorAttribute, this.defaultValidationTypeError);
	
}

function setError(e, errorAttribute, defaultTypeError)
{
    if (e.type == 'radio')
    {
        var name = e.getAttribute('name');
        if (name.length > 0)
        {
            if (this.namedErrors[name] != null)
            {
                return;
            }
            this.namedErrors[name] = name;
        }
    }
         
    var error = eval('(e.' + errorAttribute + ');');
    if (error == null)
    {
        error = e.getAttribute(errorAttribute);
    }
	//var error = e.getAttribute(errorAttribute);
	if (!error)
	{
		if (eval('(e.' + this.defaultErrorAttribute + ');'))
		{
			error = eval('(e.' + this.defaultErrorAttribute + ');');
		}
		else if (defaultTypeError)
		{
			error = defaultTypeError;
		}
		else
		{
			error = this.defaultError;
		}
	}
	//alert(errorAttribute + "\n" + error + "\n" + e.requiredError);
	
	// this would make more sense but it doesn't work
	// so i'll do each explicitly while i make this work
	var results = error.match(/{\s*(\w+)\s*}/g);
	if (results)
	{
		for (var i = 0; i < results.length; i++)
		{
			var dollarOne = results[i].replace(/{\s*(\w+)\s*}/, '$1');
			error = error.replace(/{\s*\w+\s*}/, this.cleanAttributeForErrorDisplay(e, dollarOne));
		}
	}
	
	$(e).addClass(this.defaultValidationErrorClass);
	$("label[@for=" + e.id + "]").eq(0).addClass(this.defaultValidationErrorLabelClass);
	//this.errors += error + '\n';
	this.errors += error + "<br/>";
	this.checkFocus(e);
	
}

function cleanAttributeForErrorDisplay(e, attributeName)
{
    attributeName = attributeName.toLowerCase();
	var attribute = "";
	if (attributeName == 'label')
	{
	    attribute = $("label[@for=" + e.id + "]").eq(0).text();
	}
	if ((attribute == null) || (attribute == ""))
	{
	    attribute = e.id;
	    //attribute = eval('(e.' + attributeName + ');');
	    //attribute = e.getAttribute(attributeName.toLowerCase());
	}
	
	if (attribute == null)
	{
		return attributeName;
	}
	
	if (attributeName.match(/^(minvalue|maxvalue)$/i))
	{
		return attribute.replace(/[^\d.,]/g, '');
	}
	
	return attribute;
}

function validateAmount(amount)
{
	if ((!amount.match(this.amountPattern)) || (amount == 0))
	{
		return false;
	}
	
	return true;
}

function validateDate(e, type, value)
{
    var lowerCaseType = '';
    if (type)
    {
        lowerCaseType = type.toLowerCase();
    }
	var today = new Date();
	
	if ((lowerCaseType == 'dateyear') && ((value < today.getYear()) || (!value.match(this.dateYearPattern))))
	{
		return false;
	}
	//just make sure it is two digits for now
	else if ((lowerCaseType == 'datemonth') && (!value.match(this.dateMonthPattern)))
	{
		return false;
	}
	//just make sure it is two digits for now
	else if ((lowerCaseType == 'dateday') && (!value.match(this.DateDayPattern)))
	{
		return false;
	}
	
	return true;
}

function validateMod10(cardNumber)
{
	var ccCheckRegExp = /\D/;
	var cardNumbersOnly = cardNumber.replace(/ /g, "");
		
	if (!ccCheckRegExp.test(cardNumbersOnly))
	{
		var numberProduct;
		var checkSumTotal = 0;
		
		while (cardNumbersOnly.length < 16)
		{
			cardNumbersOnly = '0' + cardNumbersOnly;
		}

		for (digitCounter = cardNumbersOnly.length - 1; 0 <= digitCounter; digitCounter -= 2)
		{
			checkSumTotal += parseInt (cardNumbersOnly.charAt(digitCounter));
			numberProduct = String((cardNumbersOnly.charAt(digitCounter - 1) * 2));
			for (var productDigitCounter = 0; productDigitCounter < numberProduct.length; productDigitCounter++)
			{
				checkSumTotal += parseInt(numberProduct.charAt(productDigitCounter));
			}
		}

		return (checkSumTotal % 10 == 0);
	}

	return false;
}

function validateNumeric(number)
{
	number = number.replace(/\s/g, '');
	
	if (!number.match(this.numericPattern))
	{
		return false;
	}
	
	return true;
}

function validateBySelector(selectorString)
{
    if (selectorString != null)
    {
        // run validation on the form elements
        var validate = new Validate(null, '', errorsHeader, null);
        validate.runBySelector(selectorString);
	    return validate.outputErrors();
    }
    return true;
}

function validate(controlID, elementName, filter)
{
    //make sure we can run this javascript
 	if (document.getElementById && document.createTextNode)
	{
	    // check if you can getAttribute if you can it is an element use the id.
	    if (controlID.getAttribute)
	    {
	        controlID = controlID.getAttribute("id").replace(/_\w+$/, "");
	    }
	    var validate = new Validate(document['SkySales'], controlID + '_', errorsHeader, filter);
		
		if (elementName)
		{
		    var e = elementName;
		    if (!elementName.getAttribute)
		    {
		        e = document.getElementById(controlID + "_" + elementName);
			}
		    validate.validateSingleElement(e);
			return validate.outputErrors();
		}
		
		return validate.run(controlID);
	}
  	
  	// could not use javascript rely on server validation
  	return true;
}

var preventDoubleClick = function ()
{
    return true;
};

var events = new Array();

function register(eventName, functionName)
{
	if (eval(events[eventName]) == null)
	{
		events[eventName] = new Array();
	}
	events[eventName][events[eventName].length]	= functionName;
}

function raise(eventName, eventArgs)
{
	var undefined;

	if (events[eventName] != undefined)
	{
		for (var ix=0; ix<events[eventName].length; ix++)
		{
			if ( eval(events[eventName][ix] + "(eventArgs)") == false)
			{
				return false;
			}
		}
	}
	
	return true;
}

function WindowLoadEventArgs()
{
}

function WindowInitialize()
{
    var originalOnLoad = window.onload;
    //fix this up so initialize is synched with everything else
    $(window).ready(function()
        {
            raise('WindowLoad', new WindowLoadEventArgs());
   
            if (originalOnLoad)
            {
                originalOnLoad();
            }
        });
}

function debug()
{
    var items = debug.arguments.length;
    if (items > 0)
    {
        var strbuf = '' + debug.arguments[0] + ' [';
        
        for (var i=1; i < items; i++)
        {
            strbuf += '' + debug.arguments[i];
            if (items != (i + 1))
            {
              strbuf += ', ';
            }
        }
        alert(strbuf + ']');
    }
}

function displayPopUpConverter()
{
    var url = 'CurrencyConverter.aspx';

    if (!window.converterWindow || converterWindow.closed)
    {
      converterWindow = window.open(url,'converter','width=360,height=300,toolbar=0,status=0,location=0,menubar=0,scrollbars=1,resizable=1');
    }
    else
    {
      converterWindow.open(url,'converter','width=360,height=300,toolbar=0,status=0,location=0,menubar=0,scrollbars=1,resizable=1');
      converterWindow.focus();
    }
 }

//Function to hide/show controls. Inputs are the control you want to hide and the dependent control 
//or which control is interacted with to trigger the hide/show of the other control.
function hideShow( hideControl, depControl )
{
    if ( document.getElementById && document.getElementById(hideControl) )
    {
      var controlHide = hideControl;
      var controlDepend = depControl;
      if ( document.getElementById(controlDepend).checked == true )
      {
        document.getElementById(controlHide).style.display = "inline";
      }else{
        document.getElementById(controlHide).style.display = "none";
      }
    }
}
 
 var jsLoadedCommon = true;



// <balanceHeight_javascript>

function balanceHeight(idContainer, idLeft, idRight)
{
	if (document.getElementById)
	{
		hLeft 	= document.getElementById(idLeft).clientHeight;
		hRight  = document.getElementById(idRight).clientHeight;

		if (hLeft > hRight)
		{
			document.getElementById(idContainer).style.height = hLeft + "px";
		}
	}
}

// </balanceHeight_javascript>

/* Page Behaviors */

//Toggle the left side panels when clicked
      $(document).ready(function(){
      $("div.atAGlanceDivHeader").click(
          function()
          {
            $(this).next().toggle();
          }
          );
      }); 
      
      
      $(function(){
        //$("input.Date").datePicker();   //Market selection fails here
      });
      //initialize time clases
      $(function()
      {
        var i;
        for(i = 0; i < 23; i++)
        {
            $("select.Time").append("<option value="+i+">"+i+"</option>");
        }
      }); 
      
function noThanks()
{
	$('#dccCont').show('slow');
}      

function noShowThanks()
{
    $('#dccCont').hide('slow');
}
      
function dccSwitchBack()
{
    document.getElementById('PaymentInputDCCOfferDisplayView_RadioButtonInlineDccStatusOfferAccept').checked = true;    
    $('#dccCont').hide('slow');
}      

$(document).ready(function() {
  /* AOS Availability */
  $('.hideShow').hide();
  $('a.showContent').click(function() {
	$(this).parent().find('div.hideShow').show('slow');
	return false;
  });
  $('a.hideContent').click(function() {
	$(this).parent().parent('.hideShow').hide('slow');
	return false;
  });
  /* Drop-down menus */
  $('a.toggleSlideContent').click(function() {
	$("div").find('.slideDownUp').slideToggle('fast').toggle();
	return false;
  });
});

//load metaobjects (used for validation)
$( function() {
    $.metaobjects({clean: false});    
} );


var common = new Common();
common.ready();
/* START Functions used for market drop down lists, no longer generated code, should be included anywhere that the drop down market hash is desired*/
			function changeDest(o, d, dVal)
				{
					if (!document.images) 
				    {	
				        return;	
				    }
				    if (!d) 
				    { 
				        alert("There's no DropDownDest!");	
				        return;	
				    }

					var dLabel = d.options[0].text;
     				var oIx = window.parseInt(o.selectedIndex, 10);
					var dIx = 0;
					var name = '';

					if (oIx > 0)
					{
						var oVal = o.options[oIx].value;

						// clear and begin new destList
						d.length = 1;
						d.options[0] = new Option(dLabel, '');
                        if(d.requiredempty)
                        {
						    d.options[0].value = d.requiredempty;
                        }
                        
						for (var i=0; i < SortedStations.length; i++)
						{
							for (j=0; j<Stations[oVal].mkts.length; j++)
							{
								var stnCode	= Stations[oVal].mkts[j];
								if(Stations[stnCode])
								{
								    if ((SortedStations[i] == stnCode) && (Stations[stnCode].validDest == true))
								    {
									    if ( stnCode == dVal ) { dIx = d.length; }

									    d.length += 1;
									    if (showStationCodes)
									    {
										    name = Stations[stnCode].name + ' (' + stnCode + ')';
									    }
									    else
									    {
										    name = Stations[stnCode].name;
									    }
									    d.options[d.length-1] = new Option( name );
									    d.options[d.length-1].value = stnCode;
									    break;
								    }
								}
							}

							if (d.length-1 == Stations[oVal].mkts.length) { break; }
						}

						d.selectedIndex = dIx;
					}
					else
					{
						fillList(d, dVal);
					}
				} // end changeDest

				function fillList(d, dVal)
				{
					if (!d) 
				    { 
				        alert("There's no DropDownDest!"); 
				        return; 
				    }
					var dLabel = d.options[0].text;

					if ((dVal == '') && (d.selectedIndex > -1))
					{
						dVal = d.options[ d.selectedIndex ].value;
					}
					var dIx = 0;
					
					d.length = 1;
				    d.options[0] = new Option(dLabel, dVal);
					if(d.requiredempty)
                        {
						    d.options[0].value = d.requiredempty;
                        }
                        
					var name = '';
					var i = 0;
    				for (i = 0; i < SortedStations.length; i++)
					{
						stnCode	= SortedStations[i];
                        var station = Stations[stnCode];
                        if (!station)
                        {
                            continue;
                        }

						if (Stations[stnCode].validDest == true)
						{
							if (dVal == stnCode)
							{
								dIx = d.length;
							}
							d.length += 1;
							if (showStationCodes)
							{
								name = Stations[stnCode].name + ' (' + stnCode + ')';
							}
							else
							{
								name = Stations[stnCode].name;
							}
							d.options[d.length-1] = new Option( name);
							d.options[d.length-1].value = stnCode;
						}
					}

					d.selectedIndex = dIx;

				}	// end fillList

/*END Functions used for market drop down lists, no longer generated code, should be included anywhere that the drop down market hash is desired*/

//Replace characters that could not be stored in a cookie
SKYSALES.Util.decodeUriComponent = function (str)
{
    str = str || '';
    if (window.decodeURIComponent)
    {
        str = window.decodeURIComponent(str);
    }
    str = str.replace(/\+/g, ' ');
    return str;
};

//Replace characters for cookie storage
SKYSALES.Util.encodeUriComponent = function (str)
{
    str = str || '';
    if (window.encodeURIComponent)
    {
        str = window.encodeURIComponent(str);
    }
    return str;
};

//Return the main resource instance, this object is instantiated in the common.xslt
SKYSALES.Util.getResource = function ()
{
    return SKYSALES.Resource;
};

//Douglas Crockford's inheritance method
SKYSALES.Util.extendObject = function (o)
{
    var F = function () {};
    F.prototype = o;
    return new F();
};

SKYSALES.Util.convertToLocaleCurrency = function (num)
{
    var json = {
        'num': num
    };
    var localCurrency = new SKYSALES.Class.LocaleCurrency();
    localCurrency.init(json);
    return localCurrency.currency;
};

/*
    Name: 
        Class SkySales
    Param:
        None
    Return: 
        An instance of SkySales
    Functionality:
        This is the SkySales base class that most objects inherit from
    Notes:
        This class provides the ability to show and hide objects based on their container.
    Class Hierarchy:
        SkySales
*/
if (!SKYSALES.Class.SkySales)
{
    SKYSALES.Class.SkySales = function ()
    {   
        var thisSkySales = this;
        
        thisSkySales.containerId = '';
        thisSkySales.container = null;
        
        thisSkySales.init = SKYSALES.Class.SkySales.prototype.init;
        thisSkySales.getById = SKYSALES.Class.SkySales.prototype.getById;
        thisSkySales.setSettingsByObject = SKYSALES.Class.SkySales.prototype.setSettingsByObject;
        thisSkySales.addEvents = SKYSALES.Class.SkySales.prototype.addEvents;
        thisSkySales.setVars = SKYSALES.Class.SkySales.prototype.setVars;
        thisSkySales.hide = SKYSALES.Class.SkySales.prototype.hide;
        thisSkySales.show = SKYSALES.Class.SkySales.prototype.show;
        return thisSkySales;
    };
    SKYSALES.Class.SkySales.prototype.getById = function (id)
    {
        var retVal = null;
        if (id)
        {
            retVal = window.document.getElementById(id);
        }
        if (retVal)
        {
            retVal = $(retVal);
        }
        else
        {
            retVal = $([]);
        }
        return retVal;
    };
    SKYSALES.Class.SkySales.prototype.init = function (json)
    {
        this.setSettingsByObject(json);
        this.setVars();
    };
    SKYSALES.Class.SkySales.prototype.setSettingsByObject = function (json)
    {
        var propName = '';
        for (propName in json)
        {
            if (json.hasOwnProperty(propName))
            {
                if (this[propName] !== undefined)
                {
                    this[propName] = json[propName];
                }
            }
        }
    };
    SKYSALES.Class.SkySales.prototype.addEvents = function () {};
    SKYSALES.Class.SkySales.prototype.setVars = function () 
    {
        this.container = $('#' + this.containerId);
    };
    SKYSALES.Class.SkySales.prototype.hide = function () 
    {
        this.container.hide('slow');
    };
    SKYSALES.Class.SkySales.prototype.show = function () 
    {
        this.container.show('slow');
    };
}

/*
    Name: 
        Class LocalCurrency
    Param:
        num
    Return: 
        An instance of LocalCurrency
    Functionality:
        This class is used by Util.convertToLocaleCurrency(num)
    Notes:
        This class provides the ability to convert a number to the local currency format
    Class Hierarchy:
        LocalCurrency
*/
if (!SKYSALES.Class.LocaleCurrency) 
{
    SKYSALES.Class.LocaleCurrency = function ()
    {
        var parent = new SKYSALES.Class.SkySales();
        var thisLocaleCurrency = SKYSALES.Util.extendObject(parent);
        
        thisLocaleCurrency.num = 0;
        
        var resource = SKYSALES.Util.getResource();
        var currencyCultureInfo = resource.currencyCultureInfo;
        var integerPartNum = 0;
        var integerPartString = '';
        var decimalPartString = '';
        var number = '';
        var positive = true;
        
        thisLocaleCurrency.currency = thisLocaleCurrency.num.toString();

        var getCurrencyPattern = function ()
        {
            var pattern = currencyCultureInfo.positivePattern;
            if (!positive)
            {
                pattern =  currencyCultureInfo.negativePattern;
            }
            return pattern;
        };
        
        var getIntegerPart = function (numVal)
        {
            var groupSizes = currencyCultureInfo.groupSizes || [];
            var groupSeparator = currencyCultureInfo.groupSeparator;
            var groupSizesIndex = 0;
            var index = 0;
            var currentGroupSize = 3;
            if (groupSizesIndex > groupSizes.length)
            {
                currentGroupSize = groupSizes[groupSizesIndex];
            }
            var currentGroupEndIndex = currentGroupSize - 1;
            
            integerPartNum = Math.floor(numVal);
            var localString = integerPartNum.toString();
            var array = localString.split('');
            var reverseArray = array.reverse();
            var reverseArrayOutput = [];            

            var getNextGroupSize = function ()
            {
                var nextGroupSize = 3;
                //Increment group sizes index if necessary
                if (groupSizesIndex <= groupSizes.length - 2)
                {
                    groupSizesIndex += 1;
                    nextGroupSize = groupSizes[groupSizesIndex];
                }
                else
                {
                    nextGroupSize = currentGroupSize;
                }
                currentGroupEndIndex += nextGroupSize;
                return nextGroupSize;
            };

            for (index = 0; index < reverseArray.length; index += 1)
            {
                if (index > currentGroupEndIndex)
                {
                    currentGroupSize = getNextGroupSize();
                    reverseArrayOutput.push(groupSeparator);
                }                
                reverseArrayOutput.push(reverseArray[index]);
            }
            
            array = reverseArrayOutput.reverse();
            var outputString = array.join('');
            return outputString;
        };
        
        var getDecimalPart = function (numVal)
        {
            var decimalPart = numVal - integerPartNum;
            var decimalPartTrimmed = decimalPart.toFixed(currencyCultureInfo.decimalDigits);
            var decimalPartString = decimalPartTrimmed.substring(2);
            return decimalPartString;
        };
        
        var applyPattern = function ()
        {
            var pattern = getCurrencyPattern() || '';
            var replaceNumber = pattern.replace('n', number);
            return replaceNumber;
        };
        
        thisLocaleCurrency.init = function (json)
        {
            this.setSettingsByObject(json);
            positive = this.num >= 0;
            // Make the number positive. The applyPattern will reestablish the sign.
            this.num = Math.abs(this.num);            
            integerPartString = getIntegerPart(this.num);
            decimalPartString = getDecimalPart(this.num);
            number = integerPartString + currencyCultureInfo.decimalSeparator + decimalPartString;    
            thisLocaleCurrency.currency = applyPattern();
        };
        return thisLocaleCurrency;
    };
}

/*
    Name: 
        Class Resource
    Param:
        None
    Return: 
        An instance of Resource
    Functionality:
        Used to hold any common data that multiple controls use such as
        CountryInfo, MacInfo, StationInfo, and BookingInfo
    Notes:
        Right now there is one resource object instance.
        It is accessed in the JavaScript by calling SKYSALES.Util.getResource()
        It is created in the common.xslt file, and populated by resource data
        that is written to JSON.
        The resources that come down to the browser are configured at a view level in the naml file.
        To get a list of stations in JSON you add the node of
        <bind link="StationResource" property="ResourceContainer"/>
        as a child node of the view node.
        
        This class also contains a way to access cookie data. 
        Such as the contact info that is stored in a cookie to populate the contact view.
    Class Hierarchy:
        SkySales -> Resource
*/
SKYSALES.Class.Resource = function ()
{
    var parent = new SKYSALES.Class.SkySales();
    var thisResource = SKYSALES.Util.extendObject(parent);
    
    thisResource.locationInfo = {};
    thisResource.countryInfo = {};
    thisResource.stationInfo = {};
    thisResource.macInfo = {};
    thisResource.marketInfo = {};
    thisResource.macHash = {};
    thisResource.stationHash = {};
    thisResource.marketHash = {};
    thisResource.sourceInfo = {};
    thisResource.clientHash = {};
    thisResource.dateCultureInfo = {};
    thisResource.currencyCultureInfo = {};
    
    /*
        Turns the macInfo into a hash for quick lookups.
        Keying into the macHash with the mac code you will get back 
        an object that contains an array of station codes that the mac code is associated with.
        macHash[macCode] = { "code": "stationCode", "stations": [ "stationCode1", "stationCode2" ] };
    */
    thisResource.populateMacHash = function ()
    {
        var i = 0;
        var macArray = [];
        var macHash = {};
        var mac = null;
        if (thisResource.macInfo && thisResource.macInfo.MacList)
        {
            macArray = thisResource.macInfo.MacList;
            for (i = 0; i < macArray.length; i += 1)
            {
                mac = macArray[i];
                macHash[mac.code] = mac;
            }
        }
        thisResource.macHash = macHash;
    };
    
    /*
        Turns the stationInfo into a hash for quick lookups.
        Keying into the stationHash with the station code you will get back a station object
        stationHash[stationCode] = { "macCode": "", "name":"", "code": "" };
    */
    thisResource.populateStationHash = function ()
    {
        var i = 0;
        var stationArray = [];
        var stationHash = {};
        var station = null;
        if (thisResource.stationInfo && thisResource.stationInfo.StationList)
        {
            stationArray = thisResource.stationInfo.StationList;
            for (i = 0; i < stationArray.length; i += 1)
            {
                station = stationArray[i];
                stationHash[station.code] = station;
            }
        }
        thisResource.stationHash = stationHash;
    };
    
    /*
        Turns the marketInfo into a hash for quick lookups.
        Keying into the marketHash with the orgin station code you will get back an array of objects.
        Each object contains a destination station code that can be mapped to a station object using the stationHash.
        marketHash[originStationCode] = [ { "code": "destinationStationCode1", "name": "destinationStationCode2" } ]
    */
    thisResource.populateMarketHash = function ()
    {
        var i = 0;
        var marketHash = {};
        var marketArray = [];
        var market = {};
        
        var destinationIndex = 0;
        var destinationArray = [];
        var destinationCode = '';
        var destination = {};
        var station = {};
        
        if (thisResource.marketInfo && thisResource.marketInfo.MarketList)
        {
            marketArray = thisResource.marketInfo.MarketList;
            for (i = 0; i < marketArray.length; i += 1)
            {
                market = marketArray[i];
                destinationArray = market.Value;
                if (destinationArray)
                {
                    marketHash[market.Key] = destinationArray;
                    for (destinationIndex = 0; destinationIndex < destinationArray.length; destinationIndex += 1)
                    {
                        destination = destinationArray[destinationIndex];
                        destinationCode = destination.code;
                        destination.name = '';
                        station = thisResource.stationHash[destinationCode];
                        if (station)
                        {
                            destination.name = station.name;
                        }
                    }
                }
            }
            thisResource.marketHash = marketHash;
        }
    };
    
    /*
        The clientHash is data that has been stored in a cookie
    */
    thisResource.populateClientHash = function ()
    {
        var cookie = window.document.cookie;
        var nameValueArray = [];
        var i = 0;
        var singleNameValue = '';
        var key = '';
        var value = '';
        var eqIndex = -1;
        if (cookie)
        {
            nameValueArray = document.cookie.split('; ');
            for (i = 0; i < nameValueArray.length; i += 1)
            {
                singleNameValue = nameValueArray[i];
                eqIndex = singleNameValue.indexOf('=');
                if (eqIndex > -1)
                {
                    key = singleNameValue.substring(0, eqIndex);
                    value = singleNameValue.substring(eqIndex + 1, singleNameValue.length);
                    if (key)
                    {
                        value = SKYSALES.Util.decodeUriComponent(value);
                        thisResource.clientHash[key] = value;
                    }
                }
            }
        }
    };
    
    /*
        Populate the object instance.
        This is accomplished by matching the name of the public menber 
        with the name of the key in the key: value pair of the JSON object that is passed in.
        It then turns the data into hash lists for quick lookups.
    */
    thisResource.setSettingsByObject = function (jsonObject)
    {
        parent.setSettingsByObject.call(this, jsonObject);
        thisResource.populateStationHash();
        thisResource.populateMacHash();
        thisResource.populateMarketHash();
        thisResource.populateClientHash();
    };
    return thisResource;
};
