/*!
 * jTimeLine, version 1
 *
 * Copyright (c) 2010 Developed by Eric Stafford
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * Built on top of the jQuery library
 *   http://jquery.com
 *
 */

(function($) {
	jQuery.fn.timeline = function(options) {
		var defaults = {
			bubbleContainer : "#bubbles",
			bubble : ".bubble",
			yearBlock : ".yearBlock",
			leftButton : "#tlLeftButton",
			rightButton : "#tlRightButton",
			slides : "",
			ulWidth : 0,
			slideCount : 0,
			ulLeft : 0,
			clicks : 1,
			cell : "",
			lastCell : "",
			currentYear : "",
			liPos : 0,
			liWidth : 0
		},
		settings = jQuery.extend({}, defaults, options);
	 	
		this.each(function() {
			var $this = jQuery(this),
				ulContainer = "#" + $this.attr("id"),
				totalWidth = 0;				
				
				settings.slideCount = $this.find("li").length;
				
			if($this.is('ul'))
			{	
				// Builds out the shadows and buttons, Nav		
				jQuery(ulContainer).wrap("<div id=\"tlSlideContainer\"></div>");
				jQuery(ulContainer).parent().before("<div id=\"tlSlideNav\"></div><div id=\"tlShadowLeft\"></div><div id=\"tlShadowRight\"></div><div id=\"tlLeftButton\"></div><div id=\"tlRightButton\"></div><div id=\"bubbles\"></div>");
				
				// Adds the slides to the nav				
				jQuery("#tlSlideNav").append(buildTimeline(settings.yearSlides));
				
				// Creates a way to reference the li from the id ulContainer represents
				settings.slides = ulContainer + " li";
				
				// Retrieves the total width of a single li
				settings.liWidth = parseInt(jQuery(settings.slides).width()) + parseInt(jQuery(settings.slides).css('paddingLeft').replace("px", "")) + parseInt(jQuery(settings.slides).css('paddingRight').replace("px", ""));
				
				// Gets the total width of all the lis and applies it to the ulWidth variable
				$this.find("li").each(function(){
					settings.ulWidth += settings.liWidth;
				});		
				
				$this.css({"width":settings.ulWidth});
				
				// Controls all the animation when the timeline cell is clicked
				jQuery(settings.yearBlock).find("a").click(function(e){
						e.preventDefault();
						jQuery(this).addClass("active");
						jQuery(this).siblings().removeClass("active");
						jQuery(this).parent().siblings().find("a").removeClass("active");
						settings.clicks = parseInt(jQuery(this).text());
						
						settings.liPos = jQuery(settings.slides).eq(settings.clicks - 1).position();
						
						$this.animate({ 
							left: settings.liPos.left * -1
						}, 500, function() {
										
						});
						
						settings.ulLeft = (settings.liPos.left * -1);
				});
						
				// Controls all the animation when the right button is clicked
				jQuery(settings.rightButton).click(function(){
					if(settings.clicks < settings.slideCount)
					{	
						settings.clicks += 1;
						settings.cell = "#cell" + settings.clicks;
						settings.lastCell = "#cell" + (settings.clicks -  1);
						settings.ulLeft -= settings.liWidth;
						
						$this.animate({
							left: settings.ulLeft
						}, 500, function() {
						});
						
						timelineActiveA(settings.cell, settings.lastCell);
						
					} else {
						settings.clicks += 1;
						settings.cell = "#cell1";
						settings.lastCell = "#cell" + (settings.clicks -  1);
						settings.ulLeft = 0;
						
						$this.animate({
							left:0
						}, 500, function(){
						});
						
						timelineActiveA(settings.cell, settings.lastCell);
						settings.clicks = 1;
					}
				});
								
				// Controls all the animation when the left button is clicked
				jQuery(settings.leftButton).click(function(){
					if(settings.clicks > 1)
					{
						settings.clicks -= 1;
						settings.cell = "#cell" + settings.clicks;
						settings.lastCell = "#cell" + (settings.clicks +  1);
						settings.ulLeft += settings.liWidth;
						
						$this.animate({
							left: settings.ulLeft
						}, 500, function() {
						});
						
						timelineActiveA(settings.cell, settings.lastCell);
						
					} else {
						settings.clicks = 0;
						settings.cell = "#cell" + (settings.slideCount);
						settings.lastCell = "#cell" + (settings.clicks +  1);
						
						$this.animate({
							left: -1 * (settings.ulWidth - settings.liWidth)
						}, 500, function(){
						});						
						
						timelineActiveA(settings.cell, settings.lastCell);
						
						settings.clicks = settings.slideCount;
						settings.ulLeft = -1 * (settings.ulWidth - settings.liWidth);
					}					
				});	
				
				// This tries to make sure a Year block with one cell's year marker doesn't run into the other year
				jQuery(settings.yearBlock).each(function(){
					if(isIE6() == false){
						if(jQuery(this).find("a").length < 2)
						{
							jQuery(this).not(":last-child").find("a").siblings("span").css({"left":"-30px"});
						}
					} else {
						if(jQuery(this).find("a").length < 2)
						{
							jQuery(this).not(":last-child").find("a").siblings("span").css({"left":"-30px"});
							jQuery(this).is(":last-child").find("a").siblings("span").css({"left":"-15px"});
						}
					}
				});
		
				// POPs up the bubbles
				// Needs to use .live for dynamically created DOM elements
				jQuery(settings.yearBlock).find("a").live("mouseover mouseout", function(event) {
					var aPos = jQuery(this).parent().position(),
						bubblePos = jQuery(this).position(),
						aIndex = jQuery(this).text() - 1,
						bubbleWidth = 0;
						
					if(event.type == "mouseover")
					{
						// Takes the title and adds it to the bubble, if no title takes the H1
						if(jQuery(settings.slides).eq(aIndex).find("div.title").length == 1 && jQuery(settings.slides).eq(aIndex).find("div.title").text().length > 2) {
							jQuery(settings.bubble).eq(aIndex).html(buildBubble(jQuery(settings.slides).eq(aIndex).find(".title").text())).fadeIn("fast");
						} else {
							jQuery(settings.bubble).eq(aIndex).html(buildBubble(jQuery(settings.slides).eq(aIndex).find("h1").text())).fadeIn("fast");
						}			
						
						//  Used for the sides of the buddle - CSS
						var bubbleHeight = jQuery(settings.bubble).eq(aIndex).find(".content").height() + 10,
							totalHeight = "-" + jQuery(settings.bubble).eq(aIndex).height() + 10;
						
						jQuery(settings.bubble).eq(aIndex).find(".left").css({"height":bubbleHeight});
						jQuery(settings.bubble).eq(aIndex).find(".right").css({"height":bubbleHeight});

						// Gets the total width of the timeline
 						if(isIE6() == false){
							totalWidth = jQuery(ulContainer).parent().width();
						} else {
							totalWidth = jQuery(ulContainer).parent().parent().width();
							
							// Sets the width of the bubble so it displays properly in IE6
							jQuery(settings.bubble).eq(aIndex).css({"width": jQuery(settings.bubble).eq(aIndex).width()});
						}
							
						// Flips the bubbles position about half way through
						if(aPos.left < (totalWidth / 2) - 100)
						{
							jQuery(settings.bubble).eq(aIndex).css({"left":aPos.left + bubblePos.left + 17,"top":"0px"});
						} else {
							bubbleWidth = jQuery(settings.bubble).eq(aIndex).width() - 35;
			
							jQuery(settings.bubble).eq(aIndex).css({"left":(aPos.left + bubblePos.left - jQuery(settings.bubble).eq(aIndex).width() + 60),"top":"0px"});
							jQuery(settings.bubble).eq(aIndex).find(".arrow").css({"left": bubbleWidth});
						}
					} else {
						jQuery(settings.bubble).eq(aIndex).fadeOut("fast");
					}
				});
				
				// Builds out the bubble list for each li "slide"	
				buildBubbleList(settings.slides);
				
			}	
		});
		
		//  Builds the bubble adds the title
		function buildBubble(title)	{
					
			var bubble = "<div class=\"top\"><div class=\"topLeft\"></div><div class=\"topRight\"></div></div><div class=\"left\">&nbsp;</div><div class=\"content\">" + title + "</div><div class=\"right\">&nbsp;</div><div class=\"bottom\"><div class=\"bottomLeft\"></div><div class=\"bottomRight\"></div><div class=\"arrow\"></div></div>";
					
			return bubble;
		}
		
		// Foreach slide gets a bubble with the title, this builds the list of the bubbles		
		function buildBubbleList(slides) {
			jQuery(settings.slides).each(function(){
				jQuery(settings.bubbleContainer).append("<div class=\"bubble\"></div>");
			});
		}
		
		//  Builds the timeline
		function buildTimeline(yearSlides)
		{
			var counter = 1;
			var tlList = "<ul>";
			jQuery.each(yearSlides, function(year, slides) {
				tlList += "<li class=\"yearBlock\">";
				tlList += "<span>" + year + "</span>";
				
				for(i = 1; i <= slides; i++)
				{
					if(counter == 1){
						tlList += "<a href=\"#\" id=\"cell" + counter + "\" class=\"active\"><span>" + counter + "</span></a>";
					} else {
						tlList += "<a href=\"#\" id=\"cell" + counter + "\"><span>" + counter + "</span></a>";
					}
					
					counter++;
				}
				
				tlList += "</li>";
			});
			
			// This makes sure the timeline nav actually builds
			jQuery(window).load(function(){
				yearBlockWidth(counter);
			});
			
			return tlList;		
		}
		
		// Dynamically changes the width of the cell in each year block depending on cell count and container width 
		function yearBlockWidth(counter)
		{
			var navWidth = jQuery("#tlSlideNav").width();
			var aWidth = Math.round((navWidth / counter));
			
			if(isIE6() == false){
				jQuery("#tlSlideNav").find("a").each(function(){
					jQuery(this).css({"width":aWidth});
					jQuery(this).children().css({"width": aWidth + 2});
				});
			} else {
				jQuery("#tlSlideNav").find("a").each(function(){
					jQuery(this).css({"width":aWidth - 1, "border-right": "solid 1px #999"});
					jQuery(this).children().css({"display": "none"});
				});
			}
		}
		
		
		//  Used this code in more than one spot, broke it off to a function to follow the DRY principle
		function timelineActiveA(cell, lastCell)
		{
			//  Finds the current year block
			settings.currentYear = jQuery(cell).parent().index();
			
			//  Adds the active class to the current timeline cell
			jQuery(settings.yearBlock).find(cell).toggleClass("active");
			
			// Removes the active class from the last timeline cell
			jQuery(settings.yearBlock).find(lastCell).removeClass("active");
		}
		
		// Is the browser IE6??
		function isIE6 ()
		{
			if (jQuery.browser.msie && jQuery.browser.version.substr(0,1) < 7){
				return true;
			} else {
				return false;
			}
		}
		
		return this;
	}	 
})(jQuery);
