/*!
 *	Fancy Carousel jQuery Plugin
 *	Developed By: Jemco Logics, Inc
 *	Version: 1.0.0
 *	Date: Tue Jul 19 14:16:56 2011 -0500
 *
 */
 
 (function($) {
	//define plugin options default values
	var def = {
		speed: 'normal',
		maskColor: '#171717',
		maskOpacity: 85,
		width: 385,
		scale: 40,
		height: 275,
		winWidth: 930,
		displayMax: 7,
		showTitle: true,
		useLinks: true,
		titleColor: '#FFFFFF',
		titleFontSize: 14,
		titleAlign: 'center',
		background: '#171717'
	};
	
	//define a container to store calculated properties
	var prop = { 
		//create some namespacing
		gallery: { },
		current: { },
		controls: { }
	};
	
	//define plugin methods
	var fc = {
		//intialize gallery
		initProp: function() {
			//gallery properties
			prop.gallery.HCenter = Math.floor( def.winWidth / 2 );
			prop.gallery.VCenter = Math.floor( def.height / 2 );
			prop.gallery.scaleRate = ( 100 - def.scale ) / Math.floor( def.displayMax / 2 ) ;
			prop.gallery.lOffset = Math.floor( def.winWidth / ( def.displayMax + 1 ) );
			prop.gallery.pivot = Math.ceil( prop.gallery.size / 2 ); //initial array pivot point, will be adjusted as user traverses gallery
			prop.gallery.furthest = prop.gallery.pivot - 1;
			//current image properties
			prop.current.index = 0; //collection index of image
			prop.current.top = 0;
			prop.current.right = prop.gallery.HCenter + Math.floor( def.width / 2 );
			prop.current.bottom = 0;
			prop.current.left = prop.gallery.HCenter - Math.floor( def.width / 2 );
			prop.current.zIndex = Math.ceil( prop.gallery.size / 2 ) * 5;
			//control settings
			prop.controlWidth = Math.floor( def.winWidth / 2 ) - Math.floor( def.width / 2 );
			prop.maskOpacity = fc.toPercentDecimal( def.maskOpacity );
			prop.maskZIndex = prop.current.zIndex + 10
			prop.btnZIndex = prop.maskZIndex + 5;
			prop.titleZIndex = prop.maskZIndex;
			prop.btnOpacity = 0.3;
			
		},
		initGallery: function( images, title) {
			//set current image, start with first in list
			images.each(function(i) {
				//set current image
				var adj = fc.getAdjacentProp(i),
				img = $(this);
				img.css({
					'width': adj.width,
					'height': adj.height,
					'top': adj.top,
					'left': adj.left,
					'z-index': adj.zIndex
				});

				if ( i === prop.current.index && def.showTitle) {
					fc.setTitle( img, title );
				}
				
				//wrap links around images
				if ( def.useLinks && typeof( img.attr('longdesc') ) !== 'undefined' && img.attr('longdesc') !== false ) {
					img.wrap( '<a href="' + img.attr('longdesc') + '" style="text-decoration: none; color: ' + def.titleColor + '">' );
				}
				
			});
			
			
		},
		slideGallery: function( images, title, dir ) {
			var clicks, fn, btn;
			
			if (dir === 'next' ) { 
				btn = prop.controls.btnRight;
			}
			else if (dir === 'prev' ) {
				btn = prop.controls.btnLeft;
			}
			
			clicks = btn.data('events').click;
			$.each(clicks, function( i, f ) {
				fn = f;
				return false;
			});
			
			btn.unbind('click');  //unbind cick handler to avoid click excesive clicking
				
			images.each(function(i) {
				var adj = fc.getAdjacentProp(i);
				var img = $(this);
				
				img.css({ 'z-index': adj.zIndex });
				
				if( ( adj.offset === -prop.gallery.furthest && dir === 'next' ) || ( adj.offset === prop.gallery.furthest && dir === 'prev' ) ) {
					img.css({
						'width': adj.width,
						'height': adj.height,
						'top': adj.top,
						'left': adj.left
					});
				}
				else {
				img.animate({
						'width': adj.width,
						'height': adj.height,
						'top': adj.top,
						'left': adj.left
				}, def.speed );
				
				}
				
				if ( i === prop.current.index && def.showTitle) {
					fc.setTitle( img, title );
				}
			}); 
			images.promise().done( function() {
				if ( btn ) {
					btn.click( fn );
				}
			});
			//console.log('----------------------------------------------------------');
			title.css({'opacity':0}).fadeTo( def.speed, 1 );
		},
		//calculate adjacent image dimensions and position
		getAdjacentProp: function ( n ) {
			var adj = {
				width: def.width,
				height: def.height,
				top: prop.current.top,
				left: prop.current.left,
				zIndex: prop.current.zIndex,
				offset: 0
			},
			offset = 0,
			pivot = prop.gallery.pivot; //position away from current index
			
			//adjust offset for transversing the array
			if ( n > prop.current.index ) {
				if ( n < prop.gallery.pivot ) { 
					offset = ( n - prop.current.index );
				} else {
					if ( prop.gallery.pivot < prop.current.index ) {
						offset = ( n - prop.current.index );
					} else {
						offset = ( n - prop.gallery.size - prop.current.index );
					}
				}
			} else { 
				if ( n < prop.gallery.pivot ) {
					if ( prop.gallery.pivot < prop.current.index ) {
						offset = ( prop.gallery.size - prop.current.index + n );
					} else {
						offset = ( n - prop.current.index );
					} 
				} else {
					if ( prop.gallery.pivot < prop.current.index ) {
						offset = ( n - prop.current.index );
					} else {
						offset = ( prop.current.index - n );
					}
				}
			}

			if ( n !== prop.current.index ) {
				adj.width = Math.floor( def.width - ( prop.gallery.scaleRate * Math.abs( offset ) ) );
				adj.height = Math.floor( def.height - ( prop.gallery.scaleRate * Math.abs( offset ) ) );
				adj.top = Math.floor( prop.gallery.VCenter - ( adj.height / 2 ) );
				adj.left = Math.floor( prop.gallery.HCenter + ( offset * prop.gallery.lOffset ) - ( adj.width / 2 ) );
				adj.offset = offset;
				
				if ( offset === -prop.gallery.furthest) { adj.zIndex = 1; }
				else {
					adj.zIndex = prop.current.zIndex - ( Math.abs( offset ) * 5 );
				}
	
			}
			
			//console.log('current: ' + prop.current.index + ' index: '+n+' pivot: '+prop.gallery.pivot+' offset: '+offset+' left: ' + adj.left + ' z: ' + adj.zIndex);
			return adj; //return adjacent property object
			
			
		},
		//convert percentage to decimal representation
		toPercentDecimal: function( n ) {
			var abs = Math.abs(n);
			if ( abs > 100 ) { return 1; }
			else if ( abs < 1 ) { return abs; }
			else { return (abs / 100); }
		},
		//set title / link
		setTitle: function ( img, title ) {
			if ( def.useLinks && typeof( img.attr('longdesc') ) !== 'undefined' && img.attr('longdesc') !== false ) {
				title.html( '<a href="' + img.attr('longdesc') + '" style="text-decoration: none; color: ' + def.titleColor + '">' + img.attr('alt') + '</a>' );
			} else {
				title.text( img.attr('alt') );
			}
		}
	};
	
	//add plugin to jQuery
	$.fn.fancyCarousel = function( options ) {
		//overwrite option defaults with option values
		$.extend(def, options);
		//define local gallery container
		var gallery = this,
		//define local image wrapper
		wrapper = $('#fcImages');
		//add wrapper if it does not exist
		if (wrapper.length === 0) {
			wrapper = gallery.children('img').wrapAll('<div id="fcImages" >').parent();
		}
		//define local image array object
		var images = wrapper.children('img');
		prop.gallery.size = images.length;
		
		//adjust array to meet criteria (odd number )
		if ( prop.gallery.size > 1 ) {
			//even number of images
			if ( prop.gallery.size % 2 === 0 ) {
				wrapper.find( 'img:eq(1)' ).clone( true ).appendTo( wrapper );
				images = wrapper.children('img');
				prop.gallery.size = images.length;
			}
			
			//update display max if not enough images
			if ( prop.gallery.size < def.displayMax ) {
				def.displayMax = prop.gallery.size;
			}
		}
		//define local control elements
		var maskLeft = gallery.append('<div id="fcMaskLeft" >').find(':last'),
		maskRight = gallery.append('<div id="fcMaskRight" >').find(':last'),
		btnLeft = gallery.append('<a id="fcBtnLeft" href="javascript:void(0)" class="btnLeft">PREV</a>').find(':last'),
		btnRight = gallery.append('<a id="fcMaskRight" href="javascript:void(0)" class="btnRight">NEXT</a>').find(':last'),
		titleBar = gallery.append('<div id="fcTitleBar" >').find(':last');
		
		//expose buttons
		prop.controls.btnLeft = btnLeft;
		prop.controls.btnRight = btnRight;
		
		//calculate all inital prop values
		fc.initProp();

		//Apply styles
		if ( def.showTitle ) {
			titleBar.text('TITLE');
			titleBar.css({ position: 'absolute', 'bottom': 0, 'left': 0, 'width': def.winWidth, 'z-index': prop.titleZIndex, 'padding': 10, 'font-weight': 'bold', 'color': def.titleColor, 'font-size': def.titleFontSize, 'text-align': def.titleAlign });
		}
		wrapper.css({ 'position': 'relative', 'width': def.winWidth, 'height': def.height, 'overflow': 'hidden', 'z-index': 1 });
		gallery.css({ 'position': 'relative', 'overflow': 'hidden', 'background': def.background, 'height': def.height+ titleBar.outerHeight(), 'width': def.winWidth, 'z-index': 1 });
		maskLeft.css({ 'width': prop.controlWidth, 'height': def.height, 'position': 'absolute', 'background': def.maskColor, 'opacity': prop.maskOpacity, 'z-index': prop.maskZIndex, 'top': 0, 'left': 0 });
		maskRight.css({ 'width': prop.controlWidth, 'height': def.height, 'position': 'absolute', 'background': def.maskColor, 'opacity': prop.maskOpacity, 'z-index': prop.maskZIndex, 'top': 0, 'right': 0 });
		btnLeft.css({ 'width': prop.controlWidth, 'height': def.height, 'position': 'absolute', 'z-index': prop.btnZIndex, 'top': 0, 'left': 0, 'opacity': prop.btnOpacity });
		btnRight.css({ 'width': prop.controlWidth, 'height': def.height, 'position': 'absolute', 'z-index': prop.btnZIndex, 'top': 0, 'right': 0, 'opacity': prop.btnOpacity });
		images.css({ 'position': 'absolute' });
		
		//setup gallery
		fc.initGallery( images, titleBar );
		
		//define event handlers
		btnRight.mouseover(function() {
			$(this).fadeTo(200, 1);
		});
		
		btnRight.mouseout(function() {
			$(this).fadeTo(200, prop.btnOpacity);
		});
		
		btnLeft.click(function() {
			this.blur();
			(prop.current.index < prop.gallery.size-1) ? prop.current.index++ : prop.current.index = 0;
			(prop.gallery.pivot < prop.gallery.size) ? prop.gallery.pivot++ : prop.gallery.pivot = 1;
			fc.slideGallery(images, titleBar, 'prev');
			return false;
		});
		
		btnRight.click(function() {
			this.blur();
			(prop.current.index > 0) ? prop.current.index-- : prop.current.index = prop.gallery.size-1;
			(prop.gallery.pivot-1 > 0) ? prop.gallery.pivot-- : prop.gallery.pivot = prop.gallery.size;
			fc.slideGallery(images, titleBar, 'next' );
			return false;
		});
		
		btnLeft.mouseover(function() {
			$(this).fadeTo(200, 1);
		});
		
		btnLeft.mouseout(function() {
			$(this).fadeTo(200, prop.btnOpacity);
		});
		
		
		
		//return object for chaining
		return this;
	};
 })(jQuery);
