/**
 * @namespace Holds all Balenciaga functionality.
 */
bale ={	
	/**
	 *The basic config holder
	 */
	config:{
		ready : false,
		useHash : true
	},
	/**
	 * Holds any language specific settings which appear to the user.
	 */
	lang:{
		colorView : "view-color",
		detailsView : "product-details",
		mediaView : "media",
		categoryView :"category",
		mediaToDetails : "media-transition-details",
		mediaToColor : "media-transition-color",
		viewProductDetails : "View Product Details",
		viewColors : "View Colors"
	}
}

/**
 * external information like URLs
 */
bale.external = {
	backBActive:'images/back-active.gif',
	backBInactive:'images/back-inactive.gif',
	nextBActive:'images/next-active.gif',
	nextBInactive:'images/next-inactive.gif'
}

/**
 * Information about the current page.
 */
bale.pageInfo = {
	/**
	 * @private
	 */
	bodyId : null,
	/**
	 * Check if this is the Product Page
	 * @return (boolean)
	 */
	isProductPage : function(){
		if (this.bodyId == null) this.getBodyId();
		return (this.bodyId == "bale-productDetails")
	},
	/**
	 * Check if this is the Category Page
	 * @return (boolean)
	 */
	isCategoryPage : function(){
		if (this.bodyId == null) this.getBodyId();
		return (this.bodyId == "bale-productCategory")
	},
	/**
	 * Internal 
	 */
	getBodyId : function(){
		this.bodyId = $('body').attr('id');
	}
}

/**
 * The holds a collection of product data objects and methods for retrieval of product data objects.
 */
bale.productData = {
	
	/** @private product data holder */
	library : {},
	
	/**
	 * Adds product to library
	 * @param {object} productObject a product object. 
	 */
	addProduct : function(productObject){
		this.library["prodId"+productObject.id] = productObject;
	},
	
	/**
	 * @param {string} productId the ID of the product to return
	 * @return {object} product data object
	 */
	getProduct : function(productId){
		return this.library["prodId"+productId];
	},
	/**
	 * @param {string} productId the unique URL slug of the product to return
	 * @return {object} product data object
	 */
	getProductBySlug : function(urlSlug){
	    urlSlug = unescape(urlSlug);
		for(prod in bale.productData.library){
			if( urlSlug == bale.productData.library[prod].urlSlug){
				return bale.productData.library[prod];
			};
		}
	},
	/**
	 * @param {string} colorName name of the color object you're looking for
	 * @param {object} product product data object to search for name in
	 * @return {object} color data object
	 */
	getColorByName:function(colorName,product){
	    for(i =0; i<product.colors.length;i++){
			if(product.colors[i].name == colorName){
			    return product.colors[i];
			}
		}
	},
	/**
	 * @param {string} mediaName name of the media object you're looking for
	 * @param {object} product product data object to search for name in
	 * @return {object} media data object
	 */
	getMediaByName:function(mediaName,product){
		for(i =0; i<product.media.length;i++){
			if(product.media[i].name == mediaName){
				return product.media[i];
			}
		}
	},
	getMediaById:function(mediaId,product){
		for(i =0; i<product.media.length;i++){
			if(product.media[i].id == mediaId){
				return product.media[i];
			}
		}
	},
	defaultColor:null,
	setDefaultColor:function(colorObject){
		 this.defaultColor = colorObject;
	},
	getDefaultColor:function(){
		return this.defaultColor;
	}
}

/**
 * Model for the product and category pages. Holds the current status of the view, product, photos etc.
 */
bale.stateManager={
	/** 
	 * eventBroadcaster notifies listeners of a change in the model
	 * example:
	 * 	 bale.stateManager.eventBroadcaster.addListener(
	 *       bale.stateManager.eventNames.changeView,
	 *	     method-to-call,
	 *	     scope-to-call-method-in
	 *    )
	 */
	eventBroadcaster : new EventBroadcaster(),
	
	/** list of valid event names */
	eventNames:{
		changeView : "changeView",
		changeMedia : "changeMedia",
		changeProduct : "changeProduct",
		changeColor : "colorName",
		changeCatThumb : "catThumb",
		changeSendToFriend : "sendToFriend",
		changeSizeGuide : "sizeGuide"
	},
	
	/** @private */
	currentView : null,
	/** @private */
	currentProduct:null,
	/** @private */
	currentMedia:null,
	/** @private */
	currentColor:null,
	/** @private */
	currentSendToFriendViewable:false,
	/** @private */
	currentCatThumb:null,
	currentSizeGuideViewable : false,
	/**
	 * Changes the current view state and broadcasts event
	 * @param {string} newView name of the new view. valid view names are same as the internationalization <bale.lang> object 
	 */
	 
	setView : function(newView){
		console.log('new view', newView)
		if(this.currentView != newView){
			var eventToFire = this.eventNames.changeView;
			fromTo = {
				from: this.currentView , 
				to:newView
			};
			console.log('EVENT - changeView',fromTo);
			this.currentView =  newView;
			this.eventBroadcaster.fireEvent(eventToFire, fromTo);
		}
	},
	/**
	 * sets if the the send to friend should be opened of closed.
	 * @param {string} either "open" or "close"
	 */
	setSendToFriend : function(openOrClose){
		if(this.currentSendToFriendViewable != openOrClose){
			console.log('EVENT stateChange :',openOrClose);
			this.currentSendToFriendViewable = openOrClose;
			var eventToFire = this.eventNames.changeSendToFriend;
			this.eventBroadcaster.fireEvent(eventToFire, openOrClose);
		}
	},
	
	setSizeGuide : function(openOrClose){
		if(this.currentSizeGuideViewable != openOrClose){
			console.log('EVENT stateChange :',openOrClose);
			this.currentSizeGuideViewable = openOrClose;
			var eventToFire = this.eventNames.changeSizeGuide;
			this.eventBroadcaster.fireEvent(eventToFire, openOrClose);
		}
	},
	/**
	 * Changes the current product and broadcasts event
	 * @param {object} product product data object 
	 */
	setCurrentProduct:	function (product){
		if(this.currentProduct != product){
			this.currentProduct = product;
			if(bale.pageInfo.isCategoryPage()){
				//currentMedia = product.media[0].name;
				this.setCurrentMedia(product.media[0].id);
			}else{
				this.currentMedia = product.media[0].id;
				this.setColor(product.colors[0].name);
			}
		}
	},
	/**
	 * Changes the current active category thumbnail and broadcasts event
	 * @param {object} product product data object 
	 */
	setCurrentCatThumb:	function (productId){
		if(this.currentCatThumb != productId){
			this.currentCatThumb = productId;	
			var eventToFire = this.eventNames.changeCatThumb;
			console.log('EVENT - '+this.eventNames.changeCatThumb,productId);
			this.eventBroadcaster.fireEvent(eventToFire, productId);
		}
	},
	/**
	 * Changes the current active category thumbnail  and broadcasts event
	 * @param {object} product product data object 
	 */
	setCurrentMedia:function(mediaName){
		if(this.currentMedia != mediaName){
			var eventToFire = this.eventNames.changeMedia;
			this.currentMedia = mediaName;
			console.log('EVENT - '+this.eventNames.changeMedia,mediaName);
			this.eventBroadcaster.fireEvent(eventToFire, mediaName);
		}
	},
	/**
	 * Changes the current color and broadcasts event
	 * @param {string} colorName 
	 */
	setColor:function(colorName){
		var eventToFire = this.eventNames.changeColor;
		this.currentMedia = colorName;
		console.log('EVENT - '+eventToFire,colorName);
		this.eventBroadcaster.fireEvent(eventToFire, colorName);
		//this.buildHash();
		//alert (colorName);
	}
}

