/*
Namespace: CLEAR

About: Version
	1.0

Description:
	A collection of functions to be shared with all CLEAR projects

Requires:
	jQuery 1.3 <http://jquery.com>
	jQuery Flash Module (Schematic Customized)
	jQuery sIFR Module (Schematic Customized)
	jQuery Easing Module
*/

// JS Lint Globals
/*global window, document, $, jQuery */

// Global Namespace
var CLEAR = window.CLEAR || {};

// When the DOM is ready.
(function () {
	
	// Storing a variable to reference
	var $self = CLEAR;
	
	// Shared variables
	$self.vars = $.extend($self.vars, {});
	
	// A legacy namespace to be used if Clear has any legacy dependencies
	$self.legacy = $.extend($self.legacy, {});
	
	// Shared utilities
	$self.utils = $.extend($self.utils, {
		
		ie6Check : function() {
			// Let's set a flag for IE 6
			$.extend($.browser, {
				ie6 : function () {
					return !!($.browser.msie && $.browser.version == 6);
				}()
			});
		}(),
		
		// Initialization function
		// This loops through each function in the $self namespace
		// And fires each one.
		init : function (object) {
			$(document).ready(function () {
				for (var key in object) {
					if (object.hasOwnProperty(key) && (typeof object[key] === "function")) {
						object[key]();
					}
				}
			});
		},
		
		applyStyle : function (spacing) {
			return {
				".sIFR-root" : {
					"color" : "#333333",
					"letter-spacing" : spacing
				},
				"a" : {
					"color": "#50bb25",
					"text-decoration": "none"
				}
			};
		},
		
		sharedSettings : function (color, kerning) {
			
			if (typeof color === "object") {
				kerning = color.kerning;
				color = color.color;
			}
			
			var props = {
				offsetTop : 2,
				tuneHeight : -3,
				css : $self.utils.applyStyle(kerning || -2.1)
			};
			
			if (color) {
				props.css[".sIFR-root"].color = color;
				props.css.a.color = color;
			}
			
			return props;
		},
		
		applyNavigationShine : function(obj) {
			if ($.browser.ie6) {
				return false;
			}
			
			var el = obj.target,
			    src = obj.src;
			
			el.each(function() {
				var parent = $(this),
				    items = parent.find("a"),
				    shine = $('<img class="shine" alt="" />').attr("src", src).appendTo(parent),
				    list = parent.find("> ul"),
				    listLinks = list.find("a"),
				    clone = list.clone().css(list.position()).addClass("shine-list-clone").insertAfter(shine),
				    cloneLinks = clone.find("a");

				// Bind  events
				$.each(("mouseenter,mouseleave,mousedown,mouseup,click,dblclick").split(","), function(i, type) {

					cloneLinks.bind(type, function(e) {
						var index = cloneLinks.index(this);
						listLinks.eq(index).trigger(e.type);
					});

				});

			});

			el.find("ul a").hover(function() {
				$(this).parent().addClass("hover");
			}, function() {
				$(this).parent().removeClass("hover");
			});
		},
		
		applyColumnCaps : function(columns) {
			if (!$.browser.ie6) {
				columns.prepend('<div class="chrome top"></div>').append('<div class="chrome bottom"></div>');
			}
		},
				
		equalHeightColumns : function(columns) {
			if ($.browser.ie6) {
				return false;
			}
			
			// We're assuming here that column direct descendents won't change
			var	el, maxHeight = 0, cachedHeight = 0,
				children = columns.children().not(".chrome");

			var equalize = function() {
				maxHeight = 0;
				
				children.each( function() {
					el 		  	  = $(this);
					var	top       = el.position().top,
						height    = el.outerHeight(true),
						curHeight = top+height;
											
					if (curHeight > maxHeight) {
						maxHeight = curHeight;
					}
				});

				if (maxHeight !== cachedHeight) {
					columns.each(function() {
						el = $(this);
						el.css("min-height", maxHeight);
						var outerHeight = el.outerHeight(true);

						if (outerHeight > maxHeight) {
							el.css("min-height", maxHeight - (outerHeight - maxHeight));
						}
					});

					cachedHeight = maxHeight;
				}
			};
			
			// Fire on document ready, we want this to initialize ASAP
			window.setInterval(equalize, 333.3333);

			// Do once on load
			$(window).load(equalize);
			
		},
		
		actionLinks : function() {
			if ($.browser.msie && $.browser.version == 7) {
				$(document).ready(function() {
					$('.action-link').prepend('▸ ');
					$('.back-link').append(' ▸');
				});
			}
		}(),
		
		/**
		 * Overlays Controller
		 * 
		 * Manages elements in the #overlays include, including the 
		 * semi-transparent scrim behind the overlays.
		 * 
		 * Usage:
		 * 		CLEAR.utils.OverlayController.show(someOverlayElement);
		 *		CLEAR.utils.OverlayController.hide(someOverlayElement);
		 */
		OverlayController : function() {
			
			var overlayParent = $('<div id="overlays"></div>'),
			    overlays = $(".overlay").appendTo(overlayParent),
			    scrim = $('<div class="overlay-controller-scrim"></div>').appendTo(overlayParent);
			
			// Prep overlays
			function prep(overlay) {
				overlay.wrapInner('<div class="overlay-wrap"></div>');
				overlay.prepend('<div class="overlay-cap top"></div>').append('<div class="overlay-cap bottom"></div>');
			}
			
			overlays.each(function() {
				prep($(this));
			});
			
			overlayParent.appendTo(document.body);
			
			function showScrim() {
				scrim.width($(window).width()).height($("html, body").height() + 160);
				scrim.show();
			}
			
			// Make sure scrim resizes on window resize
			$(window).bind("resize", function() {
				if (scrim.is(":visible")) {
					showScrim();
				}
			});

			function hideScrim() {
				scrim.hide();
			}
			
			function prepOverlayDimensions(overlayObject) {
				var objWidth = overlayObject.width(),
				    objHeight = overlayObject.height(),
				    winWidth = $(window).width(),
				    winHeight = $(window).height(),
				    objTop = Math.max(50, (winHeight / 2) - (objHeight / 1.25));
				
				overlayObject.css({
					position : "",
					left : (winWidth / 2) - (objWidth / 2),
					top : objTop
				});
				
				if ((objHeight + objTop) > winHeight) {
					overlayObject.css("position", "absolute");
				}
				
				showScrim();
			}
			
			function formulateOverlay(overlayObject) {
				overlayObject.find("input, select, a.ui-formulate-button").formulate();
			}
			
			function focusFirstInput(overlayObject) {
				overlayObject.find("input, select").eq(0).focus();
			}
			
			return {
				show : function(overlayObject) {
					if (overlayObject.get(0) && typeof overlayObject.show === "function") {
						if (!overlayObject.parent().is("#overlays")) {
							prep(overlayObject);
							overlayObject.appendTo(overlayParent);
						}
						
						overlayObject.siblings(".overlay-active").hide();
						overlayObject.show().addClass("overlay-active");
						
						prepOverlayDimensions(overlayObject);
						formulateOverlay(overlayObject);
						showScrim();
						
						focusFirstInput(overlayObject);
					}
				},

				hide : function(overlayObject) {
					if (overlayObject.get(0) && typeof overlayObject.hide === "function") {
						overlayObject.hide().removeClass("overlay-active");
						hideScrim();
					}
				},
				
				redraw : function(overlayObject) {
					prepOverlayDimensions(overlayObject);
				}
			};
		}(),
		
		/**
		 * Spinner Controller
		 * 
		 * Handles spinner injection / removal
		 * 
		 * Usage:
		 * 		CLEAR.utils.SpinnerController.add(targetElement);
		 *		CLEAR.utils.SpinnerController.remove(targetElement);
		 */
		SpinnerController : function() {
			
			// Define spinner with CSS
			var spinner = $('<div class="ui-spinner"></div>').appendTo(document.body).hide();
			
			return {
				
				show : function(targetElement) {
					if (targetElement.closest(".ui-formulate").get(0)) {
						targetElement = targetElement.find(".ui-formulate-value");
					}
					
					spinner.show().appendTo(targetElement);
				},
				
				hide : function(targetElement) {
					spinner.hide().appendTo(document.body);
				}
			}
		}()
	});
	
}).call(CLEAR);