/** 
* @projectDescription	Globally-used javascript
*
* @id	base.js
*/ 
/*Effect.Transitions.EaseFromTo = function(pos) {
    if ((pos/=0.5) < 1) return 0.5*Math.pow(pos,4);
    return -0.5 * ((pos-=2)*Math.pow(pos,3) - 2);   
}; */
// IE6 Browser Detection
Prototype.Browser.IE6 = Prototype.Browser.IE && parseInt(navigator.userAgent.substring(navigator.userAgent.indexOf("MSIE") + 5), 10) === 6;

var Tabs = Class.create({
	initialize: function (container, togglers, tabs, active, options) {
		this.container = $(container);
		this.togglers = $(togglers);
		this.tabs = $(tabs);
		this.active = active || 0;
		this.options = options || null;
		this.setup();
	},
	setup: function () {
		this.tabs[this.active].addClassName('active');
		this.togglers[this.active].addClassName('active');
		
		this.togglers.each(function (el, i) {
			el.onclick = function () {
				if (i !== this.active) {
					el.addClassName('active');
					this.togglers[this.active].removeClassName('active');
					
					if (this.tabs.length === this.togglers.length) {
						this.tabs[this.active].removeClassName('active');
						this.tabs[i].addClassName('active');
					}
				}
				this.active = i;
				return false;
			}.bind(this);
		}.bind(this));
	}
});


var AjaxTabs = Class.create(Tabs, {
	setup: function($super){
	    this.cache = {};
        this.togglers.each(function(t, i){
            t.observe('click', function(ev){
                this.click(ev, i);
            }.bind(this));
            if (t.hasClassName('active'))
                this.active = i;
        }.bind(this));
		this.tab = this.tabs[0].addClassName('active');
        this.togglers[this.active].addClassName('active');
        this.extra_params = this.options ? this.options.extra_params : null;
        this.onUpdate = this.options ? this.options.onUpdate ? this.options.onUpdate : null : null;
        //this.reload();
        document.observe('state:selected', this.update_link.bind(this));
	},
	click: function(ev, idx){
		var el = ev.element ? ev.element() : ev;

        this.togglers[this.active].removeClassName('active');
        
        var cache_key = el.readAttribute('href');
        var cache = this.cache[cache_key];
        if (cache){
            this.tab.select('div.container').invoke('hide');
            cache.show();
        }else{
            var url = el.readAttribute('href');
            if (this.extra_params)
                url += (url.include('?') ? '&' : '?')+Object.toQueryString(this.extra_params);
            this.loading();
    		new Ajax.Request(url, {
    		    method:'get',
    		    //onFailure: function(){ this.loading(true); },
    		    onSuccess: function (r) {
    		        var div = new Element('div').addClassName('container').insert('<div>'+r.responseText.stripScripts()+'</div>');
    		        this.cache[cache_key] = div;
    		        this.tab.select('div.container').invoke('hide');
    		        if (this.notfirst)
    		          this.tab.insert(div);
    		        else{
    		            this.tab.update(div);
    		            this.notfirst = true;
    		        }
    		        this.loading(true);
    		        if (this.onUpdate) this.onUpdate();
                }.bind(this)});
        }
		this.active = idx;
		this.togglers[this.active].addClassName('active');
		if (ev.stop) ev.stop();
	},
	loading: function(done){
        this.container.down('#product_tab_loader')[done?'hide':'show']();
        var o = this.container.down('.overlay');
        if (! done)
            o.style.height = this.container.getHeight()-70+'px';
        o[done?'hide':'show']();
	    
	},
	reload: function(){
	    this.click(this.togglers[this.active].down('a'), this.active);
	},
	update_link: function(event){
	    var initmode = event.memo.init || false;
	    if (initmode)
	       delete event.memo['init'];
	       
        this.togglers.each(function(el){
        	var el = el.down('a');
    		var href = el.readAttribute('href').split('?');
    		var params = href.length>1 ? href[1].toQueryParams() : {};
    		Object.extend(params, event.memo);
    		el.writeAttribute('href', href[0]+'?'+Object.toQueryString(params));
        }.bind(this));	
        // bust cache
        this.tabs.invoke('update');
        this.cache = {};
        if (! initmode)
            this.reload(); 
	}
});