/**
 * handels animation among the different product & category views
 */
bale.transitioner = {
	
	init : function(){
		console.log('-initializing bale.transitioner.init');
		
		console.log('  setting event listeners for view changes');
		bale.stateManager.eventBroadcaster.addListener(
		bale.stateManager.eventNames.changeView,
		bale.transitioner.transition,
		bale.transitioner
		)
	},
	
	/**
 	* animates the view
 	* @param {object} fromTo object in form {from:"view name",to:"view name"}
 	*/
	transition : function(fromTo){
	
		console.log(' recieved event -bale.transitioner.transition', fromTo);

		if(fromTo.from == bale.lang.categoryView && fromTo.to == bale.lang.mediaView ){
			$('#bale-productView').stop().animate({
      			left:0
      			}, 1500);
		}else if(fromTo.from == bale.lang.mediaView && fromTo.to == bale.lang.categoryView){
			$('#bale-productView').stop().animate({
      			left:960
      			},1500)
		}else if(fromTo.from == bale.lang.mediaView && fromTo.to == bale.lang.mediaToDetails){
			$("#bale-zoomable").fadeOut(500,function(){
				var hash = "";
				if(bale.config.useHash){
					hash = "#"+bale.lang.mediaToDetails;
					bale.config.ready = false;
				}
				window.location = bale.stateManager.currentProduct.url+hash;
			}
		)}else if(fromTo.from == bale.lang.mediaView && fromTo.to == bale.lang.mediaToColor){
			$("#bale-zoomable").fadeOut(500,function(){
				var hash = "";
				if(bale.config.useHash){
					hash = "#"+bale.lang.mediaToColor;
					bale.config.ready = false;
				}
				window.location = bale.stateManager.currentProduct.url+hash;
			}
		)}else if(fromTo.from == null && fromTo.to == bale.lang.mediaToDetails){
				$("#bale-productDetails-photo").css('display','none');
				
				$("#bale-productHolder").css('left','837px').addClass('out').animate({
	      			left:480
	   				   }, 1250 ,function(){
	   						$("#bale-productDetails-photo").fadeIn(500,function(){
	   							bale.stateManager.setView(bale.lang.detailsView);
	   						});	
	   			})
		}else if(fromTo.from == bale.lang.detailsView && fromTo.to == bale.lang.mediaToDetails){
			$("#bale-productDetails-photo").fadeOut(500, function(){
								$("#bale-productHolder").stop().removeClass('out').animate({
					      			left:837
					   				   }, 1250 ,function(){
							   				pageInLimboBool = true;
							   				history.go(-1);
											bale.config.ready = false;
					   				   })
			});
		}else if(fromTo.from == null && fromTo.to == bale.lang.mediaToColor){
			$('bale-productHolder').removeClass('out');
			$("#bale-productHolder li a.selected").removeClass("selected");
			$("#bale-productHolder").css('left','837px');
			$("#bale-productDetails-photo").css('display','none');
				$("#colorsNav").fadeIn(500)
				$("#bale-productDetails-photo").fadeIn(500,function(){
	   							bale.stateManager.setView(bale.lang.colorView);
	   						});	
				
		}else if(fromTo.from == bale.lang.colorView && fromTo.to == bale.lang.mediaToColor){
			$('bale-productHolder').removeClass('out');
			
			$("#colorsNav").fadeOut(500);
			$("#bale-productDetails-photo").fadeOut(500, function(){
	   				history.go(-1);
	   				bale.config.ready = false;	
		})
		}else if (fromTo.from == bale.lang.detailsView && fromTo.to == bale.lang.colorView){
			////alert('sss')
			$("#colorsNav").css("display","block");
			$("#bale-productHolder").stop().removeClass('out').animate({
      			left:837
   				   }, 1250 ,function(){
   				   	
	   		});
		}else if (fromTo.from == bale.lang.colorView && fromTo.to == bale.lang.detailsView){
			$("#bale-productHolder").stop().addClass('out').animate({
      			left:480
   				   }, 1250 ,function(){
   				   	$("#colorsNav").css("display","none");
   				   	
	   		});
		}else if (fromTo.from  == bale.lang.detailsView && fromTo.to == bale.lang.mediaView ){
			$("#colorsNav").css("display","none");
			$("#bale-productHolder").stop().removeClass('out').animate({
      			left:837
   				   }, 1250 ,function(){  	
	   		})
	   		$("#bale-zoomable").stop().addClass('out').animate({
	      				left:0
	   				   }, 1250 ,function(){
	   							//bale.stateManager.setView(bale.lang.detailsView);
	   			})
		}else if (fromTo.from == bale.lang.mediaView && fromTo.to  == bale.lang.detailsView ){
			$("#bale-zoomable").stop().addClass('out').animate({
	      				left:960
	   				   }, 1250 ,function(){
	   							
	   			})
	   		$("#bale-productHolder").stop().addClass('out').animate({
      								left:480
   				   					}, 1250)
		}else if (fromTo.from == bale.lang.colorView && fromTo.to == bale.lang.mediaView){
			$("#bale-zoomable").stop().addClass('out').animate({
      			left:0
   				   }, 1250 ,function(){
   						$("#colorsNav").css('display','none');
	   		});
		}else if (fromTo.from == bale.lang.mediaView && fromTo.to == bale.lang.colorView ){
			$("#colorsNav").css('display','block');
			$("#bale-zoomable").stop().addClass('out').animate({
				left:960
				   }, 1250 ,function(){
			})
		}else if (fromTo.from == null && fromTo.to == bale.lang.mediaView){
			$("#bale-zoomable").stop().addClass('out').animate({
      			left:0
   				   }, 1250 ,function(){
   						$("#colorsNav").css('display','none');
   						$("#bale-productDetails-photo").show();
	   		});
		}else if (fromTo.from == null && fromTo.to == bale.lang.colorView){
			$("#bale-productHolder li a.selected").removeClass("selected");
			$("#bale-productHolder").css('left','837px');
			$("#bale-productDetails-photo").css('display','none');
				$("#colorsNav").fadeIn(500)
				$("#bale-productDetails-photo").fadeIn(500,function(){
								$("#bale-productDetails-photo").show();
	   							bale.stateManager.setView(bale.lang.colorView);
	   						});	
		}else if (fromTo.from == null && fromTo.to == bale.lang.detailsView){
			$("#bale-productDetails-photo").fadeIn(400);
			//$("#bale-productHolder").css('left','480px');
			$("#bale-productHolder").stop().addClass('out').animate({
      								left:480
   				   					}, 1250)
		}
	}
}

