/************************************************************/
/* Root client-side functionality of www.Green-Circuit.com  */						
/* @author doug				                                */
/* @version 1.0                                             */
/************************************************************/
var site = new function() {

	/*****************
	* Site variables *
	******************/
	var navigation;
	
	/**************
	* Tab Objects *
	***************/
	// Constructor for tabs
	function Tab(name, animated){
		this.name = name;
		if (animated) {
			this.animated = true;
		} else {
			this.animated = false;
		}
		this.seen = false;
	}
	
	// Initialize the names of the tabs and whether they are animated
	this.tab = new Array();
	this.tab[0] = new Tab("about");
	this.tab[1] = new Tab("our_team", true);
	this.tab[2] = new Tab("solar");
	this.tab[3] = new Tab("expertise");
	this.tab[4] = new Tab("projects", true);
	this.tab[5] = new Tab("blog_spot");
	this.tab[6] = new Tab("contact");
	
	// Speed of open and close animations
	// TODO Start some sort of "settings" construct
	this.accordion_speed = 675;
	this.featured_projects_slide_speed = 1500;

	/***************
	* Site methods *
	****************/
	// Construct and initialize everything but the content
	this.initialize = function() {
		$(function() {
		
			// Preload all images referenced in CSS (boom)
			$.preloadCssImages();

			// Create the navigation tabs
			// Cache content as well as ajax calls
			navigation = $('#main').tabs({ 
				cache: true, 
				spinner: false, 
				ajaxOptions: { cache: true },
				// Cause links to load within the tab viewer
				load: function(event, ui) {
					// Anchors with the tab class do not exit the site
					$("a.tab", ui.panel).click(function() {
						$(ui.panel).load(this.href);
						return false;
					});
					var options = {
                                                        'autoScale'     :       'true',
                                                        'autoDimensions':       'true',
                                                        'hideOnOverlayClick':   'true',
                                                        'hideOnContentClick':   'true',
                                                        'padding'       :       10,
                                                        'titlePosition' :       'inside',
                                                        'transitionIn'  :       'elastic',
                                                        'transitionOut' :       'elastic',
                                                        'speedIn'               :       600,
                                                        'speedOut'              :       400,
                                                        'overlayShow'   :       false,
							'width'			: 750 
                                                };
					$(ui.panel).find('a img').parent().each(function() { $(this).fancybox(options) } );
					$(ui.panel).find('a.iframe').each(function() { $(this).fancybox(options) } );
				}
			});
			
			// If the navigation tabs are instantiated, and the URL contains a hash 
			if ($('#main') && document.location.hash) {
					// Jump to the tab
					$('a[href$="' + document.location.hash + '"]').click();
			}

			// Enable hash appending for hijaxed links
			/* TODO This method causes small screens to jump
			$('#main').localScroll({ 
				target:'#main',
				hash:true
			});
			*/
			
			// Get the currently selected tab
			var initially_selected_tab = navigation.tabs('option', 'selected');

			// Initialize ajax history and send in a callback function to 
			// reset to the currently selected tab on reset
			// That is, when a user navigates back to the tab they began on, the currently selected tab
			$.ajaxHistory.initialize(function() { navigation.tabs('select', initially_selected_tab) });
			$('a.remote').remote('#main');
			
			// If the user hasn't been to the site (or in awhile)
			// TODO Send in flashvars to swf instead, indicating to draw only the last frame?
			// More efficient than downloading the jpg since they presumably have the swf already in cache?
			if (($.cookie("visited_recently")) == null) {
					// Embed the flash object
					var flashvars = {};
					var params = { wmode: "transparent" };
					var attributes = {
						id: "gc_flash_border",
						name: "gc_flash_border"
					};
					var callback = function() {}
					swfobject.embedSWF("flash/grid_border.swf", "gc_border", "960", "720", "8", false, flashvars, params, attributes, function() {
						$("#border").removeClass("inactive");
						window.setTimeout(function() {
							$("#main").fadeIn("slow", function() { 
								$(this).removeClass("inactive");
								$("#reset").removeClass("inactive");
							});
						}, 4000); // TODO Parameterize
					});
			} else {
				// Otherwise show the main viewer immediately, no theatrics
				$("#border").removeClass("inactive");
				$("#main").removeClass("inactive");
				$("#reset").removeClass("inactive");
			}
			// Mark that they have visited, and keep the cookie for 7 days
			$.cookie("visited_recently", true, { expires: 7 } );
			
			// Set up the reset handler function (click gc logo)
			$('#reset').bind('click', function () { site.reset(); });
			
			// Set up an event when a tab's content is about to be shown
			navigation.bind('tabsshow', function(event, ui) {

				// Hide all of the immediate child divs in the nav main (the content divs) that are not this tab's
				// This defeats possible race conditions, only the most recently selected can ever be shown with this method
				// Aka this guards against krazy klickers vs asynchronous loading
				$("#main > div:not(#" + ui.panel.id + ")").addClass("ui-tabs-hide");
				// If this tab is animated and it hasn't already been seen
				if (site.tab[ui.index].animated && !site.tab[ui.index].seen) {
					// Begin its animation
					site.animate(site.tab[ui.index]);
					// Mark the tab as seen
					site.tab[ui.index].seen = true;
				}
				// Turn all tab backgrounds inactive
				$("#nav .tab .background").each(function() {
					$(this).addClass("inactive");
				});
				// Turn on this tab's background
				$("#nav .tab[title='" + ui.panel.id.replace("_", " ") + "'] .background").removeClass("inactive");
			});

		});
	}

	// Load the content of the site
	this.load = function() {
		$(function() {
		
			// Create the list of content to begin preloading
			// Ordered by the integer corresponding to each tab's sequence
			var preload = [];

			// And we'll also keep a list of the content that has been loaded
			var loaded = [];
			
			// Set up the special case, the first tab to load		
			// Switch on the current hash
			switch(window.location.hash)
				{
					case "#" + site.tab[0].name: preload[0] = 0; break;
					case "#" + site.tab[1].name: preload[0] = 1; break;
					case "#" + site.tab[2].name: preload[0] = 2; break;
					case "#" + site.tab[3].name: preload[0] = 3; break;
					case "#" + site.tab[4].name: preload[0] = 4; break;
					case "#" + site.tab[5].name: preload[0] = 5; break;
					case "#" + site.tab[6].name: preload[0] = 6; break;
					default: preload[0] = 0;
				}

			// Queue the tabs in the preload in sequential order
			var tab = 0;
			for (var index=0; index<navigation.tabs('length'); index++) {
					// The first tab has already been decided, skip it
					if (tab != preload[0]) {
						preload[index] = tab + "";
					}
					tab++;
			}
	
			// Set up an event such that if a tab is clicked it is put to the head of the queue
			navigation.bind('tabsselect', function(event, ui) {
					var tab = ui.index;
					// If the tab that was selected has not yet had its contents loaded
					if (is_content_loaded(tab) == false) {
							// Then let's put it at the head of the list
							// First find the selected tab in the preload list
							// (tab should be the only instance in the set,
							//	but might as well get the last one - if one
							//  somehow snuck onto the front, it wouldn't be
							//  such a bad thing)
							var tabIndex = preload.lastIndexOf(tab);
							//	If it was found in the list (and it should be,
							//  wish you could throw exceptions in this language..)
							if (tabIndex > 0) {
								// Remove one instance at the indexed location
								preload.splice(tabIndex, 1);
							}
							// Then let's place the selected tab
							// at the head of the preload list
							preload.unshift(tab);
							// And begin loading content again
							load_content();
					}
			});
	
			// Set up an event for when a tab's content has been loaded
			navigation.bind('tabsload', function(event, ui) {
					// Mark that the content has been downloaded for some tab
					loaded[ui.index] = true;
					// And begin downloading the next tab's content
					load_content();
			});
												
			// Begin loading the next tab in the queue
			function load_content() {
					var tab_to_load = preload.shift();
					// If there is a tab to load
					if (tab_to_load != null) {
							// And the content isn't loaded yet
							if (is_content_loaded(tab_to_load) == false) {
									// Let's load it (this will fire the load event)
									navigation.tabs('load', tab_to_load);
							} else {
									/* Otherwise keep loading content.
									   This is here because javascript does not provide a Set data structure,
									   which would allow only unique elements. Eg, if a user clicks on a tab before
									   it has been loaded, it will appear twice in the list. So we do a check if it has been
									   loaded already. */
									load_content();
							}
					}
			}
	
			// Is the content of a tab downloaded?
			function is_content_loaded(tab)	{
					return loaded[tab] || false;								
			}
			
			// Begin loading content in the background
			load_content();
														
		});	
	}

	this.gallery = new function() {
	
		// The fade in speed
		var speed = 1600;

		this.boot = function(which) {
				$('.gallery_unstyled').addClass('gallery_styled'); // adds new class name to maintain degradability
				$('#content_bubble.content').fadeOut(speed, function() {
						$('#' + which + '_content_bubble.content').fadeIn(speed);
						$('#' + which + '_content_bubble.content img').fadeIn(speed); // Fade in the content for the gallery
				});
				$('.navigation').fadeIn(speed); // fade in the navigation
				$('#' + which).removeClass("inactive"); // Show the gallery (not the images in the gallery)
				$('#' + which + ' ' + 'ul.gallery_styled').galleria({
							history   : false, // activates the history object for bookmarking, back-button etc.
							clickNext : true, // helper for making the image clickable
							insert    : '#' + which + '_main_image', // the containing selector for our main image
							onImage   : function(image,caption,thumb) {
							// fade in the image & caption
							image.css('display','none').fadeIn(speed);
							caption.css('display','none').fadeIn(speed);
							
							// add a title for the clickable image
							image.attr('title','Next image >>');
						}
				});
		}
		
		this.shutdown = function() {
				$('#gallery .navigation').fadeOut(speed);
				$('#gallery .content').fadeOut(speed);
				window.setTimeout(function() {	
					$('#content_bubble.content').fadeIn(speed);
				}, speed);
				$(".main_image").each(function() { $(this).fadeOut("slow");	}); /* TODO Parameterize this */
				gallery_toggled = false;
		}
	}
	
	this.animate = function(which) {
		if (which == this.tab[1]) {	
			var delay = 0
			var speed = 375;
			var reverse = false;
			if ($.browser.msie == true) {
				delay = 500;
			}
			window.setTimeout(function() {
				var collection = reverse ? $.makeArray($(".handle .hover")).reverse() : $.makeArray($(".handle .hover"));
				$(collection).each(function(index) {
					var $this = this;
					window.setTimeout(function() {
						if ($($this).get(0) == $($(".handle:last").children()[0]).get(0)) {
							$($this).fadeIn(speed, function() {
								$($this).click();
							});
						} else {
							$($this).fadeIn(speed, function() {
								$($this).fadeOut(speed);
							});
						}
					}, speed * parseInt(index));
				});
			}, delay);
		}
		if (which == this.tab[4]) {
			var delay = 600;
			var speed = 750;
			window.setTimeout(function() {
				$("#gallery1_handle_background").fadeIn(speed, function() {
					$(this).fadeOut(speed);
					$("#gallery2_handle_background").fadeIn(speed, function() {
						$(this).fadeOut(speed);
					});
				});
			}, delay);
		}
	}
	
	// See if this browser is supported
	/* Supported browsers:
			FF 3, 3.5+
			IE 7, 8+
			Chrome 4, 5, 6+
			Safari 4, 5+
	*/
	this.checkBrowser = function() {
		$(function() {
			$.reject({
				display: ['firefox', 'chrome', 'msie', 'safari'],
				browserInfo: {
					firefox: {
						text: 'Firefox'
					},
					chrome: {
						text: 'Google Chrome'
					},
					msie: {
						text: 'Internet Explorer'
					},
					safari: {
						text: 'Apple Safari'
					}
				},
				imagePath: 'images/browsers/',
				reject: {
					msie: false, msie5: true, msie6: true, msie7: false, msie8: false, // MSIE Flags
					firefox: false, firefox1: true, firefox2: true,firefox3: false, // Firefox Flags
					konqueror: true,
					chrome: false, chrome1: true, chrome2: true, chrome3: true, chrome4: false, chrome5: false,// Chrome Flags (Global, 1-4) 
					safari: false, safari2: true, safari3: true, safari4: false, // Safari Flags (Global, 1-4) 
					opera: false, opera8: true, opera9: false, opera10: false,
					unknown: true // Unknown covers everything else 
				},
				closeCookie: true, 	// Only show once per session
				cookieSettings: {
					expires: 0		// Expires after current session
				}
			});
		});
	}

	this.reset = function() {
		$(function() {
				// First reset the cookie
				$.cookie("visited_recently", null);
				// Then refresh the current page
				location.reload();
		});
	}
	
	this.ourTeam = function() {
		$(function() {
			$('#biographiesHandle0').supersleight({shim: 'images/transparent.gif'});
			$('#profile0.profile').supersleight({shim: 'images/transparent.gif'});
			$('#biographiesHandle1').supersleight({shim: 'images/transparent.gif'});
			$('#profile1.profile').supersleight({shim: 'images/transparent.gif'});
			$('#biographiesHandle2').supersleight({shim: 'images/transparent.gif'});
			$('#profile2.profile').supersleight({shim: 'images/transparent.gif'});
			$('#biographiesHandle3').supersleight({shim: 'images/transparent.gif'});
			$('#profile3.profile').supersleight({shim: 'images/transparent.gif'});
			
			// Fix for safari 
			if ($.browser.safari && $.browser.version < "523.12.9") {
				$("#our_team_content").css("top", "-17px");
			}

			// Get the horizontal accordion script and
			// call the accordion function on the unordered list and
			// set up the hover over and click effects for each handle
			$.getScript("scripts/jquery.hrzAccordion.js", function() {
					// Load the accordian as a callback function once the dependant js loads
					$(".biographies").hrzAccordion({eventTrigger:"click",
													openOnLoad:"",
													handlePosition:"left"});

					// Setup a hover over effect for each handle of the accordion
					// TODO Move out
					var speed = 500;
					var selected;
					$(".handle").hover(
						function () {
							// TODO
							// Only perform the hover effect if no handles have been selected, 
							// or if this handle hasn't been selected
							if (selected == null || $(this).attr("id") != selected.attr("id")) {
								$(this).children(".hover").each( function() { $(this).fadeIn(speed); });
							}
						},
						function() {
							if (selected == null || $(this).attr("id") != selected.attr("id")) {
								$(this).children(".hover").each( function() { $(this).fadeOut(speed); });
							}
						}
					);
					// Setup a click effect for each handle
					$(".handle").click(
						function() {
							selected = $(this);
							$(this).children(".hover").each( function() { $(this).fadeOut(speed); });
						}
					);
				}
			);
		});
	}
}

/***********
* Boot up *
***********/
site.checkBrowser();
site.initialize();
// In IE if tabs are clicked quickly this will add
// a history/hash property to the URL. Address if IE.
if ($.browser.msie != true) {
	site.load();
}

