/*
 * jQuery Coverslide
 * 
 * Written By Clinton LaForest (http://www.thespiritx.com/)
 * 
 * Version .1
 * ----------
 * Setting up Structure and Functions
 */

(function(){
	var coverslide = function(element, options){
		var e = instance(element);
		setup(e);
		var images = $(instance.list[e]).find('img');
		coverslide.setup.images = images.length;
		$.each(images,function(key){
			var k = extract(this);
			process(k);
		});
		//if(window.console) console.log(elements.length);
		preloader(e);
		//if(window.console) console.log('go');
		cs.wait(e);
	};
	coverslide.load = function(e){
		$($(instance.list[e]).find('a')).hide().css({
			'position':'absolute'
		}).removeClass('current');
		
		$(instance.list[e]).append(ui.title());
		$(instance.list[e]).append(ui.author());
		$(instance.list[e]).find('.preloader').remove();
		//if(window.console) console.log('zero');
		arrange(e);
		//if(window.console) console.log('one');
		ui(e);
		//if(window.console) console.log('two');
		auto(e);
		//if(window.console) console.log('three');
	};
	coverslide.setup = {
		location: '/jquery/plugins/',
		folder: 'coverslide',
		length: 5,
		center: 0,
		animate: true,
		speed: 5000,
		auto: true,
		fontSize: 16,
		loaded: false,
		images: 0,
		preloaded: 0,
		waiting: 0
	};
	
	cs = {};
	cs.wait = function(e){
		//if(window.console) console.log([coverslide.setup.preloaded,coverslide.setup.images]);
		coverslide.setup.waiting++;
		if (coverslide.setup.preloaded == coverslide.setup.images) {
			$.each(elements, function(key){
				var href = link.create(instance.list[e], elements[key]);
				var img = image.create(href, elements[key], e+';'+key);
			});
		}else{
			if(coverslide.setup.waiting >= 0){
				setTimeout('cs.wait('+e+')',400);
			}else{
				if(window.console) console.log('Failed to load')
			}
				
		}
	};
	cs.update = function(key,value){
		if (value == '+1') {
			coverslide.setup[key]++;
		}
		else {
			coverslide.setup[key] = value;
		}
	};
	cs.change = function(key,dKey,value){
		var element = elements[key]; 
		element[dKey] = value;
		elements[key] = element;
		//if(window.console) console.log([element[dKey],key,dKey,value]);
		return element;
	}
	
	// RANDOM!!!
	var random = function(s,i){
		var str = '';
		for (x = 0; x < i; x++) {
			if(x>0) str += "_";
			for (y = 0; y < s; y++) 
				str += String(Math.floor(Math.random() * 10));
		}			
		return str;
	};
	
	var setup = function(e){
		var relArr = $(instance.list[e]).attr('rel').split(';;');
		$.each(relArr,function(dkey,dvalue){
			definition = dvalue.split('::');
			coverslide.setup[definition[0]] = definition[1];
		});
		return coverslide.setup;
	};
	
	// ADD SCROLLER TO INSTANCE LIST
	var instance = function(element){
		//if(window.console) console.log(element);
		var k = instance.list.length;
		instance.list[k] = element;
		return k;
	};
	instance.list = [];
	
	// GET ELEMENTS FOR COVER SLIDE
	var extract = function(element){
		var temp = {}, element = $(element)[0], k = elements.length;
		//if(window.console) console.log(element);
		temp.tagName = element.tagName;
		$.each($(element.attributes), function(index) {
			temp[element.attributes[index].name] = element.attributes[index].value;
		});
		temp.height = typeof temp.height=='undefined'?$(element).height():temp.height;
		temp.width = typeof temp.width=='undefined'?$(element).width():temp.width;
		//if(window.console) console.log([temp.height,temp.width]);
		if (temp.height == 0 && temp.width == 0) {
			$(element).load(function(){
				var k = $(this).data('key');
				cs.change(k, 'height', $(this).height());
				cs.change(k, 'width', $(this).width());
				cs.update('preloaded', '+1');
				$(this).remove();
			});
			$(element).css({'visibility':'hidden'});
			$(element).data('key',k);
		}else{
			coverslide.setup.preloaded++;
			$(element).remove();
		}
		elements[k] = temp;
		return k;
	};
	var elements = [];
	var process = function(key){
		var relArr = typeof elements[key].rel != 'undefined'?elements[key].rel.split(';;'):false,elm=elements[key];
		$.each(relArr,function(dkey,dvalue){
			definition = dvalue.split('::');
			elm[definition[0]] = definition[1];
		});
		elements[key].loaded = false;
		elements[key] = elm;
		
		return elm;
	};
	
	// CREATE CANVAS
	var canvas = {};
	canvas.create = function(to,from){
		if (!$.browser.msie) {
			var c = canvas.empty({
				width: from.width,
				height: from.height
				});
			$(to).append(c);
			return c[0].getContext("2d");
		}
		else {
			$(to).html('STOP RUNNING IE!');
			return false;
		}
	};
	canvas.empty = function(options){
		var options = options||{};
		options.id = typeof options.id=='undefined'?random(4,4):options.id;
		options.width = typeof options.width=='undefined'?100:options.width;
		options.height = typeof options.height=='undefined'?100:options.height;
		return $("<canvas/>").attr(options);
	};
	
	// CREATE LINKS
	var link = {};
	link.create = function(to,from){
		var a = link.empty({
			width: from.width,
			height: from.height,
			href: from.href
			});
		a.data('key',to);
		$(to).append(a);
		if (typeof jQT != 'undefined') a.addClass('forceSlide');
		return a;
	};
	link.empty = function(options){
		var options = options||{};
		options.id = typeof options.id=='undefined'?random(4,4):options.id;
		options.style = 'display:block;';
		options.style += 'position:absolute;';
		options.style += 'visibility:hidden;';
		options.style += typeof options.width=='undefined'||options.width==0?"width:auto;":"width:"+options.width+"px;";
		options.style += typeof options.height=='undefined'||options.height==0?"height:auto;":"height:"+options.height+"px;";
		options.style += typeof options.backgroundColor=='undefined'?"":"background-color:#"+options.backgroundColor+";";
		return $("<a/>").attr(options);
	};
	
	// CREATE PRELOADER
	var preloader = function(key){
		var preload = $('<img/>').addClass('preloader').css({
			'position': 'absolute',
			'width': 64,
			'height': 64,
			'margin-top': $(instance.list[key]).height()/2-32,
			'margin-left': $(instance.list[key]).width()/2-32
		}).attr({
			'src': coverslide.setup.location+coverslide.setup.folder+'/108.gif',
			'alt': 'Loading',
			'title': 'Loading'
		});
		$(instance.list[key]).append(preload);
		return true;
	};
	
	// CREATE IMAGE
	var image = {};
	image.create = function(to,from,info){
		var a = image.empty({
			width: from.width,
			height: from.height,
			alt: from.title,
			title: from.title,
			rel: info
			});
		a.load(function(){
			image.resize(this);
		});
		a.attr({src: from.src});
		$(to).append(a);
		return a;
	};
	image.empty = function(options){
		var options = options||{};
		options.id = typeof options.id=='undefined'?random(4,4):options.id;
		options.style = 'display:block;';
		options.style += typeof options.width=='undefined'||options.width==0?"width:auto;":"width:"+options.width+"px;";
		options.style += typeof options.height=='undefined'||options.height==0?"height:auto;":"height:"+options.height+"px;";
		options.style += typeof options.backgroundColor=='undefined'?"":"background-color:#"+options.backgroundColor+";";
		return $("<img/>").attr(options);
	};
	image.resize = function(element,options){
		//var csa = $(element).parents('div.coverslide'), cs = $(element).closest('div.coverslide')[0], pa = $(element).parent('a')[0], testvar = true, key = $(element).data('key');
		var rel = $(element).attr('rel');
		var relExplode = rel.split(';');
		var cs = instance.list[relExplode[0]], pa = $(element).parent('a')[0], testvar = true, key = relExplode[1];
		elements[key].loaded = true;
		//if(window.console) console.log(['in',elements[key].width,elements[key].height]);
		if($(element).width() > 0) elements[key].width = $(element).width();
		if($(element).height() > 0)elements[key].height = $(element).height();
		//if(window.console) console.log(['out',elements[key].width,elements[key].height]);
		$(pa).css({
			'width': elements[key].width,
			'height': elements[key].height
		});
		$(element).css({
			'width': elements[key].width,
			'height': elements[key].height
		});
		$.each(elements,function(){
			if(!this.loaded) testvar = false;
		});
		if(testvar) coverslide.load($.inArray(cs,instance.list));
	}
	
	// SET ARRANGEMENT
	var arrange = function(element,center,options){
		//if(window.console) console.log([element,instance.list[element],$(instance.list[element])]);
		var center = center || coverslide.setup.center, length = typeof options != 'undefined' ? options.length || coverslide.setup.length : coverslide.setup.length, show = [], covers = $(instance.list[element]).find('a');
		var side = (length-1)/2, num = covers.length;
		var length_center = Math.ceil(side);
		for(x=0;x<length;x++){
			if (x < length_center) {
				show[x] = center-(side-x)>=0?center-(side-x):num+(center-(side-x));
			}
			else 
				if (x == length_center) {
					show[x] = center;
				}
				else {
					show[x] = center+(x-side)<num?center+(x-side):center-(num-(x-side));
				}
		}
		
		$(covers).each(function(){
			$(this).css({
				'visibility': 'visible'
			});
		});
		
		if(coverslide.setup.animate){
			arrange.animation(element,side,length_center,show,covers);
		}else{
			arrange.noAnimation(element,side,length_center,show,covers);
		}
	};
	arrange.noAnimation = function(element,side,length_center,show,covers){
		var tkey = show[length_center];
		var margin = ($(instance.list[element]).width()-elements[tkey].width)/2;
		var margin_increment = margin/side; 
		
		$(covers).hide().css({
			'position':'absolute'
		}).removeClass('current');
		
		$.each(show,function(key,value){
			if (key < length_center) {
				$(covers[value]).show().css({
					'top': '0',
					'z-index': 5*key,
					'left': margin_increment*key
				});
				adjust.size(covers[value],Math.pow(1/length_center,length_center-key));
				adjust.margin(show[length_center],covers[value]);
			}
			else 
				if (key == length_center) {
					$(covers[value]).show().css({
						'top': '0',
						'z-index': '100',
						'left': margin
					}).addClass('current');
					adjust.size(covers[value],1);
					$($(instance.list[element]).find('.cover_title')).text(elements[value].title);
					$($(instance.list[element]).find('.cover_author')).text(elements[value].author);
				}
				else {
					$(covers[value]).show().css({
						'top': '0',
						'z-index': 5*(show.length-key-1),
						'left': $(instance.list[element]).width()-$(covers[value]).width()-margin_increment*(show.length-key-1)
					});
					adjust.size(covers[value],Math.pow(1/length_center,key-length_center));
					adjust.margin(show[length_center],covers[value]);
				}
		});
	};
	arrange.animation = function(element,side,length_center,show,covers){
		var tkey = show[length_center];
		var margin = ($(instance.list[element]).width()-elements[tkey].width)/2;
		var margin_increment = margin/side; 
		var cssBlock;
		
		$(covers).removeClass('current');
		
		$.each(covers,function(key,value){
			var skey = $.inArray(key,show);
			//if(window.console) console.log([key,covers[key]]);
			if (skey > -1) {
				if (skey < length_center) {
					$(covers[key]).css({
						'display': 'block',
						'z-index': 5 * skey
					});
					$(covers[key]).find('img').css({
						'position': 'relative',
						'z-index': 5 * skey
					});
					cssBlock = {
						opacity: '1',
						'top': '0',
						'left': margin_increment * skey
					};
					
					cssBlock = adjust.sizeReturn(cssBlock, covers[key], key, Math.pow(1 / length_center, length_center - skey));
					cssBlock = adjust.marginReturn(cssBlock, show[length_center], covers[key]);
					$(covers[key]).animate(cssBlock);
					$(covers[key]).find('img').animate({
						height: cssBlock.height,
						width: cssBlock.width
					});
				}
				else 
					if (skey == length_center) {
						$(covers[key]).css({
							'display': 'block',
							'z-index': '100'
						});
						$(covers[key]).find('img').css({
							'position': 'relative',
							'z-index': 100
						});
						cssBlock = {
							opacity: 1,
							'top': '0',
							'left': margin
						};
						$(covers[key]).addClass('current');
						cssBlock = adjust.sizeReturn(cssBlock, covers[key], key, 1);
						$(covers[key]).animate(cssBlock);
						$(covers[key]).find('img').animate({
							height: cssBlock.height,
							width: cssBlock.width
						});
						$($(instance.list[element]).find('.cover_title')).text(elements[key].title);
						$($(instance.list[element]).find('.cover_author')).text(elements[key].author);
					}
					else {
						$(covers[key]).css({
							'display': 'block',
							'z-index': 5 * (show.length - skey - 1)
						});
						$(covers[key]).find('img').css({
							'position': 'relative',
							'z-index': 5 * (show.length - skey - 1)
						});
						cssBlock = {
							opacity: 1,
							'top': '0'
						}
						cssBlock = adjust.sizeReturn(cssBlock, covers[key], key, Math.pow(1 / length_center, skey - length_center));
						cssBlock = adjust.marginReturn(cssBlock, show[length_center], covers[key]);
						cssBlock.left = $(instance.list[element]).width()-cssBlock.width-margin_increment*(show.length-skey-1);
						$(covers[key]).animate(cssBlock);
						$(covers[key]).find('img').animate({
							height: cssBlock.height,
							width: cssBlock.width
						});
					}
			}
			else {
				$(covers[key]).css({
					'display':'none',
					opacity: 0
				});
			}
		});
	};
	
	// ADJUSTMENT FUNCTIONS
	var adjust = {};
	adjust.size = function(element,percent){
		var img = $(element).find('img');
		var key = $(img).data('key');
		$(img).width(elements[key].width*percent);
		$(img).height(elements[key].height*percent);
		$(element).width(elements[key].width*percent);
		$(element).height(elements[key].height*percent);
		return true;
	};
	adjust.margin = function(adjustby,element,side){
		var side = side||'top';
		switch(side){
			case 'top':
			case 'bottom':
				var size = (elements[adjustby].height-$(element).height())/2;
				$(element).css({'top':size+'px'});
			default:
				return false;
		}
	};
	adjust.sizeReturn = function(cssBlock,element,key,percent){
		var img = $(element).find('img')[0];
		var key = key===false?$(img).data('key'):key;
		//if(window.console) console.log([key,element,img,elements[key]])
		cssBlock['width'] = elements[key].width*percent;
		cssBlock['height'] = elements[key].height*percent;
		return cssBlock;
	};
	adjust.marginReturn = function(cssBlock,adjustby,element,side){
		var side = side||'top';
		switch(side){
			case 'top':
			case 'bottom':
				var size = (elements[adjustby].height-cssBlock.height)/2;
				cssBlock['top'] = size+'px';
				break;
			default:
				break;
		}
		return cssBlock;
	};
	
	// UI ELEMENTS
	var ui = function(element){
		var mid = $(instance.list[element]).find('.current')[0];
		var margin = ($(instance.list[element]).width()-$(mid).width())/2, height = $(mid).height();
		$(instance.list[element]).append(ui.progress(element,'backward').css({
			'width': margin + 'px',
			'height': height + 'px',
			'line-height': height + 'px',
			'top': 0,
			'left': 0
		}));
		$(instance.list[element]).append(ui.progress(element,'forward').css({
			'width': margin + 'px',
			'height': height + 'px',
			'line-height': height + 'px',
			'top': 0,
			'right': 0
		}));
	};
	ui.progress = function(instance,direction){
		var direction = direction||'forward', wrapper = $('<div/>').css({'background':'url('+coverslide.setup.location+coverslide.setup.folder+'/pixel.gif)','z-index':'250','position':'absolute','text-align':'center',cursor:'pointer'}), button = {};
		wrapper.data('instance', instance);
		switch(direction){
			case 'next':
			case 'forward':
				button = $('<img/>').attr({
					src: coverslide.setup.location+coverslide.setup.folder+'/next.png',
					alt: 'Next',
					title: 'Next',
					align: 'center'
				});
				wrapper.click(function(){
					move($(this).data('instance'),1);
				});
				break;
			case 'previous':
			case 'backward':
			default:
				button = $('<img/>').attr({
					src: coverslide.setup.location+coverslide.setup.folder+'/previous.png',
					alt: 'Next',
					title: 'Next',
					align: 'center'
				});
				wrapper.click(function(){
					move($(this).data('instance'),-1);
				});
				break;
		}
		button.css({'visibility':'hidden','position':'relative','margin':'110px 0'});
		wrapper.hover(function(){
			$(this).find('img').css({
				'visibility': 'visible'
			});
		},function(){
			$(this).find('img').css({
				'visibility': 'hidden'
			});
		});
		return wrapper.append(button);
	};
	ui.title = function(){
		var wrapper = $('<div/>').css({
			'width': '100%',
			'height': '40px',
			'position': 'absolute',
			'bottom': '0px',
			'left': '0',
			'text-align': 'center',
			'font-weight': 'bold',
			'line-height': '20px',
			'font-size': coverslide.setup.fontSize+'px'
		}).addClass('cover_title');
		wrapper.text('Title Goes Here');
		return wrapper;
	};
	ui.author = function(){
		var wrapper = $('<div/>').css({
			'width': '100%',
			'height': '20px',
			'position': 'absolute',
			'bottom': '0',
			'left': '0',
			'text-align': 'center',
			'line-height': '20px',
			'font-size': coverslide.setup.fontSize+'px',
			'display': 'none'
		}).addClass('cover_author');
		wrapper.text('Author Goes Here');
		return wrapper;
	};
	
	// MOVEMENT
	coverslideMove = function(key,movement){
		var covers = $(instance.list[key]).find('a'), next = 0;
		var len = covers.length;
		if ($.inArray($(instance.list[key]).find('a.current')[0], covers) + movement >= len) {
			next = movement - (len - $.inArray($(instance.list[key]).find('a.current')[0], covers));
		}
		else 
			if ($.inArray($(instance.list[key]).find('a.current')[0], covers) + movement < 0) {
				next = len + movement;
			}
			else {
				next = $.inArray($(instance.list[key]).find('a.current')[0], covers) + movement;
			}
		arrange(key, next);
	};
	var move = coverslideMove;
	
	// AUTO ROTATE
	auto = function(key){
		auto.intervals[key] = setInterval("coverslideMove("+key+",1)", coverslide.setup.speed);
	};
	auto.intervals = [];
	
	jQuery.fn.coverslide = function(options){
		var m = null;
		if(typeof coverslide != 'undefined'){
			this.each(function(){
				coverslide(this, options);
			});
		}
		return this || m;
	};
	$(document).ready(function() {
		$('.coverslide').coverslide();
	});
})();