/**
 * builds the functionality of the category thumbnails
 */
bale.catThumbs = new function(){
	var _currentSelectedID  = ""
	var _fadeSpeed = 250;
	this.slidePosition = 0;
	/** initializes the category thumbs*/
	this.init = function(){
		
		//setup listener in order to highlight.
		bale.stateManager.eventBroadcaster.addListener(
			bale.stateManager.eventNames.changeCatThumb,
			this.highlightThumb,
			this
		)
		
		console.log('init thumb scroller called');
		
		//find first thumbs ID, the first thumb should always be selected.
		var firstItemId = $("#bale-catThumbContainer li a").attr('id');
		this._currentSelectedID  = firstItemId;
		bale.stateManager.setCurrentCatThumb(this._currentSelectedID);
		
		this.attachHoverAndClicks();
	}
	
	/** @private performs the animation of a selected category thumb */
	this.highlightThumb = function(productID){
			$("#bale-catThumbContainer li#" + productID +" p").fadeTo(_fadeSpeed, 1);
			$("#bale-catThumbContainer li#" + productID +" img").fadeTo(_fadeSpeed, .3);
			$("#bale-catThumbContainer li#" + productID +" a");
	}
	
	/** @private called after a delay in order to accomidate quick mouse movement */
	
	this.delayedHighlight = function(productID){
		if(_currentSelectedID == productID){
			bale.stateManager.setCurrentCatThumb(productID)
		}
	}
	
	/** @private */
	this.attachHoverAndClicks = function(){
		//for all items in the library.
		for(prod in bale.productData.library){
			currentProductData = bale.productData.library[prod];
			
			$("#bale-catThumbContainer li a#"+currentProductData.id).hover(
				function(){
					elementId = $(this).attr('id');
					if(elementId !== _currentSelectedID){
						//fade out previous
						$("#bale-catThumbContainer li #" + _currentSelectedID +" p").fadeTo(_fadeSpeed , 0);
						$("#bale-catThumbContainer li #" + _currentSelectedID +" img").fadeTo(_fadeSpeed , 1);
						
						
						console.log(elementId);
						_currentSelectedID  = elementId;
						
						setTimeout("bale.catThumbs.delayedHighlight('"+ _currentSelectedID + "')" ,250)
						
						$(this).children("p").fadeTo(_fadeSpeed , 1);
						$(this).children("img").fadeTo(_fadeSpeed , .3);
					}
					
				},function(){}).click(function(){
					//alert(bale.productData.getProduct(_currentSelectedID));
					console.log(bale.productData.getProduct(_currentSelectedID))
					bale.stateManager.setCurrentProduct( bale.productData.getProduct(_currentSelectedID));
					bale.stateManager.setView(bale.lang.mediaView);
					return false;
			})
		}
	}
}

/**
 * builds the functionality of the color thumbnails in the productPage.
 */
bale.colorThumbs = new function(){

	var _fadeSpeed = 250;
	var _currentSelection= null;
	
	/** initializes the color thumbnails */
	this.init = function(){
		//setup listener which highlights a thumb
		bale.stateManager.eventBroadcaster.addListener(
			bale.stateManager.eventNames.changeColor,
			this.setSelected,
			this
		)
		this.attachHoverAndClick();
	}
	
	/** fades up the hovered thumbnail and dehighlights the previous */
	this.setSelected = function(colorName){
		if(_currentSelection != colorName){
			//alert(colorName);
			$("#colorsNav li a.selected p").fadeTo(_fadeSpeed , 0);
			$("#colorsNav li a.selected img").fadeTo(_fadeSpeed , 1);
		
			$('#colorsNav li a.selected').removeClass("selected");
			
			activeAnchor = $("#colorsNav li a#"+colorName );
			console.log(activeAnchor.length);
			activeAnchor.addClass("selected");
			activeAnchor.children("p").fadeTo(_fadeSpeed , 1);
			activeAnchor.children("img").fadeTo(_fadeSpeed , .4);
			_currentSelection = colorName
		}
	}
	
	/** @private */
	this.attachHoverAndClick = function(){
		
		$("#colorsNav li a").hover(
				function(event){
					console.log(this);
					getId = $(this).attr( 'id' );
					//alert(getId);
					bale.stateManager.setColor(getId);
					
				}, function(){
				}).click( function(){
					//this is where you would put JS to switch colors on the same page.
				})
	};
}


