// Variable content SCROLLER items can be removed
var Scroller = Class.create({
	initialize : function(options){
		this.options = Object.extend({
			slideId : 'courseScroll',
			prevId : 'scrollLeft',
			nextId : 'scrollRight',
			incrementCount : 6,
			itemSelector : 'div.course:not(div.empty):not(div.inactive)',
			speed : .8, 
			endPad : 0
		}, options || {});
		this.slider = $(this.options.slideId);
		this.slider.select('a.close').each(function(el){el.observe('click', this.removeItem.bind(this))}.bind(this));
		this.nextBtn = $(this.options.nextId).observe('click', this.next.bind(this));
		this.prevBtn = $(this.options.prevId).observe('click', this.prev.bind(this));
		this.current = 1;
		this.effect = null;
		this.setup();
		this.syncButtons();
	},
	
	setup : function(){
		this.items = this.slider.select(this.options.itemSelector);
		this.itemwidth = this.items.first().getWidth();
		this.itemcount = this.items.size();
		this.incrementCount = this.options.incrementCount * this.itemwidth;
		this.sets = Math.ceil(this.itemcount/this.options.incrementCount);
		if (this.current>this.sets) this.current = this.sets;
	},
	
	prev : function(e){
		e.stop();
		if (this.effect) return;
		if (this.atStart()) return;
		this.effect = new Effect.Move(this.slider, {x:this.nextIncrement(), mode : 'relative', duration : this.options.speed, queue:'end', afterFinish : function(){this.effect = null;this.syncButtons()}.bind(this)});
		this.current--;
	}, 
	
	next : function(e){
		if (e) e.stop();
		if (this.effect) return;
		if (this.atEnd()) return;
		this.current++;
		this.effect = new Effect.Move(this.slider, {x:-this.nextIncrement(), mode : 'relative', duration : this.options.speed, queue:'end', afterFinish : function(){this.effect = null;this.syncButtons()}.bind(this)});
	},
	
	removeItem : function(ev){
		ev.stop();
		ev.element().fire('hoverdelay:stop');
		var item =  ev.element().up(this.options.itemSelector);
		item.removeClassName("active");
		item.fade({to: .01, duration:1, afterFinish: function(){
				var shift = (this.atEnd() && this.current>1);
				if (shift){
					var tomove = this.itemwidth;
					if (this.atEnd()&&this.itemcount-1==this.options.incrementCount){tomove+= this.options.endPad;}
					new Effect.Move(this.slider, {x:tomove, mode : 'relative', duration : .5});
				}
				item.setStyle({overflow:'hidden'})
				.morph({width: Prototype.Browser.IE?'0em':'0px'}, {duration:.5, afterFinish: function(){
					//item.remove();
					this.beforeRemove(item);
					item.addClassName('inactive').setStyle({width:''}).setOpacity(1);
					this.setup();
					this.afterRemove(item);
					this.syncButtons();
				}.bind(this)});
			}.bind(this)})
	},
	
	nextIncrement : function (){
		var inc = ((this.current*this.options.incrementCount) > this.itemcount)? 
			((this.itemcount%this.options.incrementCount)* this.itemwidth) : 
			  this.itemwidth*this.options.incrementCount;
		return inc+( this.atEnd() ? this.options.endPad : 0);
	},
	atEnd : function(){
		return this.current==this.sets;
	},
	atStart : function(){
		return this.current==1;
	},
	syncButtons : function(){
		if (this.atStart()) this.prevBtn.addClassName("disabled");else this.prevBtn.removeClassName("disabled");
		if (this.atEnd()) this.nextBtn.addClassName("disabled"); else this.nextBtn.removeClassName("disabled");
	},
	reset : function(){
		this.current=1;
		this.slider.style.left = 0;
		this.setup();
		this.afterRemove();
		this.syncButtons();
	},
	afterRemove : function (){},beforeRemove : function(){}
});

// GENERIC HOVER DELAY TRIGGER
var HoverDelay = Class.create({
	initialize : function(trigger, options){
		this.options = Object.extend({enterCb : function(){},	leaveCb : function(){},	delay : 0.5}, options || {});
		this.trigger = $(trigger);
		this.timeout = null; this.active = false;
		this.setup();
	},
	setup : function(){
		var eEvt = this.open.bindAsEventListener(this);
		var lEvt = this.close.bindAsEventListener(this);
		this.trigger.observe('mouseenter', eEvt);
		this.trigger.observe('mouseleave', lEvt);
		this.trigger.observe('hoverdelay:stop', function(){
			this.trigger.stopObserving('mouseenter', eEvt);
			this.trigger.stopObserving('mouseleave', lEvt);
		}.bind(this));
		document.observe('pop:active', function(){this.inactive=true;}.bind(this));
		document.observe('pop:inactive', function(){this.inactive=false;}.bind(this));
	}, 
	open : function(event){
		if (this.inactive) return;
		this.timeout = (function(){
			this.options.enterCb();
			this.active = true;
		}).bind(this).delay(this.options.delay);
	},
	close : function(){
		if (this.inactive) return;
		if (this.timeout) {
			window.clearTimeout(this.timeout);
			this.timeout = null;
		}
		if (this.active){
			this.options.leaveCb();
			this.active = false;
		}
	}
});