/**
 * Adds a delay to mouseenter/mouseleave events for any type of element
 * @alias HoverDelay
 * @param {string} trigger This is the mouseenter/mouseleave trigger
 * @param {array} options This is a set of options that can be passed such as a close selector, enter / leave functions, and delay
 */
var HoverDelay = Class.create({
	initialize : function (trigger, options) {
		this.options = Object.extend({
			closeSelector : '.close', 
			enterCb : function () {},	
			leaveCb : function () {},	
			delay : 0.5
		}, options || {});
		
		this.trigger = $(trigger);
		this.timeout = null; 
		this.active = false;
		this.setup();
	},
	setup : function () {
		var eEvt, lEvt;
		eEvt = this.open.bindAsEventListener(this);
		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.trigger.addClassName("active");
			this.options.enterCb.bind(this)();
			this.active = true;
		}.bind(this).delay(this.options.delay);
	},
	close : function (ev) {
		if (this.inactive) { 
			return;
		}
		if (this.timeout) {
			window.clearTimeout(this.timeout);
			this.timeout = null;
		}
		if (this.active) {
			this.options.leaveCb.bind(this)(ev);
			this.active = false;
			this.trigger.removeClassName("active");
		}
	}
});


/**
 * Pop controller that handles various options such as centering, fade, modal, dragging
 * @alias PopUp
 * @param {string} trigger This is the mouse click trigger
 * @param {string} pop This is the popup
 * @param {array} options This is a set of options that can be passed such as a modal, center, fade, close selector, handle selector (for dragging), and extra open / close methods that can be passed functions
 */