/**
 * Creates the product-details clickable area in the media and color views 
 * A thin tall sliver with a small arrowpointing left.
 */	
bale.detailsClickable = {
	
	currentlyClickable: false,
	/**
	 * initializes the controller 
	 */
	init:function(){
		bale.stateManager.eventBroadcaster.addListener(
		bale.stateManager.eventNames.changeView,
		this.viewChange,
		this
		)	
	},
	/** @private attaches click to the product details sliver */
	bindClickable:function(){
		$(".bale-arrow").click( function(){ 
			bale.stateManager.setView(bale.lang.detailsView)
		});
		this.currentlyClickable = true;
	},
	/** @private removes hover and clicks to the product details sliver */
	unbindClickable:function(){
		$("#bale-arrow").unbind('click').unbind('mouseout').unbind('mouseover')
		this.currentlyClickable = false;
	},

	/** changes the events depending on the view
	 *  @param {object} fromTo
	 */
	viewChange:function(fromTo){
		if(fromTo.to != bale.lang.detailsView){
			if(!this.currentlyClickable)this.bindClickable();
		}else{
			this.unbindClickable()	
		}
	}
}

function playVideo(){
	
	
}
bale.mediaTransition = new function(){
	
	
	//this variable is because we don't want the first mediaSelect to replace attempt to replace the default media
	//before the default media has itself been initialized.
	//without this there was an error from Scene 7.
	
	
	this.mediaSelect = function(mediaName){
		//alert(bale.config.ready);
		if(bale.config.ready){
			
		console.log(bale.stateManager.currentProduct);
		console.log(bale.stateManager.currentProduct);
		console.log(bale.stateManager.currentProduct);
		console.log(bale.stateManager.currentProduct);
			//get the currentActive Media
			var selectedMedia = bale.productData.getMediaById(mediaName,bale.stateManager.currentProduct);
			
	        if ( selectedMedia ) {
				if (selectedMedia.type == 'zoom') {
					s7zoom.setImage(selectedMedia.url, true);
					stopMovie();
					$('#bale-zoomFadeable').fadeIn(650);
				}
				else if (selectedMedia.type == 'video') {
					$('#bale-zoomFadeable').fadeOut(800, function(){
						playMovie(selectedMedia.url);
					});
				}
			}
		}
	}
	this.stopVideo=function(){
		stopMovie();
	}
	
	
	this.getSelectedHashMedia = function(products,pageId){
		return '';
	}
	
	this.init = function(){
		
		bale.stateManager.eventBroadcaster.addListener(
			bale.stateManager.eventNames.changeMedia,
			this.mediaSelect,
			this
		)
		bale.stateManager.eventBroadcaster.addListener(
		bale.stateManager.eventNames.changeView,
		this.stopVideo,
		this
		)	
	}
	
	this.init();
}



	baleCatThumbScroll = {
			
			//qty of ULs in one view
			visibleDivisions:3,
			
			//all possible positions
			positions:new Array(),
			
			//current position
			currentPosition:0,
			
			//div to apply the classes to
			parentElement:null,
			
			wishlistControls:null,
			
			init: function(){							
				
				this.parentElement = $('.bale-catSlider');
				
				this.wishlistControls = $("#bale-thumbControls");
				var qtyDivisions = this.parentElement.children('ul').length;
				
				//find how many whole view fit into the main view
				var divCount = Math.floor(qtyDivisions/this.visibleDivisions) -1;
				
				for (i=0; i <= divCount; i++){
					//for each view puts its pixel location into postitions
					this.positions.push(-480*i)
				}
				
				//find the modulus remainder
				remainder = qtyDivisions % this.visibleDivisions;
				
				//if more than zero add it to the positions
				if(remainder > 0){
					remainder = 161*remainder;
					remainder = this.positions[this.positions.length-1] - remainder;
					this.positions.push(remainder);
				}
				this.enableButtons();
				$('.bale-thumbNext').click(function(){baleCatThumbScroll.moveNext();return false;})
				$('.bale-thumbBack').click(function(){baleCatThumbScroll.moveBack();return false;})		
			},
			
			enableButtons:function(){
				
				if (this.positions.length-1 > this.currentPosition && this.currentPosition >= 0){
					//next button needs to be activated
					if(!this.wishlistControls.hasClass('bale-nextActive')) this.wishlistControls.addClass('bale-nextActive');
				}else{
					//next button needs to be inactive
					this.wishlistControls.removeClass('bale-nextActive');
				}
				
				if (this.positions.length >= this.currentPosition && this.currentPosition > 0){
	
					//back button needs to be active
					if(!this.wishlistControls.hasClass('bale-backActive')) this.wishlistControls.addClass('bale-backActive');
				}else{
					//back button needs to be inactive
					this.wishlistControls.removeClass('bale-backActive');
				}
				console.log("this.currentPosition",this.currentPosition)		
			},
			
			moveNext : function(){
				if (this.positions.length-1 > this.currentPosition ){
					this.currentPosition ++;				
					
					var distance = Math.abs(this.positions[this.currentPosition]) - Math.abs(this.positions[this.currentPosition -1])
					var speed = Math.round(distance/161)*700;
					
					this.parentElement.animate({left:this.positions[this.currentPosition]}, speed);
					this.enableButtons();
				}
			},
			
			moveBack : function(){
				if (this.currentPosition > 0){
					this.currentPosition --;
					
					var distance = Math.abs(this.positions[this.currentPosition +1] - this.positions[this.currentPosition] );					
					var speed = Math.round(distance/161)*700;
					
					this.parentElement.animate({left:this.positions[this.currentPosition]}, speed);
					this.enableButtons();
				}
			}
			
		}
		