var BasicHover = Class.create({
	initialize : function(el, className){
		el.observe('mouseenter', el.addClassName.bind(el, className));
		el.observe('mouseleave', el.removeClassName.bind(el, className));
	}
});

var PopUp = Class.create({
	initialize : function(linkId, popId, opts){
		this.options = Object.extend({closeSelector : '.close', modal: false, openEffect : Effect.Appear, closeEffect : Effect.Fade, effectOpts : {duration: .4}}, opts || {});
		this.pop = $(popId).setStyle({display:'none'});
		this.link = $(linkId);
		this.setup();
		this.pop.observe('pop:close', this.close.bind(this));
	},
	setup : function(){
		this.link.observe('click', this.open.bind(this));
		this.pop.select(this.options.closeSelector).each(function(el){
			el.observe('click', this.close.bind(this));
		}.bind(this));
	},
	open : function(ev){
		if (ev) ev.stop();
		new this.options.openEffect(this.pop, this.options.effectOpts);
		if (this.options.modal)document.fire('pop:active');
	},
	close : function(ev){
		if (ev) ev.stop();
		new this.options.closeEffect(this.pop, this.options.effectOpts);
		if (this.options.modal) document.fire('pop:inactive');
	}
});

var ToolTip = Class.create(PopUp, {
	setup : function(){
		new HoverDelay(this.link, {
			enterCb : this.open.bind(this),
			leaveCb : this.close.bind(this)
		});
	}
});


var PositionMixin = {
	initialize : function($super, linkId, popId, opts){
		opts = Object.extend({anchor : linkId, yOffset:0, xOffset:0, parent:$$('body').first(), enableCache:false}, opts || {});
		$super(linkId, popId, opts);
		this.anchor = $(this.options.anchor);
        this.pop.makePositioned();
		this.leftA = this.pop.select('.arrowLeft').first();
		this.rightA = this.pop.select('.arrowRight').first();
	},
	open : function($super, ev){
		if (this.options.popParent){
			(this.anchor.up(this.options.popParent) || $$(this.options.popParent).first())
				.insert(this.pop);
		}
		
		if (!this.options.enableCache || !this.position){
			this.calculatePosition(this.options.forceRender);
		}
		this.pop.style.top = this.position.top+'px'; this.pop.style.left = this.position.left+'px';
		if (this.side=="right"){
			this.leftA.addClassName('active').setStyle({visibility:'visible'}); this.rightA.removeClassName('active').setStyle({visibility:'hidden'});
		}else{
			this.rightA.addClassName('active').setStyle({visibility:'visible'}); this.leftA.removeClassName('active').setStyle({visibility:'hidden'});
		}
		$super(ev);
	},
	calculatePosition : function(force){
		var pos = this.anchor.cumulativeOffset();
		this.side = force || (pos.left<this.options.parent.cumulativeOffset().left+(this.options.parent.getWidth()/2)) ? 'right':'left';
		var position = this.anchor.positionedOffset();
		var x = position.left;
		var y = position.top;
		y+= this.options.yOffset;
		if (this.side == 'right'){
			x+= this.options.xOffset;
		}else{
			x-=this.pop.getWidth();
			//x-=this.anchor.getWidth();
			//x-=this.options.xOffset;
		}
		this.position = {left:x,top:y};
	}
};

var PositionedToolTip = Class.create(ToolTip, PositionMixin);
var PositionedPopup = Class.create(PopUp, PositionMixin);

var ZipAutocompleter = Class.create(Ajax.Autocompleter, {
	getUpdatedChoices : function($super){
		if (/[a-zA-Z]/.test(this.element.value))
			$super();
		else
			this.hide();
	}
});