var PopUp = Class.create({
	initialize : function (trigger, pop, options) {
	    if ((! trigger) || (! pop)) return;
		this.trigger = trigger;
		this.pop = $(pop);
		
		this.options = Object.extend({
			modal:  false,
			centered: false,
			fade: false,
			closeSelector:  '.close',
			handleSelector: '.overlay_head',
			enableHover: false,
			delay: 0,
			onOpen:    Prototype.emptyFunction,
			onClose:   Prototype.emptyFunction
		}, options || {});
		
		PopUp.i = 0;
		PopUp.open = false;
		this.setup();
	},
	setup : function () {
		this.pop.hide();
		if (this.options.enableHover) {
			this.trigger.observe('mouseenter', this.show.bindAsEventListener(this));
			
		}
		else {
			this.trigger.observe('click', this.open.bindAsEventListener(this));
		}
	},
	show: function (ev) {
		this.trigger.observe('mouseleave', function () {
			if (this.timeout) {
				clearTimeout(this.timeout);
				return;
			}
		}.bind(this));	
		
		this.timeout = setTimeout(this.open.bind(this), this.options.delay);
	},
	open : function (ev) {
		document.observe('pop:keepOpen',  function () { 
			Event.stopObserving(document, 'click', this.close_listener);
			
		}.bind(this));			
		
		// allow only one popup opened at a time
		if (PopUp.open) { 
			PopUp.open.close(false); 
		}
		PopUp.open = this;	
	
		document.fire("pop:active");
		this.toTop();
		this.trigger.addClassName("active");
		
		// close button(s)
		this.pop.select(this.options.closeSelector).each(function (el) {
			el.observe('click', this.close.bind(this));
		}.bind(this));
		
		// draggable handle
		this.pop.select(this.options.handleSelector).each(function (el) {
			this.draggable = new Draggable(this.pop, { handle: this.handle, starteffect: false, endeffect: false });
		}.bind(this));
				
		// close pop if user clicks anywhere in document
		this.close_listener = this.close.bindAsEventListener(this);
		Event.observe(document, 'click', this.close_listener);
		document.observe('pop:close',  this.close_listener);
		
		if (this.options.enableHover) {
			this.pop.observe('mouseleave', this.close_listener);
		}
		
		this.pop.observe('mouseenter', function () {
			Event.stopObserving(document, 'click', this.close_listener); 
		}.bind(this));

		this.pop.observe('mouseleave', function () {
			Event.observe(document, 'click', this.close_listener); 
		}.bind(this));
		
		// modal version
		if (this.options.modal) {
			this.initModalWindow('modal_overlay');
		}
		
		// centered version
		if (this.options.centered) {
			this.center();
		}

		// fade effect when appearing
		if (this.options.fade) {
			this.pop.appear({duration: 0.2});
		}
		// else just show
		else {
			this.pop.show();
		}
		
		
		(this.options.onOpen || Prototype.emptyFunction)();

		if (typeof(ev) === 'object') {
			ev.stop();
		}
	},
	close : function (ev) {

		document.fire("pop:inactive");
		PopUp.open = false;

		this.trigger.removeClassName("active");
		if (this.options.modal) {
			$('modal_overlay').hide();
		}
		if (this.options.fade) {
			this.pop.fade({duration: 0.2});
		}
		else {
			this.pop.hide();
		}
			
		Event.stopObserving(document, 'click', this.close_listener);
		document.stopObserving('pop:close',  this.close_listener);
		this.pop.stopObserving('mouseenter');
		this.pop.stopObserving('mouseleave');
		
		(this.options.onClose || Prototype.emptyFunction)();
		
		if (ev) {
			ev.stop();
		}
	},
	initModalWindow: function (el) {
		$(el).setStyle({
			height: $$('body').first().getHeight() + "px",
			zIndex: 100
		});

		$(el).show();
	},
	toTop: function () {
		PopUp.i += 1;
		this.pop.style.zIndex = PopUp.i + 1000;
		this.pop.show();
	},
	center: function () {
		if (this.hasBeenCentered) { 
			return;
		}
		var w, h, pw, ph, ws;
		w = this.pop.offsetWidth;
		h = this.pop.offsetHeight;
		Position.prepare();
		ws = this.getWindowSize();
		pw = ws[0];
		ph = ws[1];
		this.pop.setStyle({
			top: (ph / 2) - (h / 2) +  Position.deltaY + "px",
			left: (pw / 2) - (w / 2) +  Position.deltaX + "px"
		});
		//this.hasBeenCentered = true;
	},
	getWindowSize: function (w) {
		w = w ? w : window;
		var width, height;
		width = w.innerWidth || (w.document.documentElement.clientWidth || w.document.body.clientWidth);
		height = w.innerHeight || (w.document.documentElement.clientHeight || w.document.body.clientHeight);
		return [width, height];
	},
	toggleSelects: function () {
		if (Prototype.Browser.IE6) {
			$$('select').each(function (e) {
				$(e).toggle();
			});
		}
	}
});


/**
 * Slideshow controller that accomodates with options for a prev/next togger, multiple togglers, or a combination of both
 * @alias SlideShow
 * @param {string} initial This is the index of the inital slide to appear on page load
 * @param {string} container This is the parent HTML element
 * @param {array} contents This is an array of slides
 * @param {integer} delay This is the delay between each slide transition
 * @param {array} options This is a set of options that can be passed such as prev/next togglers, multiple togglers
 */