baleColorScroll = {
			
			//qty of ULs in one view
			visibleDivisions:2,
			
			//all possible positions
			positions:new Array(),
			
			//current position
			currentPosition:0,
			
			//div to apply the classes to
			parentElement:null,
			
			wishlistControls:null,
			
			init: function(){
							
				
				this.parentElement = $('#bale-colorNavSlidable');
				this.wishlistControls = $("#bale-colorsnavControls");
				var qtyDivisions = this.parentElement.children('ul').length;
				
				//find how many whole view fit into the main view
				var divCount = Math.floor(qtyDivisions/this.visibleDivisions) -1;
				
				for (i=0; i <= divCount; i++){
					//for each view puts its pixel location into postitions
					this.positions.push(-358*i)
				}
				
				//find the modulus remainder
				remainder = qtyDivisions % this.visibleDivisions;
				
				//if more than zero add it to the positions
				if(remainder > 0){
					remainder = 179*remainder;
					remainder = this.positions[this.positions.length-1] - remainder;
					this.positions.push(remainder);
				}
				this.enableButtons();
				$('.bale-thumbNext').click(function(){baleColorScroll.moveNext();return false;})
				$('.bale-thumbBack').click(function(){baleColorScroll.moveBack();return false;})		
			},
			
			enableButtons:function(){
				
				if (this.positions.length-1 > this.currentPosition && this.currentPosition >= 0){
					//next button needs to be activated
					if(!this.wishlistControls.hasClass('bale-nextActive')) this.wishlistControls.addClass('bale-nextActive');
				}else{
					//next button needs to be inactive
					this.wishlistControls.removeClass('bale-nextActive');
				}
				
				if (this.positions.length >= this.currentPosition && this.currentPosition > 0){
	
					//back button needs to be active
					if(!this.wishlistControls.hasClass('bale-backActive')) this.wishlistControls.addClass('bale-backActive');
				}else{
					//back button needs to be inactive
					this.wishlistControls.removeClass('bale-backActive');
				}
				console.log("this.currentPosition",this.currentPosition)		
			},
			
			moveNext : function(){
				if (this.positions.length-1 > this.currentPosition ){
					this.currentPosition ++;				
					
					var distance = Math.abs(this.positions[this.currentPosition]) - Math.abs(this.positions[this.currentPosition -1])
					var speed = Math.round(distance/179)*700;
					
					this.parentElement.animate({left:this.positions[this.currentPosition]}, speed);
					this.enableButtons();
				}
			},
			
			moveBack : function(){
				if (this.currentPosition > 0){
					this.currentPosition --;
					
					var distance = Math.abs(this.positions[this.currentPosition +1] - this.positions[this.currentPosition] );					
					var speed = Math.round(distance/179)*700;
					
					this.parentElement.animate({left:this.positions[this.currentPosition]}, speed);
					this.enableButtons();
				}
			}
			
		}
	