var LocationWidget = Class.create({
	initialize : function(id){
		this.container = $(id);
		this.field = $('locationField');
		this.setup();
	},
	setup : function(){
		this.form = this.container.select('form').first();
		this.container.select('a.submit').each(function(el){el.observe('click', this.submit.bind(this));}.bind(this));
		this.completer = new ZipAutocompleter(this.field, 'queryMatches', 'ajax/locationsearch.txt', {minChars:2, afterUpdateElement:this.select.bind(this)});
		this.focus = this._focus.bindAsEventListener(this);
		this.field.observe('focus', this.focus);
		this.container.select(".toggleMode").invoke('observe', 'click', this.toggle.bind(this));
	},
	_focus : function(){
		this.field.value='';
		this.field.stopObserving('focus', this.focus);
	},
	select : function(field, li){
	//id/zip extraction?	
	},
	submit : function(e){
		e.stop();
		
		this.form.request({onComplete:function(r){
			if (r.responseText == "SUCCESS"){
				document.location = document.location;
			}else{
				var styleframe = this.container.down('.field').addClassName('error');
				this.container.down('.systemMsg').update(r.responseText).appear({duration:1, afterFinish:function(e){
					(function(){
						e.element.fade();
						styleframe.removeClassName('error');
					}).delay(3);
				}.bind(this)});
				
			}
		}.bind(this)});
	},
	toggle : function(ev){
		ev.stop();
		this.container.select('.content').invoke('toggle');
	}
});

var DropDown = Class.create({
	initialize : function(select, opts){
		this.orig = $(select);
		this.options = [];
		this.opts = Object.extend({
			onchange : function(){}
		}, opts || {});
		this.setup();
	},
	setup : function(){
		this.styled = new Element('ul',{'class':'menuDrop'});
		this.hidden = new Element('input', {'type':'hidden','name':this.orig.readAttribute('name'), 'id':this.orig.readAttribute('id')});

		this.selected = new Element('li',{'class' : 'first'})
			.insert('<a href="#">&nbsp;</a>')
			.observe('click', this.open.bind(this))
			.insert(this.hidden);
			
		this.selectable = new Element('ul');
		this.selects = new Element('li',{'class':'selects'})
			.insert(this.selectable);
		
		this.styled.insert(this.selected)
			.insert(this.selects);
					
		this.onchange = this.opts.onchange;
		this.form = this.orig.form;

		this.orig.select('option').each(function(op, i){
			var a = new Element('a',{href:'#'}).update(op.innerHTML);
			var li = new Element('li');
			li._val = op.readAttribute('value');
			li.appendChild(a);
			this.selectable.appendChild(li);
			this.options.push(li);
			li.observe('click', this.select.bind(this, li));
		}.bind(this));
		this.select(this.options[this.orig.selectedIndex], true, true);
		this.orig.replace(this.styled);
		this.bfx = this.close.bindAsEventListener(this);
	},
	open : function(ev){
		var self = this;
		this.selectedItem.hide().addClassName('hidden');
		this.selects.appear({duration:.4});
		this.selected.addClassName("active");
		this.selects.down('li:not(li.hidden)').addClassName("firstItem");
		document.observe('click', this.bfx);
		ev.stop();
	},
	close : function(){
		this.selects.hide();
		this.selected.removeClassName("active");
		this.selects.select('li').invoke('removeClassName', 'firstItem');
		document.stopObserving('click', this.bfx);
	},
	select : function(item, ev, skipchange){
		if (ev.stop) ev.stop();
		this.selected.select('a').first().update(item.select('a')[0].innerHTML);
		if (this.selectedItem) this.selectedItem.removeClassName("hidden");
		this.selectedItem = item;
		this.hidden.writeAttribute('value', item._val);
		this.close();
		this.options.invoke('show');
		if (!skipchange && this.onchange){
			this.onchange.apply(this);
		}
	}
});

var HeightNormalizer = Class.create({
	initialize : function(selector){
		var max=0;
		$$(selector)
			.each(function(el){
				max = Math.max(max, el.getHeight());
			})
			.invoke('setStyle', {height:max+'px'});
	}
});


//
// Based on Easing Equations v2.0
// (c) 2003 Robert Penner, all rights reserved. 
// OPEN-SOURCE TERMS OF USE: http://www.robertpenner.com/easing_terms_of_use.html
// Adapted for Scriptaculous by Ken Snyder (kendsnyder.com) June 2006
//
var elastic = function(pos) {
    return -1*Math.pow(4,-8*pos)*Math.sin((pos*6-1)*(2*Math.PI)/2)+1;
  }
var bouncePast = function(pos){
	if(pos<(1/2.75)) { 
      return (7.5625*pos*pos);
    } else if(pos<(2/2.75)) {
      return 2-(7.5625*(pos-=(1.5/2.75))*pos+.75);
    } else if(pos<(2.5/2.75)) {
      return 2-(7.5625*(pos-=(2.25/2.75))*pos+.9375);
    } else {
      return 2-(7.5625*(pos-=(2.625/2.75))*pos+.984375);
    }
}

var ImagePreloader = Class.create({
	initialize : function(paths){
		var b = $$('body').first();
		paths.each(function(p){
			b.insert(new Element('img')
				.writeAttribute('src', p)
				.setStyle({display:'none'}));
		});
	}
});

