// 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, callback: function(){}, openEffect : Effect.Appear, closeEffect : Effect.Fade, effectOpts : {duration: .4,afterFinish:this.callbackfn.bind(this)}, useDefaultEvent: false}, opts || {});
		this.pop = $(popId).setStyle({display:'none'});
		this.link = $(linkId);
		this.setup();
		this.pop.observe('pop:close', this.close.bind(this));
	},
	callbackfn : function(){
		try{
		this.pop.down('input[type=text]').focus();
		//this.options.callback();
		}catch(e){
		}

	},
	setup : function(){
        if(!this.options.observers) {
		    this.link.observe('click', this.open.bind(this));
        } else {
            this.options.observers.each(function(ev) {
                this.link.observe(ev, this.open.bind(this));
            }, this);
        }
		this.pop.select(this.options.closeSelector).each(function(el){
			el.observe('click', this.close.bind(this));
		}.bind(this));
	},
	open : function(ev){
		if (ev && !this.options.useDefaultEvent) ev.stop();
		try { closeAnyOpenedPopupWidget(); } catch(e) {};
		new this.options.openEffect(this.pop, this.options.effectOpts);
		if (this.options.modal)document.fire('pop:active');
        if (this.options.onOpen) { this.options.onOpen(); }
	},
	close : function(ev){
		if (ev) ev.stop();
		new this.options.closeEffect(this.pop, this.options.effectOpts);
		if (this.options.modal) document.fire('pop:inactive');
        if (this.options.onClose) { this.options.onClose(); }
	}
});

var ToolTip = Class.create(PopUp, {
	setup : function(){
		new HoverDelay(this.link, {
			enterCb : this.open.bind(this),
			leaveCb : this.close.bind(this)
		});
	}
});


document.observe('dom:loaded', function() {

    window.initTitleToolTips();

});



window.initTitleToolTips = function() {

    $$('.tooltip-from-title').each(function(element) {
        new TitleToolTip(element, {
            openEvents: ['mouseenter', 'click'],
            getContent: function(element) {
                // Grabs title into instances variable
                if(!this.content) {
                    this.content = element.getAttribute('rel');
                    element.removeAttribute('rel');
                }
                return this.content;
            }
        });
    });

};


var TitleToolTip = Class.create({

    options: {

        // All autogenerated names will be prefixed with this param
        classNamePrefix: 'tooltip',

        // A specific class name for better customization
        // By default 'tooltip-left' or 'tooltip-right' allow displaying arrows of tooltip
        specificClassName: 'tooltip-left',

        // Events that fires to show tooltip
        openEvents: ['mouseenter'],

        // Events that fires to hide tooltip
        closeEvents: ['mouseleave'],

        // Template for tooltip, should have #{content} string at content placement
        getTemplate: function(/*element*/) {
            if (!this.template)
                this.template = '<div class="' + this.getClassName('container') + '">' +
                                '<div class="' + this.getClassName('left', 'arrow') + '"><!-- --></div>' +
                                '<div class="' + this.getClassName('right', 'arrow') + '"><!-- --></div>' +
                                '<div class="opacFix"><!-- --></div>' +
                                '<table cellspacing="0">' +
                                    '<thead><tr>' +
                                        '<th class="' + this.getClassName('left') + '"></th>' +
                                        '<th class="' + this.getClassName('top') + '"><!-- --></th>' +
                                        '<th class="' + this.getClassName('right') + '"></th>' +
                                    '</tr></thead>' +
                                    '<tfoot><tr>' +
                                        '<td class="' + this.getClassName('left') + '"><!-- --></td>' +
                                        '<td class="' + this.getClassName('bottom') + '"><!-- --></td>' +
                                        '<td class="' + this.getClassName('right') + '"><!-- --></td>' +
                                    '</tr></tfoot>' +
                                    '<tbody><tr>' +
                                        '<td class="' + this.getClassName('left') + '"><!-- --></td>' +
                                        '<td class="' + this.getClassName('content') + '">#{content}</td>' +
                                        '<td class="' + this.getClassName('right') + '"><!-- --></td>' +
                                    '</tr></tbody>' +
                                '</table>' +
                            '</div>';

            return this.template;
        },

        // Default class generating method: getClassName('name', 'othername') => 'prefix-name-othername'
        getClassName: function() {
            var names = Array.from(arguments);
            names.splice(0, 0, this.classNamePrefix);
            return  names.join('-');
        },

        // Default content grabber
        getContent: function(element) {
            if(!this.content) this.content = element.getAttribute('title');
            return this.content;
        },

        // Default positioning method
        applyStyles: function(element/*, tooltip*/) {
            var offset = element.cumulativeOffset();
            var dimensions = element.getDimensions();
            return {
                left: offset.left + dimensions.width + 'px',
                top: offset.top + dimensions.height + 'px',
                position: 'absolute',
                zIndex: 10
            };
        }

    },

    initialize: function(element, options) {
        this.element = $(element);

        if(this.element.hasTitleToolTip) return false;
        this.element.hasTitleToolTip = true;

        this.options = Object.extend(this.options, options);

        this.options.openEvents.each(function(event) {
            this.element.observe(event, function(event) {
                event.stop();
                this.open();
            }.bind(this));
        }, this);

        this.options.closeEvents.each(function(event) {
            this.element.observe(event, this.close.bind(this));
        }, this);
    },

    close: function() {
        try {
            this.tooltip.remove();
        } catch(e) {}
    },

    open: function() {
        this.close();

        var template = this.options.getTemplate(this.element);
        var content = this.options.getContent(this.element);
        this.tooltip = new Element('div');
        this.tooltip.addClassName(this.options.specificClassName);
        this.tooltip.innerHTML = template.interpolate({ content: content });
        this.tooltip.setStyle(this.options.applyStyles(this.element, this.tooltip));
        this.tooltip.hide();
        document.body.insert(this.tooltip);

        new Effect.Appear(this.tooltip, { duration: 0.2 });
    }

});



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.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(){
		var pos = this.anchor.cumulativeOffset();
		this.side = (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();
DropDown.prototype = {
	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').addClassName('menuDrop');
		this.hidden = new Element('input', {'type':'hidden','name':this.orig.readAttribute('name'), 'id':this.orig.readAttribute('id')});

		this.selected = new Element('li')
            .addClassName('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').addClassName('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'}));
		});
	}
});

/************ 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');

	var locationPop = $('setLocation');
	if (locationPop!= null){
		$$('.enterZipSidebar').each(function(el){
			new PositionedPopup(el, locationPop, {xOffset:108,yOffset:-74, popParent:'#mainContentWrap'});
		});

		new LocationWidget(locationPop);
	}

	$$('.cal').each(function(el){
		new Calendar(el);
	});

	//zip widget
	$$('.topZipChange').each(function(el){
		new PositionedPopup(el, $('setLocation'), {xOffset:70,yOffset:10, popParent:'div.main'});
	});

	/**
	IE is throwing aborted error. So commenting it for timebeing. Besides, this code is not called elsewhere, so
	assumed that it is safe to comment.
	**/
	/*
	new ImagePreloader(['/images/btn/btn_gray_over.gif',
						'/images/btn/btn_green_over.gif']);
	*/
});