bale.productNav = new function(){

	var _currentSelectedID = "";
	var _fadeSpeed = 250;
	
	this.isIn = true;
	this.isBuilt = false;
	this.colorIn = false;
	this.currentLinksProduct = null;
	
	
	this.buildMediaLinks = function(){
		var linksHTML = "";
		//alert(linksHTML);
		var productData = bale.stateManager.currentProduct;
		
		//never need to rebuild if this is a productPage
		if (bale.pageInfo.isCategoryPage() && productData) {
		
			//for each media item in the current product
			for (i = 0; i < productData.media.length; i++) {
			
				//build the links
				var imageData = productData.media[i];
				linksHTML = linksHTML + '<li><a title="' + imageData.name + '" class="' + imageData.id + '" href="' + imageData.url + '"';
				linksHTML = linksHTML + '" >' + imageData.name + '</a></li>';
				
			}
			
			//now add the view colors and product details
			linksHTML = linksHTML + '<li><a class="view-colors" href="#" >'+bale.lang.viewColors +'</a></li>';
			linksHTML = linksHTML + '<li class="productDetails"  ><a href="#" class="productDetails" >'+bale.lang.viewProductDetails +'</a></li>';
			
			//alert(linksHTML);
			
			//set content of buildNav
			$("#bale-buildNav").html(linksHTML);
			
			//re-init all the clicks
			this.attachEvents();
		};
		
		this.currentLinksProduct = bale.stateManager.currentProduct;
	}
	
	this.init = function(){
		this.buildMediaLinks();
		this.mediaSelect(bale.stateManager.currentMedia)
	}
	
	
	this.mediaSelect = function(event){
	
		console.log('  recieved event @ bale.productNav.mediaSelect', event);
		var currentMedia = bale.stateManager.currentMedia;
		console.log('     trying to set current media link selected', currentMedia);
		
		
		//if the current selected product isn't the same
		//as the current media links we need to rebuild 
		if (bale.stateManager.currentProduct != this.currentLinksProduct) {
			this.buildMediaLinks();
		}
		
		
		$("#bale-productHolder li a.selected").removeClass("selected");
		
		//get the current MediaAnchor and set as selected
		
		var activeAnchor = $("#bale-productHolder li a." + currentMedia);
		activeAnchor.addClass("selected");
	}
	
	bale.stateManager.eventBroadcaster.addListener(bale.stateManager.eventNames.changeMedia, this.mediaSelect, this)
	
	this.mediaViewIn = function(tofrom){
		//alert('view change');
	}
	
	bale.stateManager.eventBroadcaster.addListener(bale.stateManager.eventNames.changeView, this.mediaSelect, this)
	
	this.attachEvents = function(){
		$("#bale-buildNav li a").click(bale.productNav.eventClick).each(function(){
			console.log("-attachEvents to productNav -", this);
		})
	};
	
	this.elementHasSelectedClass = function(element){
	
		if (String($(element).attr('class').indexOf('selected')) != -1) {
			//alert('ash selected');
			return true;
		}
		else {
			//alert('not selectd');
			return false;
		}
	}
	
	this.eventClick = function(event){
		console.log(event);
		
		if (($(event.target).attr('class') != "productDetails") &&
		($(event.target).attr('class') != "view-colors")) {
			bale.stateManager.setCurrentMedia($(event.target).attr('class'));
			bale.stateManager.setView(bale.lang.mediaView);
		}
		
		if ($(event.target).attr('class') == "productDetails") {
			if (bale.pageInfo.isProductPage()) {
				bale.stateManager.setView(bale.lang.detailsView);
			}
			else {
				consol.log('  - click trying to transition to product Details view');
				bale.stateManager.setView(bale.lang.mediaToDetails);
			}
		}
		if ($(event.target).attr('class') == "view-colors") {
			(bale.pageInfo.isProductPage()) ? bale.stateManager.setView(bale.lang.colorView) : bale.stateManager.setView(bale.lang.mediaToColor)
		}
		return false;
	}	
	
	this.mediaSelect = function(event){
	
		console.log('  recieved event @ bale.productNav.mediaSelect', event);
		var currentMedia = bale.stateManager.currentMedia;
		console.log('     trying to set current media link selected', currentMedia);
		
		
		//if the current selected product isn't the same
		//as the current media links we need to rebuild 
		if (bale.stateManager.currentProduct != this.currentLinksProduct) {
			this.buildMediaLinks();
		}
		
		
		$("#bale-productHolder li a.selected").removeClass("selected");
		
		//get the current MediaAnchor and set as selected
		
		var activeAnchor = $("#bale-productHolder li a." + currentMedia);
		activeAnchor.addClass("selected");
	}
	
	bale.stateManager.eventBroadcaster.addListener(bale.stateManager.eventNames.changeMedia, this.mediaSelect, this)
	
	this.mediaViewIn = function(tofrom){
		//alert('view change');
	}
	
	bale.stateManager.eventBroadcaster.addListener(bale.stateManager.eventNames.changeView, this.mediaSelect, this)
	
	this.attachEvents = function(){
		$("#bale-buildNav li a").click(bale.productNav.eventClick).each(function(){
			console.log("-attachEvents to productNav -", this);
		})
	};
	
	this.elementHasSelectedClass = function(element){
	
		if (String($(element).attr('class').indexOf('selected')) != -1) {
			//alert('ash selected');
			return true;
		}
		else {
			//alert('not selectd');
			return false;
		}
	}
	
	this.eventClick = function(event){
		console.log(event);
		
		if (($(event.target).attr('class') != "productDetails") &&
		($(event.target).attr('class') != "view-colors")) {
			bale.stateManager.setCurrentMedia($(event.target).attr('class'));
			bale.stateManager.setView(bale.lang.mediaView);
		}
		
		if ($(event.target).attr('class') == "productDetails") {
			if (bale.pageInfo.isProductPage()) {
				bale.stateManager.setView(bale.lang.detailsView);
			}
			else {
				console.log('  - click trying to transition to product Details view');
				bale.stateManager.setView(bale.lang.mediaToDetails);
			}
		}
		if ($(event.target).attr('class') == "view-colors") {
			(bale.pageInfo.isProductPage()) ? bale.stateManager.setView(bale.lang.colorView) : bale.stateManager.setView(bale.lang.mediaToColor)
		}
		return false;
	}
}


bale.history ={};

bale.history = new function (){
	var stateVar;
	var callBackStateManager = true;
	
	//recieves notification of stateManager updates
	this.buildNewHash = function(viewChangeType){
		//alert('test');
		if(bale.pageInfo.isCategoryPage()){
			switch (viewChangeType.to){
				case bale.lang.mediaView:
					//alert('media view')
					this.setHistory(bale.stateManager.currentProduct.urlSlug+'/'+bale.stateManager.currentView+ "/"+bale.stateManager.currentMedia,false);
				break;
				case bale.lang.categoryView:
					if(unFocus.History.getCurrent() != "") this.setHistory("",false);
				break;
				default : if(bale.stateManager.currentView == bale.lang.mediaView){
						//alert('currentMedia Exists')
						this.setHistory(bale.stateManager.currentProduct.urlSlug+'/'+bale.stateManager.currentView+ "/"+bale.stateManager.currentMedia,false);
					}
			}
		}else if(bale.pageInfo.isProductPage()){
			if (bale.stateManager.currentView == bale.lang.detailsView){
				
				if(unFocus.History.getCurrent() != "")this.setHistory(bale.lang.detailsView,false);
			} 
			if (bale.stateManager.currentView == bale.lang.colorView) this.setHistory(bale.stateManager.currentView,false);
			if(bale.stateManager.currentView == bale.lang.mediaView){
				this.setHistory(bale.stateManager.currentView + "/" + bale.stateManager.currentMedia,false)
			}
		}
	}
	
	if(bale.config.useHash){
		//recieve notification of media changes 
		bale.stateManager.eventBroadcaster.addListener(
			bale.stateManager.eventNames.changeMedia,
			this.buildNewHash,
			this
		)
		
		//recieve notification of viewchamges
		bale.stateManager.eventBroadcaster.addListener(
			bale.stateManager.eventNames.changeView,
			this.buildNewHash,
			this
		)
	}
		
	this.categoryLoad = function(historyHash){
		
		splitHash = historyHash.split('/')
		var numberOfHash = splitHash.length;
		if(numberOfHash == 3){
			$("#bale-productView").css('left','0px');
			$("#bale-productHolder").css('left','837px').removeClass('out');
	   		$("#bale-zoomable").hide().css('left','0px').fadeIn(500,function(){})
	   		
	   		bale.stateManager.currentView = splitHash[1];
	   		bale.stateManager.setCurrentProduct(bale.productData.getProductBySlug(splitHash[0]));
	   		bale.productNav.init();
	   		
	   		bale.stateManager.setCurrentMedia(splitHash[2]);
	   		
	   		}else{
	   			$("#bale-zoomable").show();
	   		}
	}
	
	this.productPageLoad = function(currentHistory){
		if(currentHistory == "" ||currentHistory == bale.lang.detailsView){
			bale.stateManager.setView(bale.lang.detailsView);
		}else if(currentHistory == bale.lang.mediaToDetails ||currentHistory == bale.lang.colorView || currentHistory == bale.lang.mediaToColor){
			bale.stateManager.setView(currentHistory);
		}else{
			bale.stateManager.setCurrentMedia(currentHistory.split('/')[1]);	
			bale.stateManager.setView(currentHistory.split('/')[0]);	
		}
	}
	
	this.historyListener = function(historyHash) {
		
		if(callBackStateManager){
			
			stateVar = historyHash;
		
			console.log(historyHash, 'info');

			if (historyHash == "" && bale.pageInfo.isCategoryPage()) {				
				bale.stateManager.setView(bale.lang.categoryView);
			}else if (historyHash == "" && bale.pageInfo.isProductPage()) {		
				console.log('should go to product page',bale.lang.detailsView);	
				bale.stateManager.setView(bale.lang.detailsView);
			}
			else {
			
				//now count substrings
				hashArray = historyHash.split('/');
				var numberOfHash = hashArray.length;
				//alert(historyHash);
				if(numberOfHash == 1){
					if(bale.pageInfo.isProductPage()) bale.stateManager.setView(historyHash);
				}else if (numberOfHash == 2){
					if(hashArray[0] == bale.lang.mediaView){
						bale.stateManager.setCurrentMedia(hashArray[1]);
						bale.stateManager.setView(bale.lang.mediaView);
					}else if(hashArray[0] == bale.lang.colorView){
						bale.stateManager.setColor(hashArray[1]);
						bale.stateManager.setView(hashArray[0]);
					}
				}else if(numberOfHash == 3){
						bale.stateManager.setCurrentProduct(bale.productData.getProductBySlug(hashArray[0]));
						bale.stateManager.setCurrentMedia(historyHash.split('/')[2]);
						bale.stateManager.setView(bale.lang.mediaView);
				}
			}
		}
		callBackStateManager = true
	};
	
	unFocus.History.addEventListener('historyChange', this.historyListener);
	this.setHistory = function (newHash, callback){
		callBackStateManager = callback;
		console.log(newHash);
		unFocus.History.addHistory(newHash);
	}
}