var SlideShow = Class.create({
	initialize : function (initial, container, contents, delay, options) {
		this.initial = initial;
		this.container = container;
		this.contents = contents;
		this.delay = delay;
		this.fadeDuration = 0.5;
		this.showOnly(this.contents[this.initial]);
		this.current = initial;
		this.show = null;
		this.hide = null;
		
		this.options = Object.extend({
			prevToggler: '.prev',
			nextToggler: '.next',
			btnToggler: '.controls li'
		}, options || {});
		
		if (this.container.select(this.options.prevToggler).length > 0 && this.container.select(this.options.nextToggler).length > 0) {
			this.prevBtn = this.container.select('.prev')[0].addClassName('active');
			this.nextBtn = this.container.select('.next')[0].addClassName('active');
			this.prevBtn.observe('click', this.back.bindAsEventListener(this));
			this.nextBtn.observe('click', this.forward.bindAsEventListener(this));
			
			//handle ie6's lack of hover support on non-anchor elements
			if (Prototype.Browser.IE6) {
				this.prevBtn.observe('mouseenter', function () {
					this.addClassName('hover_prev');
				});
				this.prevBtn.observe('mouseleave', function () {
					this.removeClassName('hover_prev');
				});
			}
		}
		else if (this.container.select(this.options.btnToggler).length > 0) {
			this.buttons = this.container.select(this.options.btnToggler);
			this.buttons.each(function (el, i) {
				el.observe('click', function (ev) {
					ev.stop();
					this.pause();
					this.goTo(i, 0.5);
				}.bind(this));
			}.bind(this));
			
			this.buttons[this.current].addClassName('active');
			
		}
		else { 
			return;
		}
		
		document.observe('pop:active',  this.pause.bind(this));
		document.observe('pop:inactive',  this.start.bind(this));
		
		this.start();
	},
	start : function () {
		if (this.timer) { 
			return;
		}
		this.timer = setTimeout(this.next.bind(this), this.delay * 1000);
	},
	showOnly : function (el) {
		this.contents.invoke('hide');
		el.show();
	},
	pause : function () {
		if (this.timer) {
			clearTimeout(this.timer);
			this.timer = false;
		}
		if (this.hide) {
			this.hide.cancel();
		}
		else {
			return;
		}
	},
	back: function (ev) {
		if (this.show) {
			this.show.cancel();
			return;
		}	
		if (this.hide) {
			this.hide.cancel();
			return;
		}	

		this.pause(); 
		if (this.current === 0) {
			this.goTo(this.contents.length - 1);
		}
		else {
			this.goTo(this.current - 1);
		}
		ev.stop(); 
	},
	forward: function (ev) {
		if (this.show) {
			this.show.cancel();
			return;
		}	
		if (this.hide) {
			this.hide.cancel();
			return;
		}	
		
		this.pause();
		this.next();
		ev.stop(); 
	}, 
	next: function () {
		this.timer = false;
		if (this.current === this.contents.length - 1) {
			this.goTo(0);
		}
		else {
			this.goTo(this.current + 1);
		}
		this.start();
	},	
	goTo: function (idx, dur) {
		if (idx === this.current) { 
			return;
		}
		this.hide = new Effect.Fade(this.contents[this.current], { duration: this.fadeDuration || 2, afterFinish: function () {
			this.hide = null;
		}.bind(this)});
		
		if (this.buttons) {
			this.buttons[this.current].removeClassName('active');
		}
		
		this.current = idx;
		this.show = new Effect.Appear(this.contents[this.current], { duration: this.fadeDuration || 2, afterFinish: function () {
			this.show = null; 
		}.bind(this)});
		
		if (this.buttons) {
			this.buttons[this.current].addClassName('active');
			this.start();
		}
	}
});


/**
 * Ajax controller for handing basic ajax requests
 * @alias EasyAjax
 * @param {string} container This is the parent HTML element
 * @param {string} hotspot This is the mouse click trigger
 * @param {string} url This is url containing the requested content
 * @param {string} contents This is the HTML element that is updated with the ajax request
 */
var EasyAjax = Class.create({
	initialize: function (container, hotspot, url, contents) {
		this.container = container;
		this.hotspot = hotspot;
		this.contents = contents;
		this.url = url;
		this.loader = this.container.down('.overlay').hide();
		this.loaded = false;
		this.setup();
	},
	setup: function () {
		this.hotspot.observe('click', this.load.bind(this));
	},
	load: function () {
		var ajax = null;
		
		if (!this.loaded) {
			ajax = new Ajax.Updater(this.contents, this.url, {
				method: 'get',
				onLoading: function (t) {
					this.loader.show();
				}.bind(this),
				onSuccess: function (t) {
					this.loader.hide();
					this.loaded = true;
				}.bind(this),
				onFailure: function (t) {
					this.loader.hide();
					this.loaded = false;
				}
			});
		}
	}
});


/**
 * Basic ajax functionality for the State Fees
 * @alias AjaxStateFees
 * @param {string} container This is the parent HTML element
 */

