/** 
* @projectDescription	Globally-used javascript
*
* @id	base.js
*/

// IE6 Browser Detection
Prototype.Browser.IE6 = Prototype.Browser.IE && parseInt(navigator.userAgent.substring(navigator.userAgent.indexOf("MSIE") + 5), 10) === 6;

Effect.Transitions.easeOutCubic = function(pos){
	return (Math.pow((pos-1), 3) +1);
}

/**
 * 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();
			});
		}
	}
});



/**
 * Tab controller that uses togglers to trigger click events on toggling its
 * corresponding content
 * @alias Tabs
 * @param {string} container The parent html element
 * @param {array} togglers The elements that toggle the tabs
 * @param {array} tabs The tabs
 * @param {integer} active The index of which tab to display, defaults to 0
 */
var Tabs = Class.create({
	initialize: function (container, togglers, tabs, active) {
		this.container = $(container);
		this.togglers = $(togglers);
		this.tabs = $(tabs);
		this.active = active || 0;
		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));
	}
});

/**
 * Manages the embedded YouTube video's on the product page.
 * This fetches a relevant thumbnail screenshot using YouTube's API
 * The video is not embedded until the user clicks the video screenshot.
 * @alias YouTubeEmbed
 * @param {string} container This is the parent HTML element
 */
var YouTubeEmbed = Class.create({
	initialize: function (container, width, height) {
		this.container = $(container);
		this.playBtn = this.container.down('#btn_play');
		this.origHTML = this.container.innerHTML;
		this.matches = this.container.down('a').href.match(/v=([A-Za-z0-9\-=_]{11})/);
		
		/*
		this.screenshot = new Element('img', {
			'src': 'http://img.youtube.com/vi/' + this.matches[1] + '/0.jpg'
		});
		*/
		this.width = width;
		this.height = height;
		
		this.setup();
	},
	setup: function () {
		this.playBtn.observe('click', this.play.bind(this));
		
		//handle ie6's lack of hover support on non-anchor elements
		if (Prototype.Browser.IE6) {
			this.container.observe('mouseenter', function () {
				this.addClassName('hover');
			});
			this.container.observe('mouseleave', function () {
				this.removeClassName('hover');
			});
		}
	},
	play: function (ev) {
		this.container.up().addClassName('active');
		
		if (this.matches && this.matches[1]) {
			var url = "http://www.youtube.com/v/" + this.matches[1] + "&hl=en&autoplay=1";
			this.so = swfobject.embedSWF(url, this.container.id, this.width, this.height, "8.0.0", "", {}, {allowscriptaccess: "always", wmode: "transparent"});
		}
	
		if (ev) {	
			ev.stop();
		}
	}
});

/**
 * Controls the product sliders on the specialty brand pages
 * @alias PhotoSlider
 * @param {string} container This is the parent HTML element
 * @param {string} increment This is the increment of number of products to slide
 */
var PhotoSlider = Class.create({
	initialize: function (container, width, increment) {
		this.container = $(container);
		this.increment = increment;
		this.contents = this.container.down('.slides');
		this.prevBtns = this.container.select('.prev');
		this.nextBtns = this.container.select('.next');
		this.offset = this.contents.positionedOffset()[0];
		this.width = width;
		this.year = this.container.id.split('year_')[1];
		this.dir = "/img/photo/";
		this.setup();
	},
	setup: function () {
		this.loadPhotos(this.year);
		this.slides = this.container.select('.slides li');
		this.slideCount = parseInt(this.slides.length / this.increment) + 1;		
		
		//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);
	},
	loadPhotos: function (year) {
		this.contents.update();
		var num;
		var list = new Element('ul', { 'class' : 'clear' });
		this.contents.insert(list);
		if (year == 2009) {
			num = 16;
		}
		else {
			num = 13;
		}
		
		for (i = 1; i <= num; i++) {
			var photo = new Element('img', {
				src: this.dir + year + "/" + year + "_" + i + ".jpg"
			});
			var li = new Element('li').update(photo);
			list.insert(li);
		}
	},
	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.easeOutCubic, 
			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();
	}
});

/**
 * @alias GalleryPop
 * @param {string} trigger This is the mouse click trigger
 * @param {string} pop This is the popup
 */

