/* stub out console calls for ie */
if (!window.console || !console.firebug)
{
    var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
    "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];

    window.console = {};
    for (var i = 0; i < names.length; ++i){
        window.console[names[i]] = function() {}
    }
}


// start: Add a class name to the body as a global flag that the user has javascript.
document.observe('dom:loaded', function()
{
	var body = $(document.body);
	body.addClassName('js-enabled');
});
// end: Add a class name to the body


// start FlyoutNav
var FlyoutNav = Class.create (
{
    initialize: function(links, flyouts)
    {
        this.links = links;
        this.flyouts = flyouts;
        this.length = this.links.size();
        this.flyouts.invoke('hide'); // display block via css then hide via js
        this.flyouts.invoke('addClassName','flyout'); // add a class that JS can use without dependencies on the markup
        this.timeout;

        var boundLinkOver = this.__LinkOver.bindAsEventListener(this);
        var boundLinkOut = this.__LinkOut.bindAsEventListener(this);
        var boundFlyoutOver = this.__FlyoutOver.bindAsEventListener(this);
        var boundFlyoutOut = this.__FlyoutOut.bindAsEventListener(this);
        this.links.invoke('observe', 'mouseover', boundLinkOver).invoke('observe', 'mouseout', boundLinkOut);
        this.flyouts.invoke('observe', 'mouseover', boundFlyoutOver).invoke('observe', 'mouseout', boundFlyoutOut);
    },

    __LinkOver: function(e)
    {
        var element = e.element();
        for (var i=0; i<this.length; i++)
        {
	        if (this.links[i] == element)
	        {
				clearTimeout(this.timeout);
				if (this.flyouts[i].status != 'down')
				{
					this.doSlideDown(i);
					break;
				}
	        }
        }
    },

    __LinkOut: function(e)
    {
        var element = e.element();
        for (var i=0; i<this.length; i++)
        {
	        if (this.links[i] == element)
	        {
				if (this.flyouts[i].status == 'down')
				{
					this.timeout = setTimeout(function()
					{
						this.doSlideUp(i);
						}.bind(this), 400);
					break;
				}
	        }
        }
    },

    __FlyoutOver: function(e)
    {
        var element = e.element();
        if(!element.hasClassName('flyout'))
        {
			element = element.up('.flyout');
        }
        for (var i=0; i<this.length; i++)
        {
	        if (this.flyouts[i] == element)
	        {
				if (this.flyouts[i].status == 'down')
				{
					clearTimeout(this.timeout);
					break;
				}
	        }
        }
    },

    __FlyoutOut: function(e)
    {
        var element = e.element();
        if(!element.hasClassName('flyout'))
        {
			element = element.up('.flyout');
        }
        for (var i=0; i<this.length; i++)
        {
	        if (this.flyouts[i] == element)
	        {
				if (this.flyouts[i].status == 'down')
				{
					this.timeout = setTimeout(function()
					{
						this.doSlideUp(i);
						}.bind(this), 400);
					break;
				}
	        }
        }
    },

    doSlideDown: function(index)
    {
        for (var i=0; i<this.length; i++)
        {
	        if (i == index)
	        {
				this.flyouts[i].slideDown({ duration: 0.3, fps: 100, transition: Effect.Transitions.easeOutExpo });
				this.flyouts[i].status = 'down';
			} else {
				if (this.flyouts[i].status == 'down')
				{
					this.doSlideUp(i);
				}				
			}
        }
    },

    doSlideUp: function(index)
    {
        for (var i=0; i<this.length; i++)
        {
	        if (i == index)
	        {
				this.flyouts[i].slideUp({ duration: 0.2, fps: 100, transition: Effect.Transitions.easeInExpo });
				this.flyouts[i].status = 'up';
	        }
        }
    }
});
// end FlyoutNav