console.log("bale.config.useHash - ",bale.config.useHash);
if(bale.config.useHash == false){
	console.log('no hash');
	delete bale.history;
	bale.history=function(){
		this.setHistory = function(){};
		this.historyListener = function(){};
	}
}

$(document).ready(function(){
	
	console.log(bale.pageInfo.isProductPage());
	if( bale.pageInfo.isCategoryPage() ){
		initCategoryPage();
	}else if(bale.pageInfo.isProductPage()){
		var productPageInterval = setInterval(function(){
			if(bale.stateManager.currentProduct){
			    clearInterval(productPageInterval);
			    initProductPage();
			}
		}, 1200);
	}
});

bale.sendToFriend = new function(){

	this.animate = function(openOrClose){
		console.log('EVENT RECIEVED @ bale.sendToFriend.animte event :',openOrClose);
		
		if(openOrClose == "open") $('#bale-sendToFriendSlideOut').animate({left:37},900);
		if(openOrClose == "close") $('#bale-sendToFriendSlideOut').animate({left:387},900);
	}
	
	this.init = function(){
		console.log('INIT bale.sendToFriend:', this);
		
		$('.bale-sendToFriendLink').click(function(){bale.stateManager.setSendToFriend('open');return false});
		$('#bale-sendToFriendSlideOut .bale-closeLink a').click(function(){bale.stateManager.setSendToFriend('close');return false;});
		
		//remove possible hash
		var cleanUrl = window.location.href.split('#')[0];
		console.log('setting directlink in send to friend:',cleanUrl);
		$('#directLink').attr('value',cleanUrl);
		
		//setup even listener to animate
		bale.stateManager.eventBroadcaster.addListener(
		bale.stateManager.eventNames.changeSendToFriend,
		this.animate,
		this);
		
		//setup even listener to call close when switching views
		bale.stateManager.eventBroadcaster.addListener(
		bale.stateManager.eventNames.changeView,
		this.setClose,
		this);
	}
	
	this.setClose = function(){	
		bale.stateManager.setSendToFriend('close');
	}
}



bale.sizeGuide = new function(){

	this.animate = function(openOrClose){
		console.log('EVENT RECIEVED @ bale.sizeGuide.animate event :',openOrClose);
		
		if(openOrClose == "open") $('#bale-sizeGuideProduct').animate({left:37},900);
		if(openOrClose == "close") $('#bale-sizeGuideProduct').animate({left:387},900);
	}
	
	this.init = function(){
		console.log('INIT bale.sizeGuide:', this);
		
		$('.bale-sizeGuide a').click(function(){bale.stateManager.setSizeGuide('open');return false});
		$('#bale-sizeGuideProduct .bale-closeLink a').click(function(){bale.stateManager.setSizeGuide('close');return false;});
				
		//setup even listener to animate
		bale.stateManager.eventBroadcaster.addListener(
		bale.stateManager.eventNames.changeSizeGuide,
		this.animate,
		this);
		
		//setup even listener to call close when switching views
		bale.stateManager.eventBroadcaster.addListener(
		bale.stateManager.eventNames.changeView,
		this.setClose,
		this);
	}
	
	this.setClose = function(){	
		bale.stateManager.setSizeGuide('close');
	}
}

function initCategoryPage(){
	if(!bale.config.ready){	
	
		bale.transitioner.init();
		if ($('.bale-catSlider li').length > 12) {
			baleCatThumbScroll.init();
		}
		else {
			$("#bale-thumbControls").hide();
		}
		
		 
		baleCatFullPhoto = new balePhotoTransition();
		baleCatFullPhoto.init('#bale-fullCatPhoto');
			
		bale.stateManager.eventBroadcaster.addListener(
			bale.stateManager.eventNames.changeCatThumb,
			function(productId){
				var currentProd = bale.productData.getProduct(productId);
				baleCatFullPhoto.switchPhoto(currentProd.catLargeImage)
			}
			,
			baleCatFullPhoto
		)
		
		bale.catThumbs.init();
		bale.productNav.init();	
		
		$('#bale-zoomable').show();
		
		bale.stateManager.currentView = bale.lang.categoryView;
		console.log(bale.stateManager)
		if(bale.config.usehash){
			bale.history.categoryLoad("");
		}else{
			bale.stateManager.setView(bale.lang.categoryView);
		}
		bale.config.ready = true;
		//setInterval ( 'initCategoryPage()', 500 );
		
	}
}

