/*
 * Carousel
 * @author Marcel Gehring
 * @version 1.0
 * @classDescription A Carousel Object. Created with the help of MooTools v1.2.2 Core and MooTools v1.2.2.1 More
 * Copyright Hewlett-Packard Company 2009.
-- start it up by doing this in your domready:

new Carousel($$('img.carousel',$('carouseldiv'));
 */
 
Carousel = new Class ({

	Implements: [Events, Options],

	options: {
		'wrapper_class':'carousel',
		'carousel_class':'images',
		'leftBtn_class':'leftBtn',
		'rightBtn_class':'rightBtn',
		
		'brakeLength': 100,
		'initialLeft': 0,
		'speedfactor': 3,
		'enableHover': true,
		'enableDetail': true,
		'maxDetailWidth': 600,
		'maxDetailHeight': 450,
		'modalDetail':true,
		'snapToGrid':true,
		'transOut':Fx.Transitions.Expo,
		'transIn':Fx.Transitions.linear,
		'startevent':'mousedown',
		'endevent':'mouseup'
	},
	
	initialize: function(images, target, options) {

		this.images = images;
		
		this.options.wrapper_class = (options.wrapper_class) ? options.wrapper_class : this.options.wrapper_class;
		this.options.carousel_class = (options.carousel_class) ? options.carousel_class : this.options.carousel_class;
		this.options.leftBtn_class = (options.leftBtn_class) ? options.leftBtn_class : this.options.leftBtn_class;
		this.options.rightBtn_class = (options.rightBtn_class) ? options.rightBtn_class : this.options.rightBtn_class;
		
		this.options.brakeLength = (options.brakeLength) ? options.brakeLength : this.options.brakeLength;
		this.options.initialLeft = (options.initialLeft) ? options.initialLeft : this.options.initialLeft;
		this.options.speedfactor = (options.speedfactor) ? options.speedfactor : this.options.speedfactor;
		this.options.enableHover = (options.enableHover) ? options.enableHover : this.options.enableHover;
		this.options.enableDetail = (options.enableDetail) ? options.enableDetail : this.options.enableDetail;
		this.options.maxDetailWidth = (options.maxDetailWidth) ? options.maxDetailWidth : this.options.maxDetailWidth;
		this.options.maxDetailHeight = (options.maxDetailHeight) ? options.maxDetailHeight : this.options.maxDetailHeight;
		this.options.modalDetail = (options.modalDetail) ? options.modalDetail : this.options.modalDetail;
		this.options.snapToGrid = (options.snapToGrid) ? options.snapToGrid : this.options.snapToGrid;
		this.options.transOut = (options.transOut) ? options.transOut : this.options.transOut;
		this.options.transIn = (options.transIn) ? options.transIn : this.options.transIn;
		this.options.startevent = (options.startevent) ? options.startevent : this.options.startevent;
		this.options.endevent = (options.endevent) ? options.endevent : this.options.endevent;
		
	
		this.wrapper = new Element('div', {
			'class': this.options.wrapper_class
		});
		
		this.leftBtn = new Element('div', {
			'class': this.options.leftBtn_class
		}).setStyles({'float': 'left', 'cursor':'pointer'});
		this.carousel = new Element('div', {
			'class': this.options.carousel_class
		}).setStyles({
			'width':100000, 
			'margin-left':this.options.initialLeft
		});
		this.rightBtn = new Element('div', {
			'class': this.options.rightBtn_class
		}).setStyles({'float':'right', 'cursor':'pointer'});
		var cleardiv = new Element('div').setStyles({'height':0,'clear':'both','line-height':0});

		this.carouselwrapper = new Element('div').setStyles({
			'overflow':'hidden',
			'float':'left'
		}).grab(this.carousel);
		
		target.grab(this.wrapper);
		for (var i=0; i<this.images.length; i++)
		{
			this.carousel.grab(this.images[i]);
			this.images[i].setStyle('display','inline');
			
			if (this.options.enableDetail)
				this.images[i].addEvent('click', this.detailImage.bind(this).pass(i)).setStyle('cursor','pointer');

			if (this.options.enableHover)
			{
				this.images[i].addEvent('mouseover', this.hover.bind(this).pass(i)).setStyle('cursor','pointer');
				this.images[i].addEvent('mouseout', this.unhover.bind(this).pass(i)).setStyle('cursor','pointer');
			}
		}

		this.wrapper.adopt(this.leftBtn, this.carouselwrapper, this.rightBtn, cleardiv);

		var w_width = this.getElementWidth(this.wrapper);
		var lBtn_width = this.getElementWidth(this.leftBtn);
		var rBtn_width = this.getElementWidth(this.rightBtn);
		this.carouselwidth = w_width - lBtn_width - rBtn_width;
		this.carouselwrapper.setStyle('width', this.carouselwidth);
		
		this.maxRight = 0;
		this.grid = new Array();
		this.grid.push(0);
		for (var i=0; i<this.images.length; i++)
		{
			this.maxRight += this.getElementWidth(this.images[i]);
			this.grid.push(this.maxRight * -1);
		}
		this.maxRight -= this.carouselwidth;
		this.maxRight *= -1;
		
		this.leftBtn.addEvent(this.options.startevent, this.scrollLeft.bind(this));
		this.leftBtn.addEvent(this.options.endevent, this.stopScroll.bind(this));
		this.rightBtn.addEvent(this.options.startevent, this.scrollRight.bind(this));
		this.rightBtn.addEvent(this.options.endevent, this.stopScroll.bind(this));
		
		this.currentPos = this.options.initialLeft;
		this.fx = new Fx.Tween(this.carousel, {property: 'margin-left'});
	},
	
	scroll: function(dir) {
		var target;
		switch (dir) {
			case 'left': 	target = 0;
										this.dir = 1;
										this.leftBtn.setStyle('background-position','left bottom');
										break;
			case 'right':	target = this.maxRight;
										this.dir = -1;
										this.rightBtn.setStyle('background-position','left bottom');
										break;
		}
		this.fx.options.transition = new Fx.Transition(this.options.transIn).easeIn;
		this.fx.options.duration = Math.abs(this.currentPos-target)*this.options.speedfactor;
		this.fx.cancel().start(target);
	},
	
	scrollLeft: function() {
		this.scroll('left');
	},

	scrollRight: function() {
		this.scroll('right');
	},

	stopScroll: function() {
		this.currentPos = parseInt(this.carousel.getStyle('margin-left'));
		
		this.leftBtn.setStyle('background-position','left top');
		this.rightBtn.setStyle('background-position','left top');

		var brakeLength = this.options.brakeLength;
		
		if (this.options.snapToGrid)
		{
			var i;
			if (this.dir == 1) //Scroll Left
			{
				for (i=this.grid.length-1; i > 0 && this.grid[i] < this.currentPos; i--)
					;
				brakeLength = this.grid[i] - this.currentPos;
			}
			else if (this.dir == -1) //Scroll Right
			{
				for (i=0; i<this.grid.length && this.grid[i] > this.currentPos-this.carouselwidth; i++)
					;
				brakeLength = this.currentPos - (this.grid[i]+this.carouselwidth);
			}
		}
		
		this.fx.options.duration = brakeLength*this.options.speedfactor*3.25;
		this.fx.options.transition = new Fx.Transition(this.options.transOut).easeOut;
		
		var target = this.currentPos+(brakeLength*this.dir);
		if (target>0) target = 0;
		if (target<this.maxRight) target = this.maxRight;
		
		this.fx.cancel().start(target);
	},
		
	detailImage: function(i) {
		if (!this.images[i].detail)
		{
			if (this.options.modalDetail)
			{
				this.blockdiv = new Element('div').setStyles({
					'width':'100%',
					'height':'100%',
					'background-color':'black',
					'z-index':4,
					'position':'fixed',
					'left':0,
					'top':0,
					'opacity':0
				});
				$(document.body).grab(this.blockdiv);
				this.blockdiv.fx = new Fx.Tween(this.blockdiv,{property: 'opacity'}).start(0.6);
				this.blockdiv.addEvent('click', this.closeDetail.bind(this).pass(i));
			}
			
			var winsize = window.getSize();

			var busyimg = new Element('img',{'src':'assets/images/icons/busy_big.gif'});
			var detailimg =	new Element('img',{'src':this.images[i].alt}).setStyles({'display':'none'});

			var detail = this.images[i].detail = new Element('div').setStyles({
				'width':100,
				'height':120,
				'overflow':'hidden',
				'left':Math.round((winsize.x-100)/2),
				'top':Math.round((winsize.y-100)/2),
				'position':'fixed',
				'visibility':'visible',
				'z-index':5,
				'background-color':'#333',
				'color':'#FFF',
				'text-align':'center',
				'border-color':'#333',
				'border-style':'solid'	
			}).adopt(
				busyimg, 
				detailimg, 
				new Element('a',{
					'html':'Click to Close',
					'styles':{
						'color':'#FFF',
						'cursor':'pointer',
						'text-decoration':'none',
						'text-transform':'uppercase'
					}
				}).addEvent('click', function (e) {
					this.closeDetail.bind(this).pass(i); 
				}.bind(this))
			);
			detail.busy = busyimg;
			detail.image = detailimg;
			
			$(document.body).grab(detail);
			detail.addEvent('click', this.closeDetail.bind(this).pass(i));
			
			detail.fx = new Fx.Morph(detail);
			
			if (this.imageLoaded(detail.image))
			{
				this.startDetailMorph(i);
			}
			else
			{
				detail.image.addEvent('load',function () {
					this.startDetailMorph(i);
				}.bind(this));
			}
		}
		else
		{
			this.closeDetail(i);
		}
	},
	
	startDetailMorph: function (i) {
		var detail = this.images[i].detail;

		detail.busy.setStyle('display','none');

		detail.image.setStyles({'display':'block', 'visibility':'hidden'});
		var size = detail.image.getSize();
		var width, height;
		
		if ((size.x / size.y) > (this.options.maxDetailWidth / this.options.maxDetailHeight)) //Landscapier than max Values
		{
			width = this.options.maxDetailWidth;
			height = Math.round(this.options.maxDetailWidth * size.y / size.x);
		}
		else //Portrait
		{
			height = this.options.maxDetailHeight;
			width = Math.round(this.options.maxDetailHeight * size.x / size.y);
		}
		
		var bsize = window.getSize();
		
		var offsetTop = Math.round((bsize.y - height) / 2);
		var offsetLeft = Math.round((bsize.x - width) / 2);
		
		detail.image.setStyles({'visibility':'visible','height':height,'width':width});		
		
		detail.fx.start({
			'opacity':1,
			'left':offsetLeft,
			'top':offsetTop,
			'height':height+20,
			'width':width,
			'border-width':3
		});	
	},
	
	closeDetail: function(i) {
		var bsize = window.getSize();

		this.images[i].detail.fx.cancel().start({
			'opacity':0,
			'left':Math.round(bsize.x/2),
			'top':Math.round(bsize.y/2),
			'width':0,
			'height':0
		})
		.chain(this.images[i].detail.destroy)
		.chain(this.images[i].detail = null);

		if (this.blockdiv)
		{
			this.blockdiv.fx.cancel().start(0)
			.chain(this.blockdiv.destroy)
			.chain(this.blockdiv = null);
		}
	},
	
	hover: function(i) {
		new Fx.Morph(this.images[i],{'duration':100}).start({'opacity':0.75});
	},
	
	unhover: function(i) {
		new Fx.Morph(this.images[i],{'duration':100}).start({'opacity':1});
	},

	getElementWidth: function(ele) {
		var marginLeft = parseInt(ele.getStyle('margin-left'));
		var marginRight = parseInt(ele.getStyle('margin-right'));
		var paddingLeft = parseInt(ele.getStyle('padding-left'));
		var paddingRight = parseInt(ele.getStyle('padding-right'));
		var width = parseInt(ele.getStyle('width'));
		return (marginLeft + marginRight + paddingLeft + paddingRight + width);
	},
	
	imageLoaded: function(img) {
		if (!img.complete) 
			return false;

		if (typeof img.naturalWidth	!= 'undefined' && img.naturalWidth == 0)
			return false;

		return true;
	}
});