﻿/*    9/28/2009		PikaChoose	Jquery plugin for photo galleries    Copyright (C) 2009 Jeremy Fry    This program is free software: you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation, either version 3 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program.  If not, see <http://www.gnu.org/licenses/>.*/jQuery.iPikaChoose = {	build : function(user_options)	{		var defaults = {			show_captions: false,			slide_enabled: false,			auto_play: false,			show_prev_next: true,			slide_speed: 500000,			thumb_width: 90,			thumb_height: 60,			buttons_text: { play: "", stop: "", previous: "", next: "" },			delay_caption: true,			user_thumbs: false,			transition:[-1]		};		return jQuery(this).each(			function() {				function LoadImages()				{					var image = jQuery(this);					//clone so the on loads will fire correctly					var aParent = jQuery(this).parent('a');					if(aParent.length == 0){ aParent = jQuery(this); }					jQuery(this).attr('pikaLink', aParent.attr('href'));					var newImage = jQuery(this).clone(true).insertAfter(aParent);					jQuery(this).bind("load",function(){ aParent.remove(); });					aParent.hide();					image = newImage;					jQuery('<img />').attr('src',image.attr('src')).load(function()					{						//had to make a seperate function so that the thumbnails wouldn't have problems						//from beings resized before loaded, thus not h/w						var w = image.width();						var h = image.height();						if(w===0){w = image.attr("width");}						if(h===0){h = image.attr("height");}						//grab a ratio for image to user defined settings						var rw = options.thumb_width/w;						var rh = options.thumb_height/h;												//determine which has the smallest ratio (thus needing						//to be the side we use to scale so our whole thumb is filled)						var ratio;						if(rw<rh){							//we'll use ratio later to scale and not distort							ratio = rh;							var left = ((w*ratio-options.thumb_width)/2)*-1;							left = Math.round(left);							//set images left offset to match							image.css({left:left});						}else{							ratio = rw;							//you can uncoment this lines to have the vertical picture centered							//but usually tall photos have the focal point at the top...							//var top = ((h*ratio-options.thumb_height)/2)*-1;							//var top = Math.round(top);							var top = 0;							image.css({top:top});						}						//use those ratios to calculate scale						var width = Math.round(w*ratio);						var height = Math.round(h*ratio);						image.css("position","relative");						image.width(width).height(height);						var imgcss={							width: width,							height: height						};						image.css(imgcss);											image.hover(							function(){jQuery(this).fadeTo(250,1);},							function(){if(!jQuery(this).hasClass("pika_selected")){jQuery(this).fadeTo(250,0.4);}}						);						image.fadeTo(250,0.4);													if(image.hasClass('pika_first')){							image.trigger("click",["autoFirst"]);						}						images = ulist.children('li').find('img:last');					});										//reset images to the clones					images = ulist.children('li').find('img:last');				}				//bring in options				var tranStep = 0;				var options = jQuery.extend(defaults, user_options);				// grab our images				var images = jQuery(this).children('li').find('img');				//hide the images so the user doesn't see crap				images.hide();								//save our list for future ref				var ulist = jQuery(this);				images.each(LoadImages);				//start building structure				jQuery(this).before("<div class='pika_main'></div>");				// houses eveything about the UL				var main_div = jQuery(this).prev(".pika_main");								//add in slideshow elements when appropriate				if(options.slide_enabled){					main_div.append("<div class='pika_play'></div>");					var play_div = jQuery(this).prev(".pika_main").children(".pika_play");					play_div.html("<a class='pika_play_button'>" + options.buttons_text.play + "</a><a class='pika_stop_button'>" + options.buttons_text.stop + "</a>");					play_div.fadeOut(1);					var play_anchor = play_div.children('a:first');					var stop_anchor = play_div.children('a:last');				}				//this div is used to make image and caption fade together				main_div.append("<div class='pika_subdiv'></div>");				var sub_div = main_div.children(".pika_subdiv");				//the main image we'll be using to load				var firstImage = ulist.find("img:first");				if(options.user_thumbs)				{							firstImage = firstImage.attr('ref');				}else				{					firstImage = firstImage.attr('src');				}												sub_div.append("<img class='pika_main_img' src='"+firstImage+"' />");				sub_div.append("<div class='pika_animationDivs'>");				var ani_divs = sub_div.find(".pika_animationDivs");				ani_divs.css({'position':'absolute','width':'100%','height':'100%'});				var y = 0;				var x = 0;				for(var t = 0; t<100;t++)				{					var a = '<div col="'+y+'" row="'+x+'"></div>';					ani_divs.append(a);					y++					if(y == 10)					{						x++;						y=0;					}				}				ani_divs.children(':last').addClass("pikaLastAni");				var main_img = sub_div.children("img");								//build custom overlays. These will use navigation div				sub_div.append("<div class='pika_prev_hover'></div><div class='pika_next_hover'></div>");				var prevHover = sub_div.find('.pika_prev_hover');				var nextHover = sub_div.find('.pika_next_hover');				prevHover.hide();				nextHover.hide();				//create the caption div when appropriate				if(options.show_captions){					main_div.append("<div class='pika_caption'></div>");					var caption_div = main_div.children(".pika_caption");				}								//navigation div ALWAYS gets created, its refrenced a lot								jQuery(this).after("<div class='pika_navigation'></div>");				var navigation_div = jQuery(this).next(".pika_navigation");				//fill in sub elements				navigation_div.prepend("<a>" + options.buttons_text.previous + "</a> <a>" + options.buttons_text.next + "</a>");				var previous_image_anchor = navigation_div.children('a:first');				var next_image_anchor = navigation_div.children('a:last');								//hide the navigation if the user doesn't want it				if(!options.show_prev_next){					navigation_div.css("display","none");				}								//playing triggers the loop for the slideshow				var playing = options.auto_play;				var animating = false;				main_img.wrap("<a></a>");				var main_link = main_img.parent("a");							function activate()			{				//sets the intial phase for everything								//image_click is controls the fading				images.bind("click",image_click);				//hiding refrence to slide elements if slide is disabled				if(options.slide_enabled){					if(options.auto_play){						playing = true;						play_anchor.hide();						stop_anchor.show();					}else{						play_anchor.show();						stop_anchor.hide();					}				}								ulist.children("li:last").children("img").addClass("pika_last");				ulist.children("li:first").children("img").addClass("pika_first");				ulist.children("li").each(function(){ jQuery(this).children("span").hide(); });				//css for the list				var divcss = {					width: options.thumb_width+"px",					height: options.thumb_height+"px",					"list-style": "none",					overflow: "hidden"				};				var licss = {					"list-style": "none",					overflow: "hidden"				};				images.each(function(){					jQuery(this).parent('li').css(licss);					jQuery(this).wrap(document.createElement("div"));					jQuery(this).parent('div').css(divcss);					//jQuery(this).parent('li').css(licss);					//fixes a bug where images don't get the correct display after loading					if(jQuery(this).attr('complete')===true && jQuery(this).css('display')=="none")					{						jQuery(this).css({display:'inline'});					}				});				//previous link to go back an image				previous_image_anchor.bind("click",previous_image);				prevHover.bind("click",previous_image);				//ditto for forward, also the item that gets auto clicked for slideshow				next_image_anchor.bind("click",next_image);				nextHover.bind("click",next_image);									//enable mouse tracking for the hover				sub_div.mousemove(function(e){					var w = sub_div.width();					var x = e.pageX - sub_div.offset().left;      			if(x<w*0.3)      			{      				prevHover.fadeIn('fast');      			}else{     					prevHover.fadeOut('fast');     				}      			if(x>w*0.7)      			{      				nextHover.fadeIn('fast');	      			}else{      				nextHover.fadeOut('fast');	      			}   			});   			sub_div.mouseleave(function(){ prevHover.fadeOut('fast');nextHover.fadeOut('fast'); });			}//end activate function						function Gapper(ele, aHeight)			{				if(ele.attr('row') == 9 && ele.attr('col') == 0)				{					//last row, check the gap and fix it!					var gap = ani_divs.height()-(aHeight*9);					return gap;				}				return aHeight;			}									function AnimateImage(image_source, image_link,how)			{				//main_img.hide();				jQuery('<img />').load(function()				{					//ready for some lame sauce? if ie fuck all the cool stuff, because it's too slow					//I'm waiting on you IE 9!					if(jQuery.browser.msie)					{						ani_divs.height(main_img.height()).css({'background':'url('+image_source+') top left no-repeat'});						ani_divs.children('div').hide();						ani_divs.fadeIn('slow',function(){							FinishedAnimating(image_source,image_link);						});						return;					}					ani_divs.height(main_img.height()).show();					ani_divs.children('div').css({'width':'10%','height':'10%','float':'left'});					var aWidth = ani_divs.children('div:first').width();					var aHeight = ani_divs.children('div:first').height();					if(how!="autoFirst"){						ani_divs.children().each(function()						{							//position myself absolutely							var div = jQuery(this);							var xOffset = Math.floor(div.parent().width()/10)*div.attr('col');							var yOffset = Math.floor(div.parent().height()/10)*div.attr('row');							div.css({								'background':'url('+image_source+') -'+xOffset+'px -'+yOffset+'px',								'width':'0px',								'height':'0px',								'position':'absolute',								'top':yOffset+'px',								'left':xOffset+'px',								'float':'none'							});						});//end ani_divs.children.each					}					//decide our transition					var n = 0;					if(options.transition[0] == -1)					{	//random						//DWH n = Math.floor(Math.random()*4);						n=0;					}else{						n = options.transition[tranStep];						tranStep++;						if(tranStep >= options.transition.length){tranStep=0;}					}					//var n = 4;					switch(n)					{						case 0:							ani_divs.children().hide().each(function(index)							{								aHeight = Gapper(jQuery(this),aHeight);								jQuery(this).css({"width":aWidth,"height":aHeight}).fadeIn(800,function()								{									if(jQuery(this).hasClass('pikaLastAni'))									{										FinishedAnimating(image_source,image_link);									}								});							});							break;						case 1:							ani_divs.children().each(function(index)							{								var delay = index*10;								jQuery(this).delay(delay).animate({"width":aWidth,"height":aHeight},800,'linear',function()								{									if(jQuery(this).hasClass('pikaLastAni'))									{										FinishedAnimating(image_source,image_link);									}								});							});							break;						case 2:							ani_divs.children().hide().each(function(index)							{								var delay = jQuery(this).attr('row')*10;								jQuery(this).css({"width":aWidth}).delay(delay).animate({"height":aHeight},800,'linear',function()								{									if(jQuery(this).hasClass('pikaLastAni'))									{										FinishedAnimating(image_source,image_link);									}								});							});							break;												case 3:							ani_divs.children().hide().each(function(index)							{								var delay = jQuery(this).attr('col')*10;								aHeight = Gapper(jQuery(this), aHeight);								jQuery(this).css({"height":aHeight}).delay(delay).animate({"width":aWidth},800,'linear',function()								{									if(jQuery(this).hasClass('pikaLastAni'))									{										FinishedAnimating(image_source,image_link);									}								});							});							break;					}				}).attr('src',image_source);//end image preload			}// end animate images						function FinishedAnimating(image_source,image_link)			{				animating = false;				main_img.attr("src", image_source);				if(image_link == null){image_link = "#"}				main_link.attr("href", image_link);				ani_divs.children().css({"background":"transparent"});				ani_divs.hide();				if(playing)				{					main_img.animate({opacity:1},options.slide_speed, function()					{						//redudency needed here to catch the user clicking on an image during a change.						if(playing){next_image_anchor.trigger("click",["auto"]);}					});				}			}			function image_click(event, how){					//catch when user clicks on an image Then cancel current slideshow					if(jQuery(this).hasClass('pika_selected') || animating){ return; }					if(how!="auto" && how!="autoFirst"){						animating = true;						if(options.slide_enabled){							stop_anchor.hide();							play_anchor.show();							playing=false;						}						main_img.stop().dequeue();						if(options.show_captions)						{							caption_div.stop().dequeue();						}					}					//all our image variables					var image_source = "";					if(options.user_thumbs)					{								image_source = jQuery(this).attr("ref");					}else					{						image_source = this.src;					}					//thumbnail animations					var image_link = jQuery(this).parent("a").attr("href");					var image_caption = jQuery(this).parent().next("span").html();					//fade out the old thumb					images.filter(".pika_selected").fadeTo(250,0.4); 					images.filter(".pika_selected").removeClass("pika_selected"); 					//fade in the new thumb					jQuery(this).fadeTo(250,1);					jQuery(this).addClass("pika_selected");					//fade the caption out					if(options.show_captions)					{						if(options.delay_caption)						{							caption_div.fadeTo(800,0);						}						caption_div.fadeTo(500,0,function(){							caption_div.html(image_caption);							caption_div.fadeTo(800,1);						});					}					AnimateImage(image_source, image_link, how);			}//end image_click function						function next_image(event, how){				if(images.filter(".pika_selected").hasClass("pika_last")){					images.filter(":first").trigger("click",how);				}else{					images.filter(".pika_selected").parents('li').next('li').find('img').trigger("click",how);				}			}//end next image function						function previous_image(event, how){				if(images.filter(".pika_selected").hasClass("pika_first")){					images.filter(":last").trigger("click",how);				}else{					images.filter(".pika_selected").parents('li').prev('li').find('img').trigger("click",how);				}			}//end previous image function						function play_button(){				main_div.hover(					function(){play_div.fadeIn(400);},					function(){play_div.fadeOut(400);}				);				play_anchor.bind("click", function(){					main_img.stop();					main_img.dequeue();					if(options.show_captions)					{						caption_div.stop();						caption_div.dequeue();					}					playing = true;					next_image_anchor.trigger("click",["auto"]);					jQuery(this).hide();					stop_anchor.show();				});				stop_anchor.bind("click", function(){					playing = false;					jQuery(this).hide();					play_anchor.show();				});			}			if(options.slide_enabled){play_button();}			activate();		});//end return this.each	}//end build function		//activate applies the appropriate actions to all the different parts of the structure.	//and loads the sets the first image};//end jquery.ipikachoose		jQuery.fn.PikaChoose = jQuery.iPikaChoose.build;
