/**************************************************************

	Script		: JFDLightBox
	Version		: 1.0
	Authors		: Jean-François Desgagné
	Desc		: Lightbox like apple style
	Website		: http://jfdesgagne.com
	Licence		: Open Source MIT Licence
	Description : A good lightbox with remove events, to avoid the monkey click bug.
	Usage		: window.addEvent('domready', function(){
					  //initialize lightyBox
					  var jfdLightBox = new JFDLightBox({
						 
						 
						 
					  });
				  });

**************************************************************/
var JFDLightBox = new Class({
	
	//implements
	Implements: [Options, Events],
	
	//properties
	elements:{
		container:null,
		box: null,
		closeButtonContainer:null,
		closeButton:null,
		controlsContainer:null,
		controls:null,
		navigation:null,
		previousListItem:null,
		previousButton:null,
		nextListItem:null,
		nextButton:null,
		title:null,
		description:null,
		imageLoaded:null,
		imageTemp:null
	},
	index:0,
	opened:false,
	startObjectCoords:null,
	totalImages:0,
	clickedButton:null,
	
	effects:{
		container:null,
		controllers:null,
		box:null,
		image:null,
		controls:null,
		closeBtn:null,
		imageTemp:null
	},
	
	
	bindedFunctions: {},
	
	//options
	options: {
		startObject:null,
		offset: {x:0, y:0},
		finalDimension: {width:698, height:371},
		className: '.jfdLB',
		container:null,
		contentColor: '#fff',
		showControls: true,
		useKeyboard: true,
		onOpen: new Class(),
		onClose: new Class(),
		mouseScroll:true
	},
	
	//initialization
	initialize: function(options) {
		this.options.container = $(document.body);
		this.setOptions(options);
		this.initBindedFunction();
		this.initStartupEvents();
	},
	
	//methods
	// To remove binded event function
	initBindedFunction: function() {
		this.bindedFunctions = {
			openBoxButtonClickHandler 	: this.openBoxButtonClickHandler.bindWithEvent(this),
			close				: this.close.bind(this)
		}
	},
	
	initStartupEvents: function() {
		$$(this.options.className).each(function(el){
			el.addEvent('click', this.bindedFunctions.openBoxButtonClickHandler);
			if(el.retrieve('originalHref')==null) el.store('originalHref', el.getProperty('href'));
			el.set('href', 'javascript://');
		}, this);
	},
	
	initEvents: function() {
		this.elements.closeButton.addEvent('click', this.bindedFunctions.close);
		if(this.options.useKeyboard){
			$(window.document).addEvent('keydown',function(e){
				if(e.key == 'right' || e.key == 'space'){
					this.next();
				}else if(e.key == 'left'){
					this.previous();
				}else if(e.key == 'esc'){
					this.close();
				};
			}.bind(this));
		}
		if(this.options.mouseScroll) {
			 $(window.document).addEvent('mousewheel', function(event) {
				if(event.wheel >0) {
					this.next();
				} else {
					this.previous();
				}
							
							
			}.bind(this));
		}
		window.addEvent('resize', this.resize.bind(this));
	},
	
	initEffects: function() {
		this.elements.container.set('opacity', 0);
		this.effects.container = new Fx.Morph(this.elements.container, {duration:1000});
		this.effects.box = new Fx.Morph(this.elements.box, {duration:1000});
		this.effects.controls = new Fx.Morph(this.elements.controls, {duration:1000, transition:Fx.Transitions.Expo.easeOut});
		this.effects.closeBtn = new Fx.Morph(this.elements.closeButton, {duration:1000, transition:Fx.Transitions.Expo.easeOut});
		this.effects.imageTemp = new Fx.Morph(this.elements.imageTemp, {duration:500});
	},
	
	removeAllEvents: function(withStartButton) {
		if(withStartButton) {
			$$(this.options.className).each(function(el){
				el.removeEvent('click', this.bindedFunctions.openBoxButtonClickHandler);
				el.setProperty('href', el.retrieve('originalHref'));
			}, this);
		}
		$(window.document).removeEvents('keydown');
		if(this.elements.imageLoaded) this.elements.imageLoaded.removeEvents('onload');
		if(this.effects.image) this.effects.image.removeEvents('onComplete');
		$(window.document).removeEvents('mousewheel');
		window.removeEvents('resize');
		this.effects.imageTemp.removeEvents('onComplete');
	},
		
	
	openBoxButtonClickHandler: function(event) {
		this.open(event.target.getParent());
	},
	
	createElements: function() {
		this.elements.container = new Element('div').addClass('jfdLB_container').inject(this.options.container,'inside');
		this.elements.box = new Element('div').addClass('jfdLB_containerBox').inject(this.elements.container, 'inside');
		this.elements.imageTemp = this.clickedButton.getFirst().clone().setStyles({width:'100%', height:'100%', position:'absolute'}).inject(this.elements.box, 'inside');
		this.elements.closeButtonContainer = new Element('div').addClass('jfdLB_closeBtnContainer').inject(this.elements.container,'inside');
		this.elements.closeButton = new Element('div').addClass('jfdLB_closeBtn').inject(this.elements.closeButtonContainer,'inside');
		this.elements.controlsContainer = new Element('div').addClass('jfdLB_controlsContainer').inject(this.elements.container,'inside');
		this.elements.controls = new Element('div').addClass('jfdLB_controls').inject(this.elements.controlsContainer,'inside');
		this.elements.navigation = new Element('ul').addClass('jfdLB_navigation').inject(this.elements.controls,'inside');
		this.elements.previousListItem = new Element('li').addClass('jfdLB_previouBtn').inject(this.elements.navigation,'inside');
		this.elements.previousButton = new Element('a').set({
			 'href': 'javascript://',
			 'class': 'hyperlink ',
			 'text': '« previous'
		}).inject(this.elements.previousListItem).addEvent('click', this.previous.bind(this));
		
		this.elements.nextListItem = new Element('li').addClass('jfdLB_nextBtn').inject(this.elements.navigation,'inside');
		this.elements.nextButton = new Element('a').set({
			'href': 'javascript://',
			'class': 'hyperlink',
			'text': 'next »'
		}).inject(this.elements.nextListItem).addEvent('click', this.next.bind(this));
		this.elements.title = new Element('div').addClass('jfdLB_title').inject(this.elements.controls,'inside');
		this.elements.description = new Element('div').addClass('jfdLB_desc').inject(this.elements.controls,'inside');
	},
	
	checkControlsDisabled: function() {
		if(this.index==0) {
			this.elements.previousButton.addClass('disabled');
		} else {
			this.elements.previousButton.removeClass('disabled');
		}
		
		if(this.index>=this.totalImages-1) {
			this.elements.nextButton.addClass('disabled');
		} else {
			this.elements.nextButton.removeClass('disabled');
		}
	},
	
	removeElements: function() {
		if(this.elements.imageLoaded) this.elements.imageLoaded.destroy();
		this.elements = {};
	},
	
	load: function() {
		this.elements.box.addClass('jfdLB_loading');
		var src = this.clickedButton.retrieve('originalHref').substring(0, this.clickedButton.retrieve('originalHref').length-4)+(this.index+1)+'.jpg';
		if(pageTracker) pageTracker._trackEvent("Showcase", "ShowImage", src);
		this.elements.imageLoaded = new Asset.image(src,{onload:this.imageLoaded.bind(this)});
		this.elements.imageLoaded.setStyles({width:'100%', height:'100%'});
		
		var title_desc = this.clickedButton.getProperty('title').split('|');
		this.elements.title.set('html', title_desc[0]+'<br /><a href="'+title_desc[1]+'" title="'+title_desc[1]+'" target="_blank" class="hyperlink">'+title_desc[1]+'</a>');
		
		if(!this.elements.imageTemp) this.elements.imageLoaded.setStyle('opacity', 0);		
	},
	
	imageLoaded:function() {
		this.elements.imageLoaded.inject(this.elements.box, 'inside');
		this.effects.image = new Fx.Morph(this.elements.imageLoaded, {duration:1000});
		if(this.elements.imageTemp) {
			this.effects.imageTemp.addEvent('onComplete', function() {
				this.effects.imageTemp.removeEvents('onComplete');
				if(this.elements.imageTemp) {
					this.elements.imageTemp.destroy();
					this.elements.imageTemp = null;
				}				
			}.bind(this));
			this.effects.imageTemp.cancel().start({
				opacity:0
			});
		} else if(this.opened) {
			 this.showImage();
		}
	},
	
	showImage:function() {
		if(this.effects.image) this.effects.image.cancel().start({
			opacity:1
		});
	},
	
	hideImage:function() {
		if(this.effects.image) this.effects.image.cancel().start({
			opacity:0
		});
	},
	
	showControls: function() {
		this.effects.controls.cancel().start({
			top:0
		});
		this.effects.closeBtn.cancel().start({
			bottom:0							 
		});
	},
	
	hideControls: function() {
		this.effects.controls.cancel().start({
			top:-45
		});
		this.effects.closeBtn.cancel().start({
			bottom:-94							 
		});
	},
	
	
	open: function(el) {
		this.fireEvent('open', this.close.bind(this));
		this.clickedButton = el;
		if(pageTracker) pageTracker._trackEvent("Showcase", "Open", this.clickedButton.getFirst().alt);
		var title_desc = this.clickedButton.getProperty('title').split('|');
		window.location.href = "#/projects/"+title_desc[2];
		
		
		this.startObjectCoords = this.options.startObject.getCoordinates();
		$$(this.options.className).removeEvent('click', this.bindedFunctions.openBoxButtonClickHandler);
		this.createElements();
		this.initEvents();
		this.initEffects();
		this.totalImages = el.rel;
		this.index = 0;
		this.checkControlsDisabled();
		this.load();
		
		
		this.startObjectCoords = this.options.startObject.getCoordinates();
		this.effects.container.addEvent('onComplete', this.openCompleted.bind(this));
		this.effects.container.cancel().set({
			left:this.startObjectCoords.left,
			top:this.startObjectCoords.top,
			opacity:0,
			top:this.startObjectCoords.top,
			left:this.startObjectCoords.left,
			width:this.startObjectCoords.width,
			height:this.startObjectCoords.height
		});
		this.resize();
	},
	
	openCompleted: function() {
		this.effects.container.removeEvents('onComplete');
		this.opened = true;
		this.showControls();
		if(this.elements.imageLoaded) if(this.elements.imageLoaded.width>0) this.showImage();
	},
	
	resize: function() {
		var top = (((window.getHeight() - this.options.finalDimension.height) / 2) - this.elements.container.getStyle('border').toInt() + window.getScrollTop()) + this.options.offset.y;
		var left = (((window.getWidth() - this.options.finalDimension.width) / 2) - this.elements.container.getStyle('border').toInt()) + this.options.offset.x;
		if(top < 0) top = 0; if(left < 0) left = 0;
		this.effects.container.cancel().start({
			opacity:1,
			top:top,
			left:left,
			width:this.options.finalDimension.width,
			height:this.options.finalDimension.height
		});
	},
	
	close: function() {
		if(pageTracker) pageTracker._trackEvent("Showcase", "Close", this.clickedButton.getFirst().alt);
		window.location.href = '#/';
		this.fireEvent('close');
		this.hideControls();
		this.startObjectCoords = this.options.startObject.getCoordinates();
		
		this.opened = false;
		this.removeAllEvents(false);
		//this.elements.box.removeClass('jfdLB_loading');
		if(this.elements.imageLoaded) this.elements.imageLoaded.setStyles({width:'100%', height:'100%'});
		
		this.effects.container.removeEvents('onComplete');
		this.effects.container.addEvent('onComplete', this.hideContainerCompleted.bind(this));
		this.effects.container.cancel().start({
			left:this.startObjectCoords.left,
			top:this.startObjectCoords.top,
			opacity:0,
			top:this.startObjectCoords.top,
			left:this.startObjectCoords.left,
			width:this.startObjectCoords.width,
			height:this.startObjectCoords.height
		});
	},
	
	hideContainerCompleted:function() {
		this.effects.container.removeEvents('onComplete');
		this.removeElements();
		this.initStartupEvents();		
	},
	
	previous: function() {
		if(this.index-1>=0)  {
			this.index--;
			this.effects.image.addEvent('onComplete', this.loadOtherImage.bind(this));
			this.hideImage();
		}	
		this.checkControlsDisabled();
		if(pageTracker) pageTracker._trackEvent("Showcase", "ShowPrev");
	},
	
	loadOtherImage: function() {
		this.effects.image.removeEvents('onComplete');
		if(this.elements.imageLoaded) this.elements.imageLoaded.destroy();
		this.load();
	},
	
	next: function() {
		if(this.index+1<=this.totalImages-1) {
			this.index++;
			this.effects.image.addEvent('onComplete', this.loadOtherImage.bind(this));
			this.hideImage();
		}
		this.checkControlsDisabled();
		if(pageTracker) pageTracker._trackEvent("Showcase", "ShowNext");
	}
	
});