var GalleryPop = Class.create(PopUp, {
	initialize: function ($super, trigger, pop) {
		this.trigger = trigger;
		this.pop = pop;
		this.cancel = this.pop.down('.forgotPassword');
		this.current = this.trigger.className.split('tab_')[1];
		
		this.options = {
			centered: true,
			modal: true,
			onOpen: this._open.bind(this),
			onClose: this._close.bind(this)
		};

		$super(this.trigger, this.pop, this.options);
	},
	_open: function () {
		new PhotoSlider('year_2009', 720, 3);
		new PhotoSlider('year_2008', 720, 3);
		new Tabs($('galleries'), $('galleries').select('.togglers li'), $('galleries').select('.tab'), this.current);
	},
	_close: function () {
		$('galleries').select('.togglers li').invoke('removeClassName','active');
		$('galleries').select('.tab').invoke('removeClassName','active');
	}
});


var ChartBars = Class.create({
	initialize: function() {
		this.container = $('impact');
		this.bars = this.container.select('.bar');
		this.setup();
	},
	setup: function () {
		this.bars.each(function (el, i) {
			var targetTop = (this.container.getHeight() - el.getHeight()) - 6;
			setTimeout(function () {
				new Effect.Morph(el, {
					style: 'top: ' + targetTop + 'px',
					duration: 0.4,
					transition: Effect.Transitions.easeOutCubic,
					afterFinish: function () {
						if (Prototype.Browser.IE) {
							el.down('.over').show();
							el.down('.default').hide();
						}
						else {
							el.down('.over').appear({ duration: 0.5 });
							el.down('.default').fade({ duration: 1.8 });
						}
					}.bind(this)
				});
			}.bind(this), 1000 * i);
		}.bind(this));
	}
});

/* ExternalLink
----------------------------------------------------------------------------------------*/
var ExternalLink = Class.create({
	initialize: function(selector) {
		this.selector = selector;
		this.setup();
	},
	setup: function() {
		if(this.selector.getAttribute("href") && this.selector.getAttribute("rel") == "external")
			this.selector.observe('click', this.open_window.bind(this));
	},
	open_window: function(ev) {
		window.open(this.selector.href);
		ev.stop();
	}
});

/**
 * Manages the video popups with embedded YouTube video's.
 * When a user clicks a link to view a video, a popup will appear containing the relevant video.
 * Inherits the PopUp class
 * @alias YouTubePlayer
 * @param {string} trigger This is the mouse click trigger
 * @param {string} pop This is the popup
 */
var YouTubePlayer = Class.create(PopUp, {
	initialize: function ($super, trigger, pop, width, height) {
		this.trigger = trigger;
		this.pop = pop;
		this.width = width;
		this.height = height;
		
		this.options = {
			onOpen:  this._open.bind(this),
			modal: true,
			centered: true,
			headerSelector: "div.header",
			videoSelector:  "youtube_player"
		};
		
		
		$super(this.trigger, this.pop, this.options);
	},
	_open: function () {
		$(this.pop).down('.content').setStyle({ height: this.height + 'px' });
		
		if (this.trigger.title && this.options.headerSelector) {
			this.header = this.pop.down(this.options.headerSelector);
			if (this.header) {
				this.header.innerHTML = this.trigger.title;
				Cufon.replace(this.header, {fontFamily: 'Gotham Rounded'});
			}
		}
		if (this.options.modal) {
			$('modal_overlay').show();
		}
		var matches, url;
		matches = this.trigger.href.match(/v=([A-Za-z0-9\-=_]{11})/);
		
		if (matches && matches[1]) {
			url = "http://www.youtube.com/v/" + matches[1] + "&hl=en&hd=1&showinfo=0";
			this.so = swfobject.embedSWF(url, this.options.videoSelector, this.width, this.height, "8.0.0", "", {}, {allowscriptaccess: "always", wmode: "transparent"});
		}
	}
});