/**
 * Controller that toggles a content's display from a specified trigger
 * @alias SimpleToggler
 * @param {string} trigger This is the mouse click trigger
 * @param {string} content This is HTML element being toggled
 */
var SimpleToggler = Class.create({
	initialize: function (trigger, content, options) {
		this.trigger = trigger;
		this.content = content;
		
		this.options = Object.extend({
			duration: 0.2
		}, options || {});		
		
		this.setup();
	},
	setup: function () {
		this.trigger.observe('click', this.toggler.bind(this));
	},
	toggler: function (ev) {
		this.trigger.toggleClassName("active");
		Effect.toggle(this.content, 'slide', { duration: this.options.duration }); 
		ev.stop();
	}
});


/**
 * Global site navigation with sub-menus
 * The sub-menus appear on hover with a slight delay to prevent sensitivity
 * @alias Navigation
 * @param {string} container This is the parent HTML element
 */
var Navigation = Class.create({
	initialize: function (container) {
		this.container = $(container);
		this.togglers = this.container.select('#main_nav li.menu');
		this.menus = this.container.select('.megadrop');
		
		if ((this.togglers.length > 0) && (this.menus.length > 0)) {
			this.setup();
		}
	},
	setup: function () {
		this.togglers.each(function (el, i) {
			var pop;
			pop = new PopUp(el, this.menus[i], {enableHover: true, delay: 150});
		}.bind(this));
	}
});


/**
 * @alias MyAccountPopUp
 * @param {string} trigger This is the mouse click trigger
 * @param {string} pop This is the popup
 */
/*var MyAccountPopUp = Class.create(PopUp, {
	initialize: function ($super, trigger, pop) {
		this.trigger = trigger;
		this.pop = pop;
		this.cancel = this.pop.down('.forgot_pw');
		this.pop.select('.field').each(function (el) {
			var prompt;
			prompt = new PromptLabel(el);
		});
	
		
		this.cancel.observe('click', function () {
			this.pop.hide();
		}.bind(this));
		$super(this.trigger, this.pop, this.options);
	},
	_open: function () {
	}
});
*/

/**
 * @alias HowItWorksPop
 * @param {string} trigger This is the mouse click trigger
 * @param {string} pop This is the popup
 */
var HowItWorksPop = Class.create(PopUp, {
	initialize: function ($super, trigger, pop) {
		this.trigger = trigger;
		this.pop = pop;
		
		this.options = {
			modal: true,
			centered: true,
			onOpen: this._open.bind(this),
			onClose: this._close.bind(this)
		};
		
		$super(this.trigger, this.pop, this.options);
	},
	_open: function () {
		this.slide = new PageSlide($('hw_slide'), $('hw_slide').down('.tabs'), $('hw_slide').select('.steps li'));
	},
	_close: function () {
		this.slide.reset();
	}
});

/**
 * 
 * @alias AdvancedTabs
 * @param {string} container This is the parent HTML element
 */
/*var AdvancedTabs = Class.create({
	initialize: function (container) {
		this.container  = $(container);
		this.togglers = this.container.select('.tabs li');
		this.tabs = this.container.select('.tab');
		this.closeBtn = this.container.select('.close');
		this.setup();
	},
	setup: function () {
		this.togglers.each(function (el, i) {
			el.observe('click', this.show.bindAsEventListener(this, i));
		}.bind(this));
		this.closeBtn.each(function (el, i) {
			el.observe('click', this.close.bindAsEventListener(this, i));
		}.bind(this));
	},
	show: function (ev, i) {
		this.togglers.invoke('removeClassName', 'active');
		this.togglers[i].addClassName('active');
		this.tabs.invoke('removeClassName', 'active');
		this.tabs[i].addClassName('active');
		if (ev) {
			ev.stop();
		}
	},
	close: function (ev, i) {
		this.togglers.invoke('removeClassName', 'active');
		this.tabs.invoke('removeClassName', 'active');
		if (ev) {
			ev.stop();
		}
	}
});*/


/**
 * 
 * @alias PageSlide
 * @param {string} container This is the parent HTML element
 */