// start HeightAdjust
var HeightAdjust = Class.create (
{
    initialize: function(links, parent)
    {
        this.links = links;
        this.parent = parent || false;
        //console.log(this.parent.identify());
        this.length = this.links.size();
        this.height = 0; // start with 0 height baseline
        this.tpad = parseInt(this.links[0].getStyle('padding-top')); // get first elements padding-top in pixels as a number
        this.bpad = parseInt(this.links[0].getStyle('padding-bottom')); // get first elements padding-bottom in pixels as a number

        for (var i=0; i<this.length; i++)
        {
			// loop thru and update this.height with tallest height
	        if (this.links[i].getHeight()> this.height) {this.height = this.links[i].getHeight()}
        }
        
        this.height = this.height;
        this.adjHeight = this.height - (this.tpad + this.bpad); // remove vertical padding from height calculation

        for (var i=0; i<this.length; i++)
        {
			// loop thru and update this.height with tallest height
	        this.links[i].style.height = this.adjHeight + 'px';
        }
        if (this.parent)
        {
			this.parent.style.height = this.height + 'px';
        }
        
    }
});
// end HeightAdjust


// start PopupWindow
var PopupWindow = Class.create (
{
    initialize: function(link, width, height, xtras)
    {
        this.popName = 'popup';
        this.link = link;
        this.url = this.link.href;
        this.altW = 640;
        this.altH = 480;
        this.altX = 'location=no,menubar=no,statusbar=no,toolbar=no,scrollbars=no,resizable=yes';
        this.popupW = width || this.altW;
        this.popupH = height || this.altH;
        this.popupX = xtras || this.altX;
        this.availH = screen.availHeight;
        this.availW = screen.availWidth;
        this.topPos = (this.availH - this.popupH)/2;
        this.leftPos = (this.availW - this.popupW)/2;
        this.features = 'width=' + this.popupW + ',height=' + this.popupH + ',' + this.popupX + ',top=' + this.topPos + ',left=' + this.leftPos;
        this.link.observe('click', this.__Click.bindAsEventListener(this));
    },
    __Click: function(e)
    {
        e.stop();
        var win = window.open(this.url, this.popName, this.features);
        win.focus();
    }
});
// end PopupWindow


// start ClosePopup
var ClosePopup = Class.create (
{
    initialize: function(link)
    {
        this.link = link;
        this.link.observe('click', this.__Click.bindAsEventListener(this));
    },
    __Click: function(e)
    {
        e.stop();
        window.close();
    }

});
// end ClosePopup


// start ContentSwitcher
var ContentSwitcher = Class.create (
{
    initialize: function(links, items, options)
    {
        this.links = links;
        this.items = items;
        this.length = this.links.size();
		// set options
		this.options = Object.extend(
		{
			rotate: false // true || false
		}, options || {});
        this.hash = window.location.hash.replace('#','') || false;
        this.num = 0;

        // show the first, check url hash to override
        if (this.hash)
        {
            for (var i=0; i<this.length; i++)
            {
	            if (this.items[i].id == this.hash)
	            {
	                this.num = i;
	            }
            }
            this.doShowHide(this.num);
        }
        else
        {
            this.doShowHide(0); // show the first, hide the rest
        }

		var boundLinkClick = this.__Click.bindAsEventListener(this);
        this.links.invoke('observe', 'click', boundLinkClick);

        // show different item every 3 seconds
        if (this.options.rotate)
        {
            if (this.hash){return;} // don't rotate if url hash
            this.interval = setInterval(function()
            {
                this.doRotate();
            }.bind(this), 3000);
        }
    },

    __Click: function(e)
    {
        e.stop();
        var element = e.element();
        clearInterval(this.interval); // clear timer once link is clicked
        for (var i=0; i<this.length; i++)
        {
	        if (this.links[i] == element)
	        {
		        this.doShowHide(i);
		        break;
	        }
        }
    },

    // Rotate thru items
    doRotate: function()
    {
        this.num++;
        if (this.num == this.length)
        {
            this.num = 0;
        }
        this.doShowHide(this.num);
    },

    doShowHide: function(index)
    {
        for (var i=0; i<this.length; i++)
        {
	        if (i == index)
	        {
		        this.links[i].up().addClassName('in');
		        //this.items[i].show();
		        this.items[i].appear({ duration: 0.3 });
	        } else {
	            this.links[i].up().removeClassName('in');
	            this.items[i].hide();
	        }
        }
    }
});
// end ContentSwitcher