function initProductPage2(colour){
	var col = colour;
	
	bale.detailsClickable.init();
    
	$('input:checkbox').checkbox({cls:'bale-checkbox',empty:"/us/en/images/empty.png"});
	//baleNavBlock.init("#bale-mainNav");
	if(!bale.config.ready){
		
		bale.transitioner.init();
		bale.sizeGuide.init();
		bale.sendToFriend.init();
		
			//only attach CSS if JS
	
		$(document).ready(function(){
			$('#bale-sizeGuideProduct #bale-scrollable').jScrollPane({maintainPosition :true,scrollbarWidth:5});
			
		});
		
		//setup back an forward scrolling
		if ($('#bale-colorNavSlidable ul').length > 2) {
			baleColorScroll.init();
		}
		else {
			$("#bale-colorsnavControls").hide();
		}
			
		$('#bale-zoomable').show();
		
		baleProductAndColorPhoto = new balePhotoTransition();
		baleProductAndColorPhoto.init('#bale-productDetails-photo');
		
		bale.stateManager.eventBroadcaster.addListener(
		bale.stateManager.eventNames.changeColor,
		function(colorName){
			colorData = bale.productData.getColorByName(colorName,bale.stateManager.currentProduct);
			baleProductAndColorPhoto.switchPhoto(colorData.image);
		}
		)
		bale.stateManager.eventBroadcaster.addListener(
		bale.stateManager.eventNames.changeView,
		function(colorName){
			colorData = bale.productData.getDefaultColor();
			$('#bale-productDetails-photo #detailsPhoto').attr('src',colorData.image)
		}
		)
		
		bale.stateManager.eventBroadcaster.addListener(
		bale.stateManager.eventNames.changeView,
			function(toFrom){
					//alert(toFrom.to);
				if(toFrom.to == bale.lang.detailsView){	
					//alert(toFrom.to + "x");
					$("#bale-productHolder li a.selected").removeClass("selected");
					$("#bale-productHolder li.productDetails a").addClass("selected");
				}else if(toFrom.to == bale.lang.colorView){
					//alert(toFrom.to + "x");
					$("#bale-productHolder li a.selected").removeClass("selected");
					$("#bale-productHolder li a.view-colors").addClass("selected");
				}
			}
		)
		
		bale.colorThumbs.init();
		bale.stateManager.setColor(col);
		
		bale.productNav.attachEvents();	
		
		bale.config.ready = true;
		
		if(bale.config.useHash){
			bale.history.productPageLoad(unFocus.History.getCurrent());
		}else{
			//bale.history.productPageLoad(bale.lang.detailsView);
			bale.stateManager.setView(bale.lang.detailsView)
			//$('body#bale-productCategory #bale-productView').css('left','0px');
		}
		setInterval ( "initProductPage2('"+col+"')", 1000 );
	}
}

function initProductPage(){
	
	$('input:checkbox').checkbox({cls:'bale-checkbox',empty:"images/empty.png"});
	//baleNavBlock.init("#bale-mainNav");
	if(!bale.config.ready){
		
		bale.transitioner.init();
		bale.sizeGuide.init();
		bale.sendToFriend.init();
		
			//only attach CSS if JS
	
		$(document).ready(function(){
			$('#bale-sizeGuideProduct #bale-scrollable').jScrollPane({maintainPosition :true,scrollbarWidth:5});
			
		});
		
		//setup back an forward scrolling
		if ($('#bale-colorNavSlidable ul').length > 2) {
			baleColorScroll.init();
		}
		else {
			$("#bale-colorsnavControls").hide();
		}
			
		$('#bale-zoomable').show();
		
		baleProductAndColorPhoto = new balePhotoTransition();
		baleProductAndColorPhoto.init('#bale-productDetails-photo');
		
		bale.stateManager.eventBroadcaster.addListener(
		bale.stateManager.eventNames.changeColor,
		function(colorName){
		    colorData = bale.productData.getColorByName(colorName,bale.stateManager.currentProduct);
			$('#bale-productDetails-photo #detailsPhoto').attr('src',colorData.image)
		}
		)
		bale.stateManager.eventBroadcaster.addListener(
		bale.stateManager.eventNames.changeView,
		function(colorName){
			colorData = bale.productData.getDefaultColor();
			$('#bale-productDetails-photo #detailsPhoto').attr('src',colorData.image)
		}
		)
		
		bale.stateManager.eventBroadcaster.addListener(
		bale.stateManager.eventNames.changeView,
			function(toFrom){
					//alert(toFrom.to);
				if(toFrom.to == bale.lang.detailsView){	
					//alert(toFrom.to + "x");
					$("#bale-productHolder li a.selected").removeClass("selected");
					$("#bale-productHolder li.productDetails a").addClass("selected");
				}else if(toFrom.to == bale.lang.colorView){
					//alert(toFrom.to + "x");
					$("#bale-productHolder li a.selected").removeClass("selected");
					$("#bale-productHolder li a.view-colors").addClass("selected");
				}
			}
		)
		
		bale.colorThumbs.init();
		bale.stateManager.setColor('color-one');
		
		bale.productNav.attachEvents();	
		
		bale.config.ready = true;
		
		if(bale.config.useHash){
			bale.history.productPageLoad(unFocus.History.getCurrent());
		}else{
			//bale.history.productPageLoad(bale.lang.detailsView);
			bale.stateManager.setView(bale.lang.detailsView)
			//$('body#bale-productCategory #bale-productView').css('left','0px');
		}
		setInterval ( 'initProductPage()', 1000 );
	}
}