var PageSlide = Class.create({
	initialize : function(container, contents, buttons, options){
		this.container = $(container);
		this.contents = contents;
		this.offset = contents.positionedOffset()[0];
		this.prevBtn = this.container.down('.prev');
		this.nextBtn = this.container.down('.next');
		this.width = this.container.select('.tab')[0].getWidth();
		this.buttons = buttons;
		
		this.buttons.each(function (el,idx) {
			el.observe('click', function(ev){
				ev.stop();
				this.go(idx);
			}.bind(this));
		}.bind(this));
		
		this.slideCount = this.buttons.length;
		this.nextBtn.observe('click', this.next.bind(this));
		this.prevBtn.observe('click', this.prev.bind(this));
		this.go(0);
	},
	go : function(idx){
		this.container.select('.tab')[this.current || 0].fire('nav:go');
		if (idx < 0 || idx >= this.slideCount) return;

		this.current = idx;
		
		this.buttons.invoke('removeClassName', 'active');
		this.buttons[idx].addClassName('active');
		
		if (this.moving) this.moving.cancel();
		this.moving = new Effect.Move(this.contents, {
			mode: 'absolute', 
			x:(-(idx*this.width)+this.offset), 
			duration: 0.3, 
			afterFinish: function(){
				this.prevBtn.style.display = this.current==0?'none':'block'
				this.nextBtn.style.display = this.current==this.slideCount-1 ? 'none':'block';
			}.bind(this)
		});
	},
	next : function(ev){
		ev.stop();
		this.go(this.current+1);
	},
	prev : function(ev){
		ev.stop();
		this.go(this.current-1);
	},
	reset: function () {
		this.buttons.invoke('removeClassName', 'active');
		this.buttons[0].addClassName('active');
		new Effect.Move(this.contents, {
			mode: 'absolute', 
			x: 0,
			duration: 0.3
		});
	}
});


/**
 * 
 * @alias ModalTabs
 * @param {string} container This is the parent HTML element
 */
var ModalTabs = Class.create({
	initialize: function (trigger, pop, togglers, tabs) {
		this.trigger = $(trigger);
		this.pop = $(pop);
		this.togglers = togglers;
		this.tabs = tabs;
		this.prevBtn = this.pop.down('.prev');
		this.nextBtn = this.pop.down('.next');
		this.current = 0;
		this.setup();
	},
	setup: function () {
		var popup = new PopUp(this.trigger, this.pop, { 
			centered: true, 
			modal: true 
		});
		
		this.togglers.each(function (el, i) {
			el.observe('click', this.show.bind(this, i));
		}.bind(this));
		
		this.prevBtn.observe('click', this.prev.bind(this));
		this.nextBtn.observe('click', this.next.bind(this));
	},
	show: function (idx) {
		this.togglers.invoke('removeClassName', 'active');
		this.togglers[idx].addClassName('active');
		this.tabs.invoke('removeClassName', 'active');
		this.tabs[idx].addClassName('active');
		this.current = idx;
	},
	prev: function (ev) {
		if (this.current === 0) {
			this.show(this.togglers.length - 1);
		}
		else {
			this.show(this.current - 1);
		}
		if (ev) {
			ev.stop();
		}	
	},
	next: function (ev) {
		if (this.current === (this.togglers.length - 1)) {
			this.show(0);
		}
		else {
			this.show(this.current + 1);
		}
		if (ev) {
			ev.stop();
		}	
	}
});

		


/**
 *
 * @alias IncorpPopUp
 * @param {string} trigger This is the mouse click trigger
 * @param {string} pop This is the popup
 */
var IncorpPopUp = Class.create(PopUp, {
	initialize: function ($super, trigger, pop) {
		this.trigger = trigger;
		this.pop = pop;
		this.selects = this.pop.select('select');
		
		this.options = {
			centered: true,
			modal: true,
			onOpen: this._open.bind(this)
		};
        this.setup_form();
		$super(this.trigger, this.pop, this.options);
	},
	setup_form: function(){
	    this.pop.down('button').observe('click', function(ev){
    	    ev.stop();
	        var key = Form.serializeElements(this.pop.select('input'), true).incorporate_type;
            document.location = INCORP_URLS[key]+'?state='+$F(this.pop.down('select'));   	    
	    }.bind(this));
	},
	_open: function () {
		new ToolTip('select_state_tooltip_trigger', 'select_state_tooltip');
		new ToolTip('select_business_tooltip_trigger', 'select_business_tooltip');
		
		this.selects.each(function (el) {
			el.observe('focus', function () {
				document.fire('pop:keepOpen');
			}.bind(this));
			el.observe('change', function () {
				document.fire('pop:keepOpen');
			}.bind(this));
		}.bind(this));
	}
});