// start PrintPage
var PrintPage = Class.create (
{
    initialize: function(link)
    {
        this.link = link;
        this.link.observe('click', this.__Click.bindAsEventListener(this));
    },
    __Click: function(e)
    {
        e.stop();
        this.doPrint();
    },
    doPrint: function()
    {
        window.print();
    }
});
// end PrintPage

// start Cloak (used by BoxBox and other widgets)
Element.addMethods({
	/**
	 *  Element#cloak(@element) -> element
	 **/
	cloak: function(element) {
		element.style.visibility = "hidden";
	},
	/**
	 *  Element#reveal(element) -> element
	 **/
	reveal: function(element) {
		element.style.visibility = "visible";
	},
	/**
	 *  Element#cloaked(@element) -> Boolean
	 **/
	cloaked: function(element) {
		return element.style.visibility == "hidden";
	}
});
// end Cloak

// start Enable/Disable link (used by Photochooser in scroller)
Element.addMethods('A', {
	/**
	 *  Anchor#enable(@element) -> element
	 **/
	enable: function(element) {
		return element.removeClassName('disabled').setOpacity(1);
	},
	/**
	 *  Anchor#reveal(element) -> element
	 **/
	disable: function(element) {
		return element.addClassName('disabled').setOpacity(0.25);
	},
	/**
	 *  Anchor#cloaked(@element) -> Boolean
	 **/
	disabled: function(element) {
		return !!element.hasClassName('disabled');
	}
});
			
// end Enable/Disable link



// start onEnterClick
/*
 * EnterClick listens on a containing element for the enter/return key being pressed.
 * When the enter key is pressed within a child input element that will submit the form, 
 * it will prevent the default form submittal and fire the click event of a designated button.
 *  
 * Usage:
 * $('fieldset_forgot').onEnterClick($('btn_Forgot'));
 */