var VimeoPlayer = Class.create(PopUp, {
	initialize: function ($super, trigger, pop, width, height) {
		this.trigger = trigger;
		this.pop = pop;
		this.width = width;
		this.height = height;
		
		this.options = {
			onOpen:  this._open.bind(this),
			modal: true,
			centered: true,
			headerSelector: "div.header",
			videoSelector:  "youtube_player"
		};
		
		$super(this.trigger, this.pop, this.options);
	},
	_open: function () {
		if (this.trigger.title && this.options.headerSelector) {
			this.header = this.pop.down(this.options.headerSelector);

			if (this.header) {
				this.header.innerHTML = this.trigger.title;
			}
		}
		
		var matches, url;
		matches = this.trigger.href.match(/v=([A-Za-z0-9\-=_]{11})/);
		
		if (matches && matches[1]) {
			url = "http://www.youtube.com/v/" + matches[1] + "?&hl=en&showinfo=0";
			this.so = swfobject.embedSWF(url, this.options.videoSelector, this.width, this.height, "8.0.0", "", {}, {allowscriptaccess: "always", wmode: "transparent"});
		} 
		
		/*
		var url = "http://vimeo.com/moogaloop.swf?clip_id=10470437&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=&amp;fullscreen=1";
		*/
		this.so = swfobject.embedSWF(url, this.options.videoSelector, this.width, this.height, "8.0.0", "", {}, {
			allowscriptaccess: "always", 
			wmode: "transparent"
		});
	}
});

/*--------------------------------------------------------------------------*/

var Carousel = Class.create({
	initialize: function (container) {
		this.container = $(container);
		
		this.contents = this.container.down('.slides');
		this.slides = this.contents.select('.slide');
		this.prevBtn = this.container.down('.toggle_prev');
		this.nextBtn = this.container.down('.toggle_next');
		this.slideCount = this.slides.length;
		this.offset = this.contents.positionedOffset()[0];
		this.width = $(this.slides[0]).getWidth();
		
		this.current = 0;
		this.setup();
	},
	setup: function () {
		this.prevBtn.observe('click', this.prev.bind(this));
		this.nextBtn.observe('click', this.next.bind(this));
			
		this.goTo(0);
		//this.start();
	},
	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: .5,
			transition: Effect.Transitions.easeOutCubic
		});
	},
	next : function(ev){
		ev.stop();
		this.goTo(this.current+1);
	},
	prev : function(ev){
		ev.stop();
		this.goTo(this.current-1);
	}
});

function Hero() {
	setTimeout(function () {
		if (!Prototype.Browser.IE) {
			new Effect.Appear('paulina', {
				duration: 1.4,
				from: 0,
				to: 1
			});
		}
		else { $('video').addClassName('video_active'); }
	}, 500);
	$('video').observe('mouseenter', function () {
		$(this).addClassName('hover');
	});
	$('video').observe('mouseleave', function () {
		$(this).removeClassName('hover');
	});
}

function openWindow(url, w, h, name) {
    var width = w;
    var height = h;
    var left = parseInt((screen.availWidth/2) - (width/2));
    var top = parseInt((screen.availHeight/2) - (height/2));
    var windowFeatures = "width=" + width + ",height=" + height + ",status,resizable,left=" + left + ",top=" + top + "screenX=" + left + ",screenY=" + top;
    myWindow = window.open(url, name, windowFeatures);
}

/**
 * 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) {}
	}
	
	Cufon.replace("h2, .story .read span", {fontFamily: 'Gotham Medium', hover: true});
	Cufon.replace(".hero p", {fontFamily: 'Gotham Book'});
	Cufon.replace(".gallery .view a, .hero p strong", {fontFamily: 'Gotham Rounded', hover: true});
	Cufon.replace(".hero .sig", {fontFamily: 'Gotham Medium'});
	
	Hero();
	
	new YouTubePlayer('paulina', 'youtube', 640, 505);
	new YouTubePlayer('btn_play', 'youtube', 640, 505);
	new YouTubePlayer('video_ribbon', 'youtube', 640, 505);
	
	$$('.gallery .btn').each(function (el) { new YouTubePlayer(el, 'youtube', 640, 390); });
	$$('.gallery .view a').each(function (el) { new GalleryPop(el, $('galleries')); });
	
	new PopUp('btn_email', 'send_friend', { centered: true, modal: true });
	new PopUp('btn_email2', 'send_friend', { centered: true, modal: true });

	var valid = new Validation('form_send_friend', {immediate : true, onSubmit : true});
	
	new Carousel($('carousel'));

	$$('a[rel="external"]').each(function (el) {
		new ExternalLink(el);
	});
});

window.onload = function () { $('fblike').addClassName('loaded'); }