Effect.Transitions.easeOutSine = function (pos) {
     return Math.sin(pos * (Math.PI / 2));
};

/*
 * Controls the product sliders on the specialty brand pages
 * @alias BasicSlider
 * @param {string} container This is the parent HTML element
 * @param {string} increment This is the increment of number of products to slide
 */
var BasicSlider = Class.create({
	initialize: function (container, increment) {
		this.container = $(container);
		this.increment = increment;
		this.contents = this.container.down('.slides');
		this.slides = this.contents.select('li.slide');
		this.prevBtns = this.container.select('.prev');
		this.nextBtns = this.container.select('.next');
		this.slideCount = this.slides.length / this.increment;
		this.offset = this.contents.positionedOffset()[0];
		this.width = this.slides[0].getWidth(); /* calculate width instead of declaring it explicitly */
		this.setup();
	},
	setup: function () {
		//handle ie6's lack of hover support on non-anchor elements
		if (Prototype.Browser.IE6) {
			this.prevBtns.each(function (el) {
				el.observe('mouseenter', function () {
					this.addClassName('hover_prev');
				});
				el.observe('mouseleave', function () {
					this.removeClassName('hover_prev');
				});
			}.bind(this));
			this.nextBtns.each(function (el) {
				el.observe('mouseenter', function () { 
					this.addClassName('hover_next');
				});
				el.observe('mouseleave', function () {
					this.removeClassName('hover_next');
				});
			}.bind(this));
		}

		this.prevBtns.each(function (el) {
			el.addClassName('active');
			el.observe('click', this.next.bind(this));
		}.bind(this));
		
		this.nextBtns.each(function (el) {
			el.addClassName('active');
			el.observe('click', this.prev.bind(this));
		}.bind(this));
		
		this.goTo(0);
	},
	goTo: function (idx) {
		if (this.current === idx) {
			return;
		}
		if (idx < 0 || idx >= this.slideCount) {
			return;
		}
		this.current = idx;
		if (this.moving) {
			this.moving.cancel();
		}
		
		this.moving = new Effect.Move(this.contents, { 
			mode: 'absolute', 
			x: (-(idx * this.width) + this.offset), 
			duration: 0.6, 
			transition: Effect.Transitions.easeOutSine, 
			afterFinish: function () {
				if (this.current === 0) {
					this.prevBtns.invoke('addClassName', 'disabled_prev');
				}
				else {
					this.prevBtns.invoke('removeClassName', 'disabled_prev');
				}
				if (this.current === (this.slideCount - 1)) {
					this.nextBtns.invoke('addClassName', 'disabled_next');
				}
				else {
					this.nextBtns.invoke('removeClassName', 'disabled_next');
				}
			}.bind(this)
		});
	},
	prev: function (ev) {
		this.goTo(this.current + 1);
		ev.stop();
	},
	next: function (ev) {
		this.goTo(this.current - 1);
		ev.stop();
	}
});

var DECODER = {
    codes:$H({
        '/':/%2F/g,
        '?':/%3F/g,
        '&':/%26/g,
        '=':/%3D/g,
        '.':/%2E/g
    })
    ,
    decode: function(s){
        DECODER.codes.each(function(k){
            s = s.replace(k.value,k.key);
        });
        return s;
    }    
};


/**
 * dom:loaded function calls
 */
document.observe('dom:loaded', function () {
	// cache background images in ie6 to prevent multiple http requests
	if (Prototype.Browser.IE6) {
		try {
			document.execCommand('BackgroundImageCache', false, true);
		} catch (e) {}
	}
		
});