var EnterClick = Class.create({
	relevantTypes: $w('text password checkbox radio'),
	initialize: function(element, button){
		this.element = $(element).addClassName("enterclick");
		this.button = $(button);
		this.element.observe('keypress', this.__keyPress.bindAsEventListener(this));
	},
	__keyPress: function(e){
		var elSrc = e.element();
		if((e.keyCode == Event.KEY_RETURN) 
			&& (elSrc.nodeName == 'INPUT') 
			&& (this.relevantTypes.include(elSrc.type))) {
				// prevent default form submittal
				e.stop(); 
				// fire associated button's click event
				//console.log('firing ' + this.button.id);
				this.button.click();
		}
	}
});
// Extend Element with enterclick
Element.addMethods({
	onEnterClick: function(element, button) {
		new EnterClick(element, button);
		return element;
	}
});
// end onEnterClick
// start LabelInput
/**
* LabelInput uses the title attribute of a label element to show 
* guiding or hint text into a text input through the label's title attribute.
* e.g. <label id="lblDOB" for="txtDOB" title="mm/dd/yyyy"/>
* Usage examples:
* $('lblDOB').labelInput();
* $('lblDOB').labelInput({hintText: 'first, last', hintClassName: 'myclass'});
* $$('label').invoke('labelInput');
* 
**/
var LabelInput = Class.create({
	forms: [], // references to containing forms
	initialize: function(elLabel, options){
		var elTxtInput = $(elLabel.readAttribute('for'));
		if(!Object.isElement(elTxtInput)){return;}
		this.options = Object.extend({
			hintClassName: 'hint', 						// class to apply to input when it's using the text set.
			hintText: elLabel.readAttribute('title')	// get the text from the options, or the label's title attribute
		}, options || {});
	
		// add the text to text input as an expando property.
		elTxtInput._hintText = this.options.hintText;
		
		elTxtInput.observe('focus', this.__txtInputFocus.bindAsEventListener(this));
		elTxtInput.observe('blur', this.__txtInputBlur.bindAsEventListener(this));
		
		//set the initial hint text, and adjust className
		if(elTxtInput.value == ''){
			elTxtInput.value = elTxtInput._hintText;
		}
		if(elTxtInput.value == elTxtInput._hintText){
			elTxtInput.addClassName(this.options.hintClassName);
		} else{
			elTxtInput.removeClassName(this.options.hintClassName);
		}
		
		// clear out label text on form submit
		var elForm = elLabel.up('form');
		if(elForm && !this.forms.member(elForm)){
			elForm.observe('submit', this.__frmSubmit.bindAsEventListener(this));
			this.forms.push(elForm);
		}
	},
	
	// sets the label text
	__txtInputBlur: function(e){
		var elTxtInput = e.element();
		if (elTxtInput.value == '' && elTxtInput._hintText) {
			// add label text
			elTxtInput.value = elTxtInput._hintText;
			elTxtInput.addClassName(this.options.hintClassName);
		}
		else{
			elTxtInput.removeClassName(this.options.hintClassName);
		}
	},
	
	// removes the label text
	__txtInputFocus: function(e){
		var elTxtInput = e.element();
		if (elTxtInput.value == elTxtInput._hintText) {
			elTxtInput.value = '';
			elTxtInput.removeClassName(this.options.hintClassName);
		}
	},
	
	// makes sure text input values are not set to the label text upon form submission
	__frmSubmit: function(e){
		e.element().getElements().each(function(txtInput){
			if(txtInput._hintText && (txtInput.value == txtInput._hintText)){
				txtInput.clear();
			}
		});
	}
});

// Extend the LABEL tag with LabelInput
Element.addMethods('LABEL', {
	labelInput: function(element, options) {
		new LabelInput(element, options);
		return element;
	}
});
// end LabelInput
// start CharCounter
// Updates a character counter element with the length of a text input or textarea
// Usage sample: charCounter = new CharCounter($('txaComment'), $$('p#charcount span').first());
var CharCounter = Class.create({
	initialize: function(elText, elTarget, maxLength){
		this.elText = $(elText);
		this.elTarget = $(elTarget);
		if(!(Object.isElement(this.elText)) && !(Object.isElement(this.elTarget))){
			return;
		} else {
			this.maxLength = (Object.isUndefined(maxLength)) ? parseInt(this.elText.readAttribute('maxlength')) : maxLength ;
			this.elText.observe('keyup', this.__textChange.bindAsEventListener(this));
			this.updateCounter();
		}
	},
	__textChange: function(e){
		if(this.getCount() > this.maxLength){
			this.elText.value = this.elText.value.substring(0, this.maxLength);
		}
		this.updateCounter();
	},
	
	updateCounter: function(){
		var count = this.getCount(), remaining = this.maxLength - count;
		this.elTarget.update(remaining);
	},
	
	getCount: function(){
		return this.elText.value.length;
	}
});

// end CharCounter


