/*
	RevolveProductions.com javascript layer.
	Author:
		Andy dePasquale @ Web Akimbo, Aug 2009
		based on the work of Aaron Newton - aaron [at] iminta <dot> com
	
	Notes:
	- This script depends on the MooTools framework (www.mootools.net) and the Clientcide extensions (www.clientcide.com)
	- Currently these two things are in clientcide-trunk-2.0.3.js, which was built here: www.clientcide.com/js
*/

Clientcide.setAssetLocation('images/clientcide.assets');

//Refactor the default zIndex for Iframes for this site; see Class.Refactor on Clientcide
IframeShim = Class.refactor(IframeShim, {
	options: {zindex: -1}
});

//Extend to include method for getting siblings 
Element.implement({
	getSiblings: function() {
		return this.getParent().getChildren().erase(this);
	}
});

//defines all the functionality in the rp namespace
var rp = {};
$extend(rp, {
	
	/* global startup */

	//rp.init contains a collection of methods. These will be invoked when you
	//call rp.init.run(); it basically helps keep the functionality broken up into
	//understandable and well organized chunks. You can also call 
	//rp.init.get('METHOD_NAME')() to run a specific method
	init: new Hash({
		fixAnchors: function(){
			//don't try to navigate to links with href="#"
			$('body').addEvent('click', function(e){
				var clicked = $(e.target);
				if (clicked.get('tag') != 'a') clicked = clicked.getParent('a');
				if (clicked && clicked.get('href') == '#') e.preventDefault();
			});
		},
		targetBlank: function(){
			//target="_blank" won't validate in strict xhtml
			//mimic here after page load
			$$(document.links).each(function(link){
				if (link.getProperty('rel') == 'external') link.setProperties({'target': 'rpwin', 'title': 'opens in new window'}); 
			});
		},
		getBaseHref: function(){
			var production = true;
			var basehref = 'http://' + Browser.getHost();
			basehref += production ? '/' : (':' + Browser.getPort() + '/revolve/');
			return basehref;
		}
	}),
	
	/* classes */
	
	/*
	The VidNavigator class manages interactions for navigating videos within a given section.
	
	The constructor here takes three arguments (plus options):
	- trigger that reveals the inputs and controls (HREF)
	- list containing inputs and controls (HTML UL element)
	*/
	VidNavigator: new Class({
		Implements: [ToElement, Options, Events],
		Binds: ['getVideo','getNext','getPrev','keypressHandler','fLoadVideo'],
		property: 'vidNavigator',
		initialize: function(jsonData, options) {
			//define elements
			this.data = JSON.decode(jsonData);
			this.carousel = $('vidCarousel');
			this.md = $('metaData');
			this.vids = this.carousel.getElements('div.stillCont');
			this.btnPrev = $('clipNavLt');
			this.btnNext = $('clipNavRt');
			this.dots = $('dotNavInner').getElements('a');
			this.player = $('playerCont');
			this.playBtns = this.vids.getElements('a.play');
			this.vidCont = $('vidCont'); // need to change z-Index when playing a movie in order to use controls!
			
			//measurements
			this.vidCount = this.vids.length;
			this.vidLoaded = false;
			
			//setup morphs and relationships
			this.md.set('morph', {
				transition: 'quad:out',
				duration: 400
			});
			this.vids.each(function(vid){
				//morphs
				vid.set('morph', {
					transition: 'quint:out',
					duration: 1000,
					link: 'chain'
				});
				//prev/next clips
				var ioSafe, pv, nx;
				var io = this.vids.indexOf(vid);
				vid.store('index', io);
				if (this.vidCount == 1) {
					//one vid, no prev/next
					vid.store('prev', null);
					vid.store('next', null);
				} else if (this.vidCount == 2) {
					//two vids, prev/next is same (only other) vid
					vid.store('prev', vid.getSiblings()[0]);
					vid.store('next', vid.getSiblings()[0]);
				} else {
					ioSafe = io + this.vidCount;
					pv = (ioSafe - 1) % this.vidCount;
					nx = (ioSafe + 1) % this.vidCount;
					vid.store('prev', this.vids[pv]);
					vid.store('next', this.vids[nx]);
				}
			}.bind(this));
			
			this.setOptions(options);
			
			//attach behaviors
			this.enableBtns();
			
			//positions vids where they should be
			this.currVid = this.vids[0];
			this.setup();
			
			//carousel is hidden until stills are repositioned in setup(); unhide
			this.carousel.setStyle('visibility','visible');
		},
		
		setup: function() {
			//get carousel width
			this.carouselW = this.carousel.getComputedSize().width;
			//reposition videos
			//all except selected vid live just off left edge until called into action
			this.vids.each(function(vid){
				if (vid == this.currVid) {
					vid.setPosition({
						relativeTo: this.carousel,
						position: 'centerTop',
						edge: 'centerTop',
						offset: {x: -185}
					});
				} else {
					vid.setPosition({
						relativeTo: this.carousel,
						position: 'leftTop',
						edge: 'rightTop',
						offset: {x: -100}
					});
				}
			}.bind(this));
			
			//store x vals for various positions
			this.vidPos = {
				'ctr': this.currVid.getPosition().x,
				'lt':	 -(this.currVid.getComputedSize().width + 100),
				'rt':  (this.carouselW + 100)
			};
		},

		getVideo: function(e) {
			var dot = $(e.target);
			if (dot.hasClass('sel')) { return false; }
			this.disableBtns();
			//somewhat directional: left of selected dot, come in from left, and vice versa
			//compare indexes of current and selected vids
			var mimicNext = (dot.get('rel') > this.currVid.retrieve('index'));
			var selVid = this.vids[dot.get('rel')];
			if (mimicNext) this.moveForward(selVid);
				else this.moveBack(selVid);
			//update metadata
			this.chgMetadata(selVid);
			//chg dot nav
			this.chgDotNav(selVid);
		},
		
		getNext: function(e) {
			if (this.vidCount <= 1) { return false; } //for keypresses
			this.disableBtns();
			var selVid = this.currVid.retrieve('next');
			//tween
			this.moveForward(selVid);
			//update metadata
			this.chgMetadata(selVid);
			//chg dot nav
			this.chgDotNav(selVid);
		},
		
		getPrev: function(e) {
			if (this.vidCount <= 1) { return false; } //for keypresses
			this.disableBtns();
			var selVid = this.currVid.retrieve('prev');
			//tween
			this.moveBack(selVid);
			//update metadata
			this.chgMetadata(selVid);
			//chg dot nav
			this.chgDotNav(selVid);
		},
		
		moveForward: function(selVid) {
			this.carousel.setStyle('z-index','200');
			this.fUnloadVideo();
			var sMorph = selVid.get('morph');
			var cMorph = this.currVid.get('morph');
			//put selected vid in on-deck circle (off right side)
			sMorph.set({'left':this.vidPos.rt});
			//move center and right videos to the left
			cMorph.start({'left':this.vidPos.lt});
			sMorph.start({'left':this.vidPos.ctr}).chain(function(){
				this.cleanup(selVid);
				this.carousel.setStyle('z-index','499');
			}.bind(this));
		},
		
		moveBack: function(selVid) {
			this.carousel.setStyle('z-index','200');
			this.fUnloadVideo();
			var sMorph = selVid.get('morph');
			var cMorph = this.currVid.get('morph');
			//move center and left videos to the right
			cMorph.start({'left':this.vidPos.rt});
			sMorph.start({'left':this.vidPos.ctr}).chain(function(){
				cMorph.set({'left':this.vidPos.lt});
				this.cleanup(selVid);
				this.carousel.setStyle('z-index','499');
			}.bind(this));
		},
		
		cleanup: function(selVid) {
			//update selected
			this.currVid = selVid;
			this.enableBtns();
		},
		
		chgDotNav: function(selVid) {
			this.dots[this.currVid.retrieve('index')].removeClass('sel');
			this.dots[selVid.retrieve('index')].addClass('sel');
		},
		
		chgMetadata: function(selVid) {
			var morph = this.md.get('morph'); 
			morph.start({'opacity':0}).chain(function(){
				var o = this.data[selVid.retrieve('index')];
				//update data
				//the following are all required by the db
				$('mdTitle').set('text', o.title);
				$('mdDate').set('text', o.year);
				$('mdRuntime').set('text', o.runtime);
				$('mdAbstract').set('text', o.abs);
				//and these are optional
				if (o.links) {
					$('mdLinks').setStyle('display','block');
					var linkCont = $('mdLinkCont').empty();
					var links = o.links.split(_sepRecord);
					var nLink;
					links.each(function(link){
						nLink = link.split(_sepField);
						linkCont.adopt(new Element('a', { 'href':nLink[0], 'html':nLink[1], 'rel':'external' }));
						linkCont.adopt(new Element('br'));
					});
				} else {
					$('mdLinks').setStyle('display','none');
				}
				if (o.logos) {
					var logoCont = $('mdLogos').empty().setStyle('display','block');
					var logos = o.logos.split(_sepRecord);
					var nLogo, nLogoLink;
					logos.each(function(logo){
						nLogo = logo.split(_sepField);
						nLogoLink = new Element('a', { 'href':nLogo[1], 'rel':'external' }).adopt(new Element('img', { 'src':'content/logos/' + nLogo[0] }));
						logoCont.adopt(nLogoLink);
					});
					//$('mdLogos').empty().adopt(new Element('img', { 'src':'content/logos/'+o.logos })).setStyle('display','block');
					//var logoCont = $('mdLaurelCont').empty().appendText(o.laurels);
				} else {
					$('mdLogos').setStyle('display','none');
				}
				//make sure new links open in new win
				if (o.links || o.logos) rp.init.get('targetBlank')();
				//morph
				morph.callChain();
			}.bind(this)).chain(function(){
				this.md.get('morph').start({'opacity':1});
			}.bind(this));
		},
		
		enableBtns: function() {
			this.btnPrev.addEvent('click', this.getPrev);
			this.btnNext.addEvent('click', this.getNext);
			this.dots.each(function(dot){
				dot.addEvent('click', this.getVideo);
			}.bind(this));
			this.playBtns.each(function(pb){
				pb.addEvent('click', this.fLoadVideo);
			}.bind(this));
			document.addEvent('keydown', this.keypressHandler);
		},
		
		disableBtns: function() {
			this.btnPrev.removeEvent('click', this.getPrev);
			this.btnNext.removeEvent('click', this.getNext);
			this.dots.each(function(dot){
				dot.removeEvent('click', this.getVideo);
			}.bind(this));
			this.playBtns.each(function(pb){
				pb.removeEvent('click', this.fLoadVideo);
			}.bind(this));
			document.removeEvent('keydown', this.keypressHandler);
		},
		
		keypressHandler: function(e) {
			if (e.key == 'left') return this.getPrev(e);
			if (e.key == 'right') return this.getNext(e);
			return true;
		},
		
		fLoadVideo: function(e) {
			//show player & bring forward; hide still container
			this.player.setStyle('top','0px');
//			this.vidCont.setStyle('z-index','501');
//			this.currVid.setStyle('display','none');
			this.carousel.setStyle('display','none');
			//load video
			var index = $(e.target).getParent().retrieve('index');
			this.getFlashMovie(fmId).flashLoadVideo(videoPath + this.data[index].clip);
			this.vidLoaded = true;
		},
		
		fUnloadVideo: function() {
			if (!this.vidLoaded) return false;
			//unload video
			this.getFlashMovie(fmId).flashUnloadVideo();
			//hide player & move backward; show still container
//			this.currVid.setStyle('display','block');
			this.carousel.setStyle('display','block');
			this.player.setStyle('top','-9999px');
//			this.vidCont.setStyle('z-index','-1');
			this.vidLoaded = false;
		},

		//gets a reference to the video player swf
		getFlashMovie: function(el) {
			return swfobject.getObjectById(el);
		},
		
		flashSecurityError: function(error) {
			alert(error);
		},
		
		flashExternalInterfaceError: function(error) {
			alert(error);
		},
		
		traceIt: function(msg) {
			alert(msg);
		}
	})

});


//when the dom is ready, run the methods in the rp.init hash.
window.addEvent('domready', rp.init.run.bind(rp.init));

