/*
	EcommerceObj Singleton
	
	Dependencies: jQuery
	Async loaded dependencies: underscore.js
	Author: Justin Sermeno
*/

if ( window.EcommerceObj === undefined ) {
	
	window.EcommerceObj = function() {
		var
			self,
			config,
			categoryOrders,
			styles,
			$origCategoryList,
			$tabCategoryList,
			isAlreadyHidden = false;
		
		
		// Default store properties
		config = {
			elementId: null
		};
		
		/* Default category array
		  	[{id: "842", order: "0"},
		     {id: "843", order: "4"},
		     {id: "846", order: "1"}]
		 */
		categoryOrders = [];
		
		// Default styles object
		styles = {
			displayCategories: true,
			categoryType: "dropdown", /* "horizontal" | "vertical" | "dropdown" */
			displaySearch: true,
			height: "1200px",
			width: "700px",
			textFont: "Verdana", /* CSS font family */
			linkStyle: "tabs", /* "tabs", "links" */
			textSize: "12px",
			selectedTabColor: "transparent", /* hex value */
			headerBackgroundColor: "#A7D8D5", /* hex value */
			categoryWidth: "160px",
			productFontColor: "#505050",
			productBackgroundColor: "transparent", /* hex value */
			displayBorder: true
		};
		
		self =  {
			
			// Accepts javascript object with basic properties
			setStoreProperties: function( spec ) {
				if ( !spec || !spec.elementId  ) {
					throw "InvalidStoreProperties";
				}
				
				$.extend(config, spec);
			},
			
			// Accepts array of category objects of format
			// [{ id: 838, order: 0 }, { id: 828, order: 1 }, ... ]
			setCategoryOrders: function ( spec ) {
				var 
					i, item, len;
				
				// Reset category orders
				categoryOrders = [];
				
				if ( spec === undefined)
					throw "Need Specification Parameter";
				
				for ( i = 0; len = spec.length, i < len; i++ ) {
					item = spec[i];
					if ( item === undefined || item.id === undefined || item.order === undefined ) {
						throw "InvalidCategoryItem";
					}
					
					categoryOrders.push(item);
				}
			},
			
			// Accepts styles object that will extend the default styles object
			// There are no required styles
			setStyles: function(spec) {
				if ( !spec ) {
					throw "InvalidStylesObject";
				}
				
				$.extend(styles, spec);
			},
			
			
			// Refreshs styles based on EcommerceObj
			// This will refresh all styles by making an AJAX call to SiteApps
			refreshStyles: function( params ) {
				var 
					styles = self.getEcommerceObj().styles,
					$wrapper = $("#wrapper");
				
				if ( $wrapper.length === 0 )
					return;
			
				if ( (typeof styles.displayCategories === "string" && styles.displayCategories === "false") ||
						(typeof styles.displayCategories === "boolean" && styles.displayCategories === false)) styles.categoryType = "horizontal";
					
				// Alter classes based on styling
				// Choose between vertical or horizontal
				if ( styles.categoryType.toLowerCase() === "horizontal" || styles.categoryType.toLowerCase() === "dropdown") {
					$wrapper.removeClass("categoriesVertical")
								.addClass("categoriesHorizontal");
				}
				else if ( styles.categoryType.toLowerCase() === "vertical" ) {
					$wrapper.removeClass("categoriesHorizontal")
								.addClass("categoriesVertical");
				}
				
				// Choose between tabs or links or dropdown
				$wrapper.find("#categoryLinks").removeClass()
					.addClass(styles.linkStyle);
				
				// Load styles via ajax
				$.ajax({
					type: "POST",
					url: "/~site/siteapps/simplestorestyles.action",
					data: "styles=" + encodeURI(JSON.stringify(self.getEcommerceObj().styles)),
					success: function(data) {
						var 
							$styleEl,
							$styleTag = $("#simplestoreStyleTag");
						
						// Create style element
						$styleEl = $("<style id=\"simplestoreStyleTag\" media=\"screen\">" + data + "</style>")
						
						if ( $styleTag.length === 0 ) {
							$("head").append($styleEl);
						} else {
							$styleTag.replaceWith($styleEl);
						}
											
						if ( params && params.callback !== undefined && typeof params.callback === "function" )
							params.callback();
						
						// Reset tabs
						//self.undoTabs();
						
						// Update category ordering
						if ( SS.Controllers.SimpleStore.ssView !== undefined ) {
							SS.Controllers.SimpleStore.ssView.model.updateOrder( self.getEcommerceObj().categoryOrders );
						}
						
						self.createTabs();
						
						// Find max height of vertical category list or more tab
						findMaxHeight();
					}
				});
				
			},
			
			
			//function createTabs()
			//creates the more tab for the horizontal view
			createTabs: function() {
				$("#categoryLinks").live( "click", function(event) {
					event.preventDefault();
				});
				var 
					height = 0,
					overflowIndex = -1,
					$root = $("#categoryLinks"),
					links = $("#categoryLinks").find("li").get();
								
				if( !$('#wrapper').hasClass('categoriesHorizontal') || $root.find("#moreLink").length !== 0 )
					return false;
				
				if ( $origCategoryList === undefined ) $origCategoryList = $(links).clone();	
				
				// Cleanse links of any remaining "more tab" CSS classes
				$(links).each(function(){
					$(this).removeClass("moreItems");
				})
				
				// determine index where the tabs start overflowing
				height = $(links[links.length - 1]).offset().top;
				for(var i = links.length - 2; i >= 0; i--){
					var currHeight = $(links[i]).offset().top;
					if( currHeight != height ){
						overflowIndex = i;
						height = currHeight;
					}
				}
			
				if (overflowIndex == -1)
					return false;
				
				// Check if another category will fit
				var
					$a =  $(links[overflowIndex + 1]).find("a"),
					realName = $a.html(),
					origOverflowIndex = overflowIndex;
				
				$a.html('<a id="moreLink">more <img src="/~site/siteapps/assets/images/ecommerce/moreArrowDark_8x4.png" class="moreImageArrow" /></a>');
				
				// Recalculate overflow index
				if ( $a.offset().top === $(links[overflowIndex]).offset().top ) {
					overflowIndex = overflowIndex + 1;
				}
				
				$a.html(realName);
				
				// create new elements
				var
					$endLi = $(links[overflowIndex]),
					$more = $endLi.clone(),
					ul = document.createElement("ul");
				
				var moreStyleValue = $("#arrowImage").css("width");
				
				if(moreStyleValue == "0px"){
					$more.html('<a id="moreLink">more <img src="/~site/siteapps/assets/images/ecommerce/moreArrowDark_8x4.png" class="moreImageArrow" /></a> ')
					.removeClass()
					.addClass('more');
				}else{
					$more.html('<a id="moreLink">more <img src="/~site/siteapps/assets/images/ecommerce/moreArrowLight_8x4.png" class="moreImageArrow" /></a> ')
					.removeClass()
					.addClass('more');
				}
				
				$endLi.detach().addClass("moreItems");
				
				ul.appendChild($endLi.get()[0]);
				for(var i = overflowIndex + 1; i < links.length; i++){
					$(links[i]).removeClass()
						.addClass('moreItems unselected');
						
					ul.appendChild(links[i]);
				}
				
				// append new elements to dom
				$more.append('<div class="clear"></div>');
				$more.append($(ul));
				$root.append($more).css('overflow', 'visible');
			},
			
			
			// private inner function undoTabs()
			// reverts tabs back to a state without the "more" tab for vertical view
			undoTabs: function() {
				var $categoryLinks = $("#categoryLinks");
				
				if ( $origCategoryList === undefined )
					return;
				
				$categoryLinks.find("li").detach();
				$categoryLinks.append( $origCategoryList );
				
			},
			
		
			// Returns data
			getEcommerceObj: function() {
				config.categoryOrders = categoryOrders;
				config.styles = styles;
				
				return config;
			}
		};
		
		
		function findMaxHeight() {
			var 
			$categories = $('#categories'),
			paddingTop,
			margin,
			height,
			$more;
			
			if ( $("#wrapper").hasClass("categoriesVertical") ) {
		
				paddingTop = $categories.css('padding-top').replace(/px/,"");
				margin = $categories.css('margin-top').replace(/px/,"");
				height = $('#ssContainer').css('height').replace(/px/,"");
				
				if (parseInt($categories.height()) > parseInt(height)) {
					height = parseInt(height) - parseInt(paddingTop) - parseInt(margin);
					
					$categories.css('height', height + 'px');
				}
			
			} else {
				
				paddingTop = $categories.css('padding-top').replace(/px/,"");
				margin = $categories.find("#categoryLinks").css('height').replace(/px/,"");
				height = $('#ssContainer').css('height').replace(/px/,"");
				$more = $categories.find(".more ul");
				
				if ( $more.length > 0 && (parseInt($more.height()) > parseInt(height)) ) {
					height = parseInt(height) - parseInt(paddingTop) - parseInt(margin) - 10;
					
					$more.css('height', height + 'px');
				}
				
			}
		}
		
		return self;
	};
	
	(function() {
			
		// loads a script for use
		// credit to http://css-tricks.com/snippets/jquery/load-jquery-only-if-not-present/
		function getScript(url, success) {
			var
				script = document.createElement("script"),
				head = document.getElementsByTagName("head")[0],
				done = false;
			
			script.src = url,
			
			script.onload = script.onreadystatechange = function() {
				if ( !done && (!this.readyState || this.readyState === "loaded" || this.readyState ==="complete")) {
					done = true;
					
					if ( typeof success === "function" ) {
						success();
					} else {
						throw "getScript requires callback function";
					}
					
					script.onload = script.onreadystatechange = null;
				}
			};
			
			head.appendChild(script);
		}
		
		if ( typeof $ === "undefined" ) {
			getScript("/~site/siteapps/javascript/ecommerce/lib/jquery-1.6.1.min.js", function(){
				window.EcommerceObj = window.EcommerceObj();
				if ( typeof window.ecommerceAsync === "function" ) {
					window.ecommerceAsync();
				}
			});
		} else {
			window.EcommerceObj = window.EcommerceObj();
			if ( typeof window.ecommerceAsync === "function" ) {
				window.ecommerceAsync();
			}
		}
		
	}());

}