// start Spinnster
/*
	Spinnster is an ajax responder that covers a given target element during the xhr transmission.
    Provide a target element id in the Ajax.Request's option, and the target will be covered 
    with the spinning gif during the time between xhr request and response. Effects are baked in with
    minimal configuration available.
    
    Sample Usage:
		new Ajax.Request('response.html', {
			spinnsterTargetId: 'target',
			method: 'post',
			onSuccess: function(transport){...}
		});      
*/
var Spinnster = (function(options){
	var config = Object.extend({
			xhrOptionKey: 	'spinnsterTargetId',
			idSuffix:		'_spinnster',
			fxDuration:		0.25,
			fxMaxOpacity:	0.5
		}, options || {});
		
	var self = {
		onCreate: function(transport){
			/* forza specific, since pop.ajax doesn't pass anonymous options through request */
			if(config.xhrOptionKey in transport.options.parameters){
				//console.log('found one', transport.options.parameters[config.xhrOptionKey]);
				transport.options[config.xhrOptionKey] = transport.options.parameters[config.xhrOptionKey];
			}
			
			if(config.xhrOptionKey in transport.options){
				var targetIds = transport.options[config.xhrOptionKey];
				if(Object.isString(targetIds)) targetIds = [targetIds];
				targetIds.each(function(targetId){
					var target = $(targetId);
					var spinnsterId = targetId + config.idSuffix, elSpinnster = $(spinnsterId);
					if(!(Object.isElement(elSpinnster))) {
						elSpinnster = new Element('div', {id: spinnsterId, 'class':'spinnster', title: 'Loading...'});
						elSpinnster.setOpacity(0);
						target.insert({before: elSpinnster});
						// IE 6/7 workaround (needs dimension and filter:alpha(opacity=0);).
						elSpinnster.setStyle('height:#{height}px;width: #{width}px;'.interpolate(target.getDimensions()));
					} else{
						//ie 8 workaround: gets positioning wrong after first clonePosition, moving element to body.
						$(document.body).insert({bottom: elSpinnster});
						
						Effect.Queues.get(spinnsterId).each(function(effect) {effect.cancel(); });					
					}

					elSpinnster.clonePosition(target); 
					elSpinnster.appear({to: config.fxMaxOpacity, duration: config.fxDuration, queue: { position: 'front', scope: spinnsterId, limit:2 }});
				});
			}
			
		}, 

		onComplete: function(transport){
			if(config.xhrOptionKey in transport.options){
				var targetIds = transport.options[config.xhrOptionKey];
				if(Object.isString(targetIds)) targetIds = [targetIds];
				targetIds.each(function(targetId){
					var spinnsterId = targetId + config.idSuffix;
					$(spinnsterId).fade({from: config.fxMaxOpacity, duration: config.fxDuration, queue: { position: 'end', scope: spinnsterId, limit:2 } });				
				});
			}
		},

		onFailure: function(transport){
			if(config.xhrOptionKey in transport.options){
				var targetIds = transport.options[config.xhrOptionKey];
				if(Object.isString(targetIds)) targetIds = [targetIds];
				targetIds.each(function(targetId){
					var spinnsterId = targetId + config.idSuffix;
					$(spinnsterId).hide();		
				});				
			}

		},
		
		OPTION_KEY: config.xhrOptionKey,
		
		ID_SUFFIX: config.idSuffix
	};
	return self;
})();

Ajax.Responders.register(Spinnster);
// end Spinnster


// Start shared SilverLight functions
function onSilverlightError(sender, args) {
    var appSource = "";
    if (sender != null && sender != 0) {
        appSource = sender.getHost().Source;
    }

    var errorType = args.ErrorType;
    var iErrorCode = args.ErrorCode;

    if (errorType == "ImageError" || errorType == "MediaError") {
        return;
    }

    var errMsg = "Unhandled Error in Silverlight Application " + appSource + "\n";

    errMsg += "Code: " + iErrorCode + "    \n";
    errMsg += "Category: " + errorType + "       \n";
    errMsg += "Message: " + args.ErrorMessage + "     \n";

    if (errorType == "ParserError") {
        errMsg += "File: " + args.xamlFile + "     \n";
        errMsg += "Line: " + args.lineNumber + "     \n";
        errMsg += "Position: " + args.charPosition + "     \n";
    }
    else if (errorType == "RuntimeError") {
        if (args.lineNumber != 0) {
            errMsg += "Line: " + args.lineNumber + "     \n";
            errMsg += "Position: " + args.charPosition + "     \n";
        }
        errMsg += "MethodName: " + args.methodName + "     \n";
    }

    throw new Error(errMsg);
};
// End shared SilverLight functions        