Prototype.Browser.isIE6 = function(){
	function getInternetExplorerVersion()
	{
		var rv = -1; // Return value assumes failure.
		if (navigator.appName == 'Microsoft Internet Explorer')
		{
			var ua = navigator.userAgent;
			var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
			if (re.exec(ua) != null)
				rv = parseFloat( RegExp.$1 );
		}
		return rv;
	}
	return Prototype.Browser.IE && (getInternetExplorerVersion() <= 6);
}

var DelayedHover = Class.create(HoverDelay, {
	initialize : function($super, trigger, active, options){
	var ie = Prototype.Browser.isIE6();

	options = Object.extend({
		enterCb : function(){
			this.trigger.addClassName(active);
			//Hide select box for IE6
			//if (ie) $$('.testBox').first().hide();
			if (ie) this.trigger.setStyle({'position':'static'});			
		}.bind(this),
		leaveCb : function(){
			this.trigger.removeClassName(active);
			//Display select box for IE6
			//if (ie) $$('.testBox').first().show();
			if (ie) this.trigger.setStyle({'position':''});
		}.bind(this)
	}, options || {});
	$super(trigger, options);
}
});

/************ window dimensions *************/
//Prototype-based javascript window dimensions
//http://textsnippets.com/posts/show/835 
Position.GetWindowSize = function(w) {
      w = w ? w : window;
      var width = w.innerWidth || (w.document.documentElement.clientWidth || w.document.body.clientWidth);
      var height = w.innerHeight || (w.document.documentElement.clientHeight || w.document.body.clientHeight);
      return [width, height]
}

/************ center DOM element *************/
//Center a DOM element, prototype based
//http://textsnippets.com/posts/show/836
Position.Center = function(element, parent) {
	var w, h, pw, ph;
	var d = Element.getDimensions(element);
	w = d.width;
	h = d.height;
	Position.prepare();
	if (!parent) {
			var ws = Position.GetWindowSize();
			pw = ws[0];
			ph = ws[1];
	} else {
			pw = parent.offsetWidth;
			ph = parent.offsetHeight;
	}
	element.style.top = (ph/2) - (h/2) +  Position.deltaY + "px";
	element.style.left = (pw/2) - (w/2) +  Position.deltaX + "px";
	element.style.position='absolute';
}

document.observe('dom:loaded', function() {
	//if (Prototype.Browser.IE){document.execCommand("BackgroundImageCache", false, true);}	
	
	if($('widgetHelp'))
		new ToolTip('widgetHelp', 'overlayHelp', {delay:0.1});
	
	var locationPop = $('setLocation');
	if (locationPop!= null){
		$$('.enterZipSidebar').each(function(el){
			new PositionedPopup(el, locationPop, {xOffset:108,yOffset:-74, popParent:'#mainContentWrap'});
		});
	
		$$('.topZipChange').each(function(el){
			new PositionedPopup(el, $('setLocation'), {xOffset:70,yOffset:10, popParent:'div.main'});
		});
		
		$$('.headerZip em').each(function(el){
			new PositionedPopup(el, $('setLocation'), {xOffset:70,yOffset:-18, popParent:'#header'});
		});
		
		$$('.enterZipPrice').each(function(el){
			new PositionedPopup(el, $('setLocation'), {xOffset:-10,yOffset:13, popParent:'.content_head'});
		});

		new LocationWidget(locationPop);
	}
		
	//zip widget
	new ImagePreloader(['/images/btn/btn_gray_over.gif',
						'/images/btn/btn_green_over.gif']);
						
	$$('#mainNavigation .drop').each(function(el){
		new DelayedHover(el, 'active', {delay:0.2});
	});
	
	new HeightNormalizer('.shadow_overlay, #mainContent');
});

function __globalHeightNormalizer(selector) {
		var max=0;
		$$(selector)
			.invoke('setStyle', {height:'auto'})
			.each(function(el){
				max = Math.max(max, el.getHeight());
			})
			.invoke('setStyle', {height:max+'px'});
}

function __globalFixHeight() {
	__globalHeightNormalizer('.shadow_overlay, #mainContent');
}
// When advanced filter is expanded, it adds the height and class are chopped -off, so add those px to height and when advanced filter closed, reduce px  from height.
function __adjustHeightNormalizer(selector) {
		var max=0;
		$$(selector)
			.invoke('setStyle', {height:'auto'})
			.each(function(el){
				max = Math.max(max, el.getHeight())+160;				
			})
			.invoke('setStyle', {height:max+'px'});

}

function __adjustFixHeight() {
	__adjustHeightNormalizer('.shadow_overlay, #mainContent');
}

function __reduceHeightNormalizer(selector) {
		var max=0;
		$$(selector)
			.invoke('setStyle', {height:'auto'})
			.each(function(el){
				max = Math.max(max, el.getHeight())-160;				
			})
			.invoke('setStyle', {height:max+'px'});

}

function __reduceFixHeight() {
	__reduceHeightNormalizer('.shadow_overlay, #mainContent');
}