/**************************************************************************\
* Copyright 2006-2009 myShape Inc.                                         *
* --------------------------------------------                             *
* who to blame: Ryan Day =P                                                *
* --------------------------------------------                             *
*  This code is proprietary software; you cannot redistribute it           *
*  without the express written consent of myShape Inc.                     *
\**************************************************************************/

if(!myshape){
	var myshape = {}
};

if(!myshape.gadgets) {
	myshape.gadgets = {};
}

//lazyload constructor
myshape.lazyload = function(htmlServer,ajaxData,totalChunks,resultContainerSelector,nodeSelector){
	if(typeof(this.init) !== 'function'){//functional instantation
		return new this(htmlServer,ajaxData,totalChunks,resultContainerSelector);
	} else {//standard instantiation
		this.totalChunks = totalChunks || 0;
		this.htmlServer = htmlServer || '';
		this.ajaxData = ajaxData || {};
		this.selector = resultContainerSelector;//wherre you want the results to go
		this.nodeSelector = nodeSelector;//a selector that will match only result nodes
		this.init();
	}
};

//lazyload prototype
myshape.lazyload.prototype = {
	chunks:1,//we asume the first page of results has been loaded by default
	totalChunks:0,
	isLoading:0,
	perChunk:0,
	selector:false,
	nodeSelector:false,
	htmlServer:false,
	ajaxData:{},
	loadBeforeCollision:800,
	init:function(){
		var z = this;
		if(z.selector && $(z.selector).length && z.htmlServer){
			window.scroll(0,0);
			$(window).scroll(function(){
				z.loadMoreResults();
			});
			return true;
		}
		return false;
	},
	loadMoreResults:function(){
		if(this.chunks < this.totalChunks){
			var windowAtBottom = $(document).height()-$(window).height();

			var doLoadWhenTop = windowAtBottom-this.loadBeforeCollision;

			if(doLoadWhenTop <= $(window).scrollTop()){
				//increment chunk
				this.chunks++;
				this.loadResults(this.chunks);

			}
		}
	},
	loadResults:function(currentChunk){
		var z = this;

		z.showLoading(currentChunk);

		$.post(this.htmlServer, $.extend({'chunk-id':z.chunks},z.ajaxData), function(data){
			z.loadMoreResultsComplete(currentChunk,data);
		}, 'html');
	},
	loadMoreResultsComplete:function(currentChunk,html){
		var z = this;
		html = $.trim(html);
		if(html){
			$(html).insertBefore(z.getLoading(currentChunk));
		}
		$(z.getLoading(currentChunk)).remove();
	},
	showLoading:function(chunkNum){
		$(this.selector).append("<div class='lazy-loading chunk-"+this.chunks+" left' style='height:"+this.loadBeforeCollision+"px;width:"+($(this.selector).width()-5)+"px;text-align:center;padding-top:150px;'>"+myshape.util.loadingImageBig()+"</div>");
	},
	getLoading:function(chunkNum){
		return $(".lazy-loading.chunk-"+chunkNum)[0];
	}
};

/*************************
* gadgetTalkDebug
*	this listens to all gadget speak and logs it to the console
*/


myshape.gadgets.gadgetTalkDebug = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.gadgetTalkDebug();
	} else {
		this.init();
		return this;
	}
};

myshape.gadgets.gadgetTalkDebug.prototype = {
	init:function(){
		var z = this;
		z.inherit = myshape.gadget.inherit;
		z.inherit(myshape.gadget);
		this.listen('*',function(el,key,data){ z.hearGadget(el,key,data)});
	},
	hearGadget:function(el,key,data){
		$(el).log('gadget talked: '+key);
	}
};
/**************************/

/**************************
* Live chat link gadget
*
*/
myshape.gadgets.liveChat = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.liveChat();
	} else {
		this.init();
		return this;
	}
};

myshape.gadgets.liveChat.prototype = {
	gadgetSelector:".live-chat-link",
	init:function(){
		this.inherit = myshape.gadget.inherit;
		this.inherit(myshape.gadget);
		this.clickable();
	},
	clickable:function(){
		var z = this;
		$(z.gadgetSelector).live('click',function(){
			z.doState(this,'click');
			return false;
		});
	},
	states:{
		click:function(el,oldState){
			lpButtonCTTUrl = 'https://server.iad.liveperson.net/hc/91480167/?cmd=file&file=visitorWantsToChat&site=91480167&imageUrl=https://www.myshape.com/images/main/static/liveperson&referrer='+escape(document.location);
			try{
				lpButtonCTTUrl = (typeof(lpAppendVisitorCookies) != 'undefined' ? lpAppendVisitorCookies(lpButtonCTTUrl) : lpButtonCTTUrl);
				window.open(lpButtonCTTUrl,'chat91480167','width=472,height=320,resizable=yes');
			} catch (e){
				window.open(lpButtonCTTUrl,'chat91480167','width=472,height=320,resizable=yes');
			}
			return false;
		}
	}
};

/*************************
* bag gadget
*
*/
myshape.gadgets.bag = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.bag();
	} else {
		this.init();
		return this;
	}
};

myshape.gadgets.bag.prototype = {
	init:function(){
		var z = this;
		z.inherit = myshape.gadget.inherit;
		z.inherit(myshape.gadget);
	},
	counter:false,
	counterValue:0,
	conterText:'',
	updateCounter:function(val){
		if(!this.counter){
			this.counter = $("li.my-bag , li.my-bag-active").find("strong");
		}
		if(this.counter){
			if(!$(this.counter).hasClass('activated')){
				$(this.counter).addClass('activated');

				var parts = $(this.counter).html().split(' ');

				this.counterValue = +parts[0];
				parts[0] = '';
				this.counterText = parts.join(' ');
			}
			this.counterValue = val;
			$(this.counter).html('my bag ( '+this.counterValue+' )');
		}
	},
	states:{
		closed:function(el){
			this.getPopup(el).hide();
			return true;
		},
		opened:function(el){
			this.getPopup(el).show();
			return true;
		}
	}
};


myshape.gadgets.wishlister = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.bag();
	} else {
		this.init();
		return this;
	}
};
//TODO
myshape.gadgets.wishlister.prototype = {
	gadgetSelector:"a.add-wishlist",
	init:function(){
		var z = this;
		z.inherit = myshape.gadget.inherit;
		z.inherit(myshape.gadget);
	},
	clickable:function(){
		
	}
}

/********************************
style gadget

this gadget represents the product on the page
*/

myshape.gadgets.style = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.style();
	} else {
		this.init();
		return this;
	}
};

myshape.gadgets.style.prototype = {
	selectorNode:".product img",
	selectorClickable:".product img, .product .product-name a",
	imageSelector:".product-image img",
	isInit:false,
	init:function(){
		var z = this;
		z.inherit = myshape.gadget.inherit;
		z.inherit(myshape.gadget);

		z.hoverable();
		z.clickable();

		z.ears();
		z.isInit = true;
	},
	hoverable:function(){
		var z = this,speed = false;
		var settings = myshape.getGadget('popupSettings');
		if(z.isInit){
			$(this.selectorNode).dieHover();
			$(".style-popup-quick").dieHover();
			z.clickable();
		}
		switch(settings.getHoverSetting()){
			case "hs":
				speed = 2500;
			case "hf":
				speed = speed || 1300;
				var hoverFn = function(ev){
					z.doState(this,'activated',{
						styleID:z.getStyleID(this),
						image:z.getImage(this),
						wishlistCustomersID:z.getWishlistID(this),
						addToCartString:z.getCartString(this)
					});
				};

				$(this.selectorNode).liveHover(hoverFn,function(){},{on:speed});
				$(".style-popup-quick").liveHover(hoverFn,function(){},{on:speed});
		}
	},
	clickable:function(){
		var z = this;
		var clickFn = function(){
			z.doState(this,'activated');
			$(this).removeClass('jqhover');
			return false;
		};

		$(".style-popup-quick").live('click',clickFn)
		$(this.selectorClickable).live('click',clickFn);
	},
	ears:function(){
		var z = this;
		z.listen('stylePopup.wishlister.state.added',function(el,key,data){
			var details = $(".product input[value="+data.data.styleID+"]").parents(".product").find(".product_details div:last")[0];
			if(details){
				$(details).html('<a href="http://lazy.localhost/shop/wishlist"><div class="wishlist_product_view"/></a>');
			}
		});
		z.listen('popupSettings.state.settingChanged',function(el,key,data){
			z.hoverable();//reset hoverable
		});
	},
	states:{
		node:function(){},
		activated:function(el,oldState){
			el.state = 'node';//reset
			return true;
		}
	},
	//overload+extension!
	doState:function(node,state,data){

		//reset the element accociated with this state change to the container
		el = $(node).parents(".product")[0];
		if(!el){
			if($(node).hasClass('style-popup-quick')){
				el = node;
			} else {
				el = $(node).parents(".product")[0];
			}
		}
		if(el){
			data = $.extend(data,{
				styleID:this.getStyleID(el),
				wishlistID:this.getWishlistID(el),
				wishlistItemID:this.getItemID(el),
				cartString:this.getCartString(el),
				color:myshape.util.colorFromSrc($(this.getImage(el)).attr('src'))
			});
			this.parent.doState.call(this,el,state,data);
		}
	},
	getStyleID:function(el){
		return $(el).find("input[name=styleID]").val();
	},
	getWishlistID:function(el){
		return $(el).find("input[name=wishlist_id]").val() || false;
	},
	getCartString:function(el){
		return $(el).find("input.add_to_cart_checkbox").val() || false;
	},
	getItemID:function(el){
		var id = false;
		var str = this.getCartString(el);
		if(str){
			var str = str.split(',');
			if(str[4] && str[4].length){
				id = str[4];
			}
		}
		return id;
	},
	getNext:function(el){
		return $(el).next('.product')[0];
	},
	getPrevious:function(el){
		return $(el).prev('.product')[0];
	},
	getImage:function(el){
		return $(el).find(this.imageSelector)[0];
	},
	getByStyleID:function(styleID){
		return $(".product input[value="+styleID+"]").parents(".product")[0];
	},
	//this should be an extentsion of style gadget or on its own or somthing ... doesnt fit arch
	activateQuickPops:function(){
		/*var z = this;
		var popit = function(){
			var styleID = $(this).find("input[name=styleID]").val();
			if(styleID){
				z.showPopupFromData({styleID:styleID});
			}
			return false;
		};

		$(".style-popup-quick").liveHover(popit,function(){},{on:1500});

		$(".style-popup-quick").live('click',popit);*/
	}
};
/********************************
stylePopup gadget


$("<div id='test' class='product' style='width:200px;height:200px;background:purple;'><input type='hidden' value='13528' name='styleID'/></div>").appendTo('body').top(200).left(100);

this gadget is the popup product detail
*/

myshape.gadgets.stylePopup = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.stylePopup();
	} else {
		this.init();
		return this;
	}
}

myshape.gadgets.stylePopup.prototype = {
	nodeSelector:".style-expanded",
	gadgetSelector:".style-expanded",
	activeSelector:".style-expanded.active",
	cacheSelector:"#style-expanded-cache",
	templateSelector:"#style-expanded-template",
	loadingSelector:".style-expanded-loading",
	bodySelector:".style-expanded-body",
	tabContentSelector:".style-info-tab-cont",
	popLocked:false,
	commentsFound:false,
	init:function(){
		var z = this;
		z.inherit = myshape.gadget.inherit;
		z.inherit(myshape.gadget);
		z.ears();

		z.hoverable();

		z.zoomable();

		z.closeable();
		z.tabsClickable();
		z.outfitsPoppable();

		//z.activateQuickPops();

		z.swappable();
		z.addToGadgets();

		z.styleGadget = myshape.getGadget('style');
		z.thumbGadget = myshape.getGadget('thumbCarousel');
		z.colorSizeGadget = myshape.getGadget('colorSizePicker');
	},
	hoverable:function(){
		var z = this;
		$(z.activeSelector).liveHover(function(){},function(){
			if(!z.popLocked){
				z.doState(this,'closed');
			}
		},{off:900});
	},
	zoomable:function(){
		$(this.gadgetSelector+" .zoomable-image-gadget").liveHoverZoom(function(ev,conf){
			$(conf.zoomtarget).next().hide();
			$(conf.zoomtarget).show();
		},function(ev,conf){
			$(conf.zoomtarget).hide();
			$(conf.zoomtarget).next().show();
		},{zoomtarget:this.activeSelector+" .style-zoom-cont",zoomloading:function(){
			return $("<div>").html(myshape.util.loadingImage()+' loading...')[0];
		}}/*,{on:800}*/);//cannot make intent work right now
	},
	closeable:function(){
		var z = this;
		$(z.activeSelector+" .close-link").live('click',function(){
			z.doState($(this).parents(z.activeSelector),'closed');
		});
	},
	swappable:function(){
		var z = this;
		$(this.activeSelector+" .members-also-item-item").live('click',function(){
			var imageColor = myshape.util.colorFromSrc($($(this).find('img')[0]).attr('src'));
			var styleID = $(this).find("input[name=styleID]").val();

			var guide = $(this).find("span[name=guide]").html();
			if(guide){//the guide rank is the order in which the 
				var num = 0;
				$(this).parents(".membersalso").find("input[name=styleID]").each(function(){
					num++;
					if($(this).val() == styleID){
						return false;
					}
				});
				z.doState('mostViewedClicked',this,{styleID:styleID,rank:num,guide:guide});
			}

			z.showPopupFromData({styleID:styleID,color:imageColor});
		});
	},
	getStyleIDFromPopup:function(popup){
		return this.getNode(popup).find(".style-id.holder").html();
	},
	addToGadgets:function(){
		var z = this;

		$(z.nodeSelector+" .add-mybag").live('click',function(){
			if($(this).hasClass('pending-request')){
				return false;
			}

			$(this).addClass('pending-request');

			var button = this;

			var loadingBox = $(this).parents(z.nodeSelector).find(".mybag-loading")[0];
			$(loadingBox).show();

			var popup = z.getActive();

			var styleID = $(popup).find(".style-id.holder").html();

			var cartString = $(popup).find(".cart-string").html() || '';

			var colorSize = z.colorSizeGadget.getColorSize(popup);

			var quantity = z.colorSizeGadget.getQuantity(popup);

			var completeFunction = function(data){
				$(loadingBox).hide();
				$(button).removeClass('pending-request');
				if(data.error){
					$(button).fadeBox("<div style='background:#fff;padding:5px;font-weight:bold;color:#999;' class='error-border'>"+data.error+"</div>",3000,popup);
				} else {
					if (data.redirectTo) {
						location.href = data.redirectTo;
					} else {
						myshape.getGadget('bag').updateCounter(data.data.cartCount);
						$(button).fadeBox("<div style='background:#fff;padding:5px;font-weight:bold; border:1px solid green;color:#999;'>This item has been added to your cart</div>",3000,popup);
					}
				}
			};

			if(!cartString.length){
				myshape.ajax.addToCart(styleID,colorSize.color,colorSize.size,quantity,completeFunction);
			} else {
				myshape.ajax.addManyToCart([cartString],function(data){
					completeFunction(data[0]);
				});
			}
		});

		$(z.nodeSelector+" .add-wishlist").live('click',function(){
			if($(this).hasClass('pending-request')){
				return false;
			}
			$(this).addClass('pending-request');

			var button = this;

			var loadingBox = $(this).parents(z.nodeSelector).find(".mybag-loading")[0];
			$(loadingBox).show();

			var popup = z.getActive();
			var styleID = $(popup).find(".style-id.holder").html();
			var colorSize = z.colorSizeGadget.getColorSize(popup);

			myshape.ajax.addToWishlist(styleID,colorSize.color,colorSize.size,function(data){
				$(loadingBox).hide();
				$(button).removeClass('pending-request');
				if(data.error){
					$(button).fadeBox("<div style='background:#fff;padding:5px;font-weight:bold;color:#999;width:300px' class='error-border'>"+data.error+"</div>",3000,popup);
				} else {
					$(button).fadeBox("<div style='background:#fff;padding:5px;font-weight:bold; border:2px solid #80e0f9;color:#999;'><img src = '/modules/shop/tpl/default/images/nbs/wishlist-added.png' /><br />This item has been added to your wish list.</div>",3000,popup);
				}
			});
		});
	},
	parseCartString:function(str){
		var parts = str.split(',');
		return {styleID:parts[0],color:parts[1],size:parts[2],quantity:parts[3] || 1,wishlistItemID:parts[4],wishlistID:parts[5]}
	},
	tabsClickable:function(){
		var z = this;
		$(z.tabContentSelector+" .tab-link").live('click',function(){
			ref = $(this).attr('href').split('#');

			if(ref.length > 1){
				ref = ref[1];
				$(this).parents(".tab-container").find(".htab").removeClass('selected');
				$(this).find(".htab").addClass('selected');

				$(z.activeSelector+" .tab-content.active").removeClass('active');
				$(z.activeSelector+" .tab-content."+ref).addClass('active');
			}
			return false;
		});
	},
	outfitsPoppable:function(){
		var z = this;
		$(this.gadgetSelector+" .style-outfit img").live('click',function(){
			myshape.getGadget('outfitPopup').open($(this).parents(".complete-the-look").find("input").val(),z.getNode(this));
			return false;
		});
	},
	ears:function(){
		var z = this;
		z.listen('style.state.activated',function(el,key,data){
			z.deletePopups();
			z.showPopupFromStyle(el,data.data || {});
		});

		z.listen('outfitPopup.state.beforeOpen',function(el,key,data){
			z.deletePopups();
		});

		z.listen('thumbCarousel.state.thumbChanged',function(el,key,data){
			var activePop = $(el).parents(z.activeSelector)[0];
			if(!activePop) return false;

			z.manageThumbChange(activePop,el);
		});

		z.listen('colorSizePicker.state.changed',function(el,key,data){
			var activePop = $(el).parents(z.activeSelector)[0];
			if(!activePop) return false;

			var colorSize = z.colorSizeGadget.getColorSize(el);

			z.thumbGadget.clickColor(activePop,colorSize.color);

			$(activePop).windowUncolide();
		});

		z.listen('comments.state.commentDataChanged',function(el,key,data){
			var talkData = data.data;
			if(talkData && talkData.styleID){
				var styleID = talkData.styleID;
				if(z.cachedNodes[styleID]){
					z.cachedNodes[styleID] = false;
				}
			}
		});
	},
	manageThumbChange:function(activePop,thumbElement){
		var z = this;
		//get image gadget and switch main image;

		var thumbImg = $(z.thumbGadget.getActiveThumb(thumbElement)).find('img')[0];

		var baseName = myshape.util.baseName($(thumbImg).attr('src'));

		var src = myshape.util.imagePath('large',baseName);
		var zoomSrc = myshape.util.imagePath('zoom',baseName);
		var colorID = $(thumbImg).attr('colorid');

		z.colorSizeGadget.doSelectColor(activePop,colorID);

		$(activePop).find(".zoomable-image-gadget").dataset('zoomsrc',zoomSrc).find('img').attr('src',src);

	},
	//state change gadget talk is fired after your state function so past tense names makes sense
	states:{
		closed:function(el,oldState){
			$(el).remove();
			return true;
		},
		beforeOpen:function(el,oldState){
			return true;
		},
		//anything you do to the element when you "hear" this state will be cached
		building:function(el,oldState){
			return true;
		},
		fromcache:function(el,oldState,data){
			myshape.getGadget('comments').activate(el);

			this.manageThumbChange(el,this.thumbGadget.getNode(el));
		},
		opened:function(el,oldState){
			this.thumbGadget.doActivateScroll(el);

			this.completeTheLookScrollable(el);
			this.mostViewedScrollable(el);

			this.colorSizeGadget.activateSelectables(el);
			$(el).windowUncolide();//often contents forces the box to strech unpredictably
			return true;
		},
		errored:function(el,oldState,data){
			return true;
		},
		mostViewedClicked:function(el,oldState,data){
			return true;
		}
	},
	showPopupFromStyle:function(el,styleData){
		var popup = this.getPopup(el,styleData);
		this.showPopup(popup,el);
	},
	showPopupFromData:function(styleData){
		var popup = this.getPopupFromData(styleData);
		this.showPopup(popup);
	},
	showPopup:function(popup,el){
		var z = this;
		$(popup).appendTo($("body")[0]);
		z.doState(popup,'beforeOpen');
		//if a popup is showing use the popup container
		if($(this.activeSelector).length > 0){
			var css = $(this.activeSelector).attr('style');
			$(popup).attr('style',css);
			$(this.activeSelector).remove();
			$(popup).show();
			if(this.fromCache === true){
				this.doState(popup,'opened');
			}
		} else {
			$(popup).css({zIndex:1000,display:'none'});
			$(popup).center(window).fadeIn('fast',function(){
				if(z.fromCache === true){
					z.doState(popup,'opened');
				}
			});
		}
		$(popup).addClass('active');

		return popup;
	},
	getPopup:function(el,styleData){
		var styleImage = styleData.image;
		// i return a node from cache or a new node
		return this.getPopupFromData(styleData);
	},
	getPopupFromData:function(styleData){
		var popup = this.getFromCache(styleData.styleID);

		this.fromCache = true;
		if(!popup){
			this.fromCache = false;

			styleImage = styleData.image || false;

			popup = this.getNewPopup();
			$(popup).find(".loading-image").html(myshape.util.loadingImage());
			this.showLoading(popup);
			this.getStyleData(popup,styleData);
		} else {
			this.doState(popup,'fromcache',styleData);
		}
		return popup;
	},
	getNewPopup:function(el){
		return $(this.templateSelector).find("div").eq(0).clone();
	},
	cachedNodes:{},
	getFromCache:function(styleID){
		if(this.cachedNodes[styleID]){
			var node = $(this.cachedNodes[styleID]).clone();
			return node;
		}
		return false;
	},
	lastResponse:{},
	resultCache:{},
	getStyleData:function(popup,styleData){
		var z = this;
		var styleID = styleData.styleID;

		myshape.ajax.getSuperAction(styleData,function(data){
			if(data.error){
				z.doState(popup,'errored',data);
				$(popup).remove();
				z.cachedNodes[styleID] = '<div>Error: unable to load style.<div>';
				return;
			}
			z.lastResult = data;
			z.resultCache[styleID] = data;
			z.processData(popup,styleData);
		});
		
	},
	processData:function(popup,styleData){
		this.doState(popup,'building');

		var data = this.lastResult;

		var styleImage = data.defaults.image;//(styleImage?(typeof styleImage == 'object'?$(styleImage).attr('src'):styleImage):this.lastResult.style.image);

		this.buildGadgets(popup,styleImage,this.lastResult,styleData);

		//HACK - another image source hardset
		var thumbPath = myshape.util.mediaSource()+myshape.util.imagePaths.thumb;

		// Write various HTML for the hover tabs
		this.writeStyleText(popup);

		this.writeMostViewed(popup);
		
		this.writeCompleteTheLook(popup);
		
		//complete the process by dropping the loading and caching
		this.hideLoading(popup);

		this.cachedNodes[styleData.styleID] = this.resetPopup($(popup).clone()[0]);

		this.doState(popup,'opened');
	},
	writeMostViewed:function(popup){

		var z = this;
		var style = z.lastResult.styleData;

		var container = $(popup).find(".membersalso")[0];

		var mostViewedHTML = document.createDocumentFragment();

		var template = $(container).find(".members-also-item").remove()[0];

		var items = 0;
		(function(){
		for(var i=0;i < style.mostViewed.length;i+=4){
			var chunk = style.mostViewed.slice(i,4+i);
			if(chunk.length){
				var rowTemplate = $(template).clone()[0];
				var nodeTemplate = $(rowTemplate).find(".members-also-item-item").remove()[0];
				$.each(chunk,function(k,item){
					items++;
					$(rowTemplate).append(z.buildMostViewedHTMLBlock(item,$(nodeTemplate).clone()[0]));
				});
				mostViewedHTML.appendChild(rowTemplate);
			}
		}
		})();

		if (!items){
			$(popup).find(".membersalso").parents(".related-items-cont").hide();
		} else {
			container.appendChild(mostViewedHTML);
		}

	},
	buildMostViewedHTMLBlock:function(item,template){
		$(template).find("input").val(item.style_id);
		$(template).find("img").attr('src',item.products_image_path);
		if(item.guide){
			$(template).append("<span style='display:none !important;' name='guide'>"+item.guide+"</span>")
		}
		return template;
	},
	mostViewedScrollable:function(el){
		var node = this.getNode(el);
		el = $(node).find(".members-also-considered-gadget")[0];
		if(!$(el).hasClass('activated-scroll')){
			$(el).addClass('activated-scroll');
			$(el).jToolsScrollable({
				size:1,
				items:".membersalso",
				api:true,
				clickable:false
			});
		}
	},
	writeCompleteTheLook:function(popup){
		var z = this;
		var style = this.lastResult.styleData;
		var foundOutfits = false;

		var completeTheLookCont = $(popup).find(".complete-the-look");
		var template = $(completeTheLookCont).find(".list-item")[0];

		$(completeTheLookCont).html('');

		if (style.completeTheLook.length){
			$(popup).find(".complete-the-look-gadget").show();
			$.each(style.completeTheLook,function(k,outfit){;
				foundOutfits = true;
				var cloneTemplate = $(template).clone();
				z.buildCompleteTheLookNode(outfit,cloneTemplate);
				$(cloneTemplate).appendTo(completeTheLookCont);
			});
		}
	},
	buildCompleteTheLookNode:function(outfit,template){
		$(template).find("input[name=styleID]").val(outfit.id);
		$(template).find("img").attr('src',myshape.util.imagePath('browse',outfit.image));
	},
	completeTheLookScrollable:function(el){
		var node = this.getNode(el);
		el = $(node).find(".complete-the-look-gadget")[0];
		numItems = $(el).find(".style-outfit").length;
		if(numItems > 2){
			$(el).jToolsScrollable({
				size:2,
				items:".complete-the-look",
				api:true,
				clickable:false
			});
		} else {
			$(el).find(".next").addClass('disabled');
			$(el).find(".prev").addClass('disabled');
		}
	},
	writeStyleText:function(popup){
		var style = this.lastResult.styleData;

		$(popup).find(".mybag-loading.holder").html(myshape.util.loadingImage());
		$(popup).find(".wishlister-gadget-loading").html(myshape.util.loadingImage());

		$(popup).find(".shapes.holder .shape").each(function(){
			var shape = $(this).html();
			var found = false;
			$.each(style.shapes,function(k,v){
				if(v == shape){
					return found = true;
				}
			});
			if(!found){
				$(this).hide().parent().hide();
			}
		});

		$(popup).find(".style-name.holder").html(style.designer);
		$(popup).find(".style-title.holder").html(style.name);


		//update all of the text n stuff
		if (style.price > 0) {
			if (style.salePrice){
				$(popup).find(".style-price.holder").html('<span class="on_sale">$'+myshape.util.money(style.price)+'</span><br /><span class = "sale_price">$'+myshape.util.money(style.salePrice)+'</span>');
			} else {
				$(popup).find(".style-price.holder").html("$"+myshape.util.money(style.price));
			}
		}

		if(style.description){
			if(style.description.length){
				$(popup).find(".style-description-cont").show();
				$(popup).find(".style-description.holder").html(style.description);
			}
		}

		$(popup).find(".style-id.holder").html(style.id);
		var cleanDescription = [];

		$.each(style.extendedDescription,function(k,v){
			if(v && v.length){
				cleanDescription[cleanDescription.length] = v;
			}
		});
		var txt = '';
		if(cleanDescription.length){
			txt = '<ul><li>'+cleanDescription.join('</li><li>')+'</li></ul>';
		}
		$(popup).find(".style-extended-description.holder").html(txt);

		$(popup).find(".fabric-content.holder").html(style.content);
		if(style.care.length){
			$(popup).find(".fabric-care.holder").html(style.care);
		} else {
			$(popup).find(".fabric-care.holder").hide();
		}
	},
	buildGadgets:function(popup,image,data,styleData){

		//right now the only id that is passed with the request is the current shop id if you have no shop this is blank
		if(!(+data.commentData.shopViewerID)){
			this.hideWishlistLink(popup);
		}

		var style = data.styleData;

		//this cart string is passed up from the styleGadget
		if(styleData.cartString){
			if(styleData.cartString.length){
				$(popup).append("<span style='display:none;' class='cart-string'>"+styleData.cartString+"</span>");
			}
		}

		this.colorSizeGadget.build(popup,{
			sizes:data.styleData.sizes,
			colors:data.styleData.colors,
			sizesToColors:data.styleData.sizesToColors,
			colorsToSizes:data.styleData.colorsToSizes,
			size:data.defaults.size,
			suggestedSize:data.defaults.suggestedSize,
			defaultColor:data.defaults.color,
			message:data.defaults.message,
			swatches:data.styleData.swatches
		});

		//thumb gadget
		var mainColor = myshape.util.colorFromSrc(image);
		if(!style.colors[mainColor] && data.defaults.color){
			mainColor = data.defaults.color;
		}

		var thumbs = [];

		$.each(style.thumbs,function(k,thumbData){
			if(style.colors[thumbData.color]){
				thumbData.colorName = style.colors[thumbData.color].name;
				thumbs[thumbs.length] = thumbData;
			}
		});

		this.thumbGadget.build(popup,thumbs,mainColor,4);
		//end thumb gadget

		//comments gadget
		if(data.commentData.shopViewerID){

			myshape.getGadget('comments').build(popup,data.styleData.id,data.commentData);
	
			// Default to comments tab / content if in friend mode
			if(data.commentData.allowComments){
				$(popup).find(".commentsTab").click();
			}
		} else {
			//if you are not logged in you cannot see the comments tab
			$(popup).find(".commentsTab").parents(".tab").hide();
		}
	},
	showLoading:function(popup){
		$(popup).find(this.bodySelector).hide().prev(this.loadingSelector).show();
	},
	hideLoading:function(popup){
		$(popup).find(this.loadingSelector).hide().next(this.bodySelector).show();
	},
	deletePopups:function(){
		var z = this;
		$("body > "+this.nodeSelector).each(function(){
			z.doState(this,'closed');
		});
	},
	resetPopup:function(popup){
		return $(popup).removeAttr('style').removeClass('active')[0];
	},
	getActive:function(){
		return $(this.activeSelector)[0] || false;
	},
	close:function(){
		var popup = this.getActive();
		if(popup){
			this.doState(popup,'closed');
		}
	},
	hideWishlistLink:function(el){
		var node = this.getNode(el);
		//hide wishlist add link
		var wlli = $(node).find(".add-wishlist").parents("li")[0];
		if(wlli){
			$(wlli).remove();
		}
	}
};

/*
the myshape comments gadget powers friend comments in the style popup but can be used anywhere
*/
myshape.gadgets.comments = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.comments();
	} else {
		this.init();
		return this;
	}
};

myshape.gadgets.comments.prototype = {
	gadgetSelector:".comments-gadget",
	//activeClass
	init:function(){
		var z = this;
		z.inherit = myshape.gadget.inherit;
		z.inherit(myshape.gadget);

		z.saveable();
	},
	saveable:function(){
		var z = this;
		var loading = false;
		$(z.gadgetSelector+" .add-comment").live('click',function(){
			var button = this;

			if(loading){
				return false;
			}

			loading = true;


			var node = z.getNode(button);
			var loadingBox = $(node).find(".comments-loading")[0];
			$(loadingBox).show();

			var styleID = z.styleID(node);
			var shopID = z.shopID(node);

			var comment = $(node).find("textarea.comments-input").val();
			if(comment.length > 0){

				myshape.ajax.addComment(shopID, styleID, comment,function(data){

					$(loadingBox).hide();	
					loading = false;

					if(data.error){
						$(button).fadeBox(myshape.util.errorBox(data.error),false,node);
					} else {
						var comment = data.data;
						$(button).fadeBox("<div class='border-radius' style='background:#fff;padding:5px;font-weight:bold; border:2px solid #80e0f9;color:#999;'>Your comment has been added</div>",false,node);

						z.writeComment(node,comment);
						z.doState(node,'commentDataChanged',comment);
						$(node).find("textarea.comments-input").val("");
					}
				});

			} else {
				loading = false;
				$(button).fadeBox(myshape.util.errorBox('Please type a comment'),false,node);
			}
		});
	},
	states:{
		node:function(){
			return true;
		},
		commentDataChanged:function(){
			//fired when a new comment is made =)
			return true;
		}
	},
	build:function(el,styleID,commentData){

		var z = this;

		/*
case1
	i have no shop
		*/

		var noShop = (!commentData.shopID && commentData.shopViewerID? true:false);

		//var myShop = (commentData.shopID == commentData.shopViewerID? true:false);

		var allowComments = commentData.allowComments;
		var comments = commentData.comments;
		var shopID = commentData.shopID;

		var node = z.getNode(el);

		if(noShop){
			$(node).find(".no-comments .li-comment center").each(function(){
				if($(this).hasClass('swf-no-shop')){
					$(this).show();
				} else {
					$(this).hide();
				}
			});
		}

		$(node).find(".comments-loading").html(myshape.util.loadingImage());

		if(node && styleID){

			z.styleID(node,styleID);
			z.shopID(node,shopID);

			if (shopID){
				if(allowComments){
					$(node).find("div.comments-input").show();
				}
				if (comments){
					$.each(comments,function(k,comment){
						z.writeComment(node,comment);
					});
				}
			}
		}
		this.activate(node);
	},
	//this gadget requires non live event handlers so must be initalized post build and on every reload
	activate:function(el){
		this.activateTextarea(el);
		this.activateInviteLink(el);
	},
	activateTextarea:function(el){
		var node = this.getNode(el);
		$(node).find("textarea").parents(".comments-input").textAreaLimit({counterSelector:'.comments-counter'});
	},
	activateInviteLink:function(el){
		var node = this.getNode(el);
		$(node).find(".no-comments .li-comment .swf-shop a").nyroModal(); // Add nyro modal to invite link in comments section.
	},
	writeComment:function(el,comment){
		var node = this.getNode(el);
		/*var comment = {
			name: this.lastResult.style.currentViewer, 
			date: this.lastResult.style.currentDate, 
			comment: commentText
		};*/

		var commentHTML = this.buildCommentHTMLBlock(comment);

		if (!this.haveComments(node)){
			//clear no comments message if exists
			$(this.getCommentsCont(node)).html("");
		}
		// Prepend the new comment
		$(this.getCommentsCont(node)).prepend(commentHTML);
	},
	haveComments:function(node){
		return $(this.getCommentsCont(node)).find(".no-comments").length == 0;
	},
	getCommentsCont:function(el){
		return $(this.getNode(el)).find(".comments-cont")[0];
	},
	buildCommentHTMLBlock:function(comment){
		html  = '<div class="list-item">';
		html += '<div class="clearfix"><div class="li-user-name holder left">'+comment.name+'&nbsp;</div><div class="right">'+comment.date+'</div></div>';
		html += '<div class="li-comment">'+comment.comment+'</div>';
		html += '</div>';
		return html;
	},
	styleID:function(el,styleID){
		var node = this.getNode(el);
		if(!styleID){
			return $(node).attr('styleID');
		}
		$(node).attr('styleID',styleID);
		return styleID;
	},
	shopID:function(el,shopID){
		var node = this.getNode(el);
		if(!shopID){
			return $(node).attr('shopID');
		}
		$(node).attr('shopID',shopID);
		return shopID;
	}
};

/********************************
thumbCarousel gadget

this gadget should be used to opperate all carouseled thumbs on the site
*/
myshape.gadgets.thumbCarousel = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.thumbCarousel();
	} else {
		this.init();
		return this;
	}
};

myshape.gadgets.thumbCarousel.prototype = {
	gadgetSelector:".thumb-gadget",
	thumbSelector:".carousel-thumb",
	thumbTemplateSelector:".thumb-template",
	thumbScrollableSelector:".scrollable",
	thumbContainerSelector:".scrollable .items",
	//activeClass
	init:function(){
		var z = this;
		z.inherit = myshape.gadget.inherit;
		z.inherit(myshape.gadget);
		z.clickable();

	},
	clickable:function(){
		var z = this;
		$(this.thumbSelector+' img').live('click',function(){
			z.activateThumb(this);
		});
	},
	clickColor:function(el,newColor){
		var node = this.getNode(el);
		var colorID = this.getActiveColor(node);
		if(newColor != colorID){
			$(node).find(this.thumbSelector+" img[colorid="+newColor+"]").eq(0).click();
		}
		return true;
	},
	doActivateScroll:function(el){
		el = this.getNode(el);
		this.activateScroll(el);
	},
	activateScroll:function(el){
		if(!$(el).hasClass('activated-scroll')){
			$(el).addClass('activated-scroll');
			$(el).jToolsScrollable({
				size:4,
				api:true,
				clickable:false
			});
		}
	},
	setupScroll:function(scrollable,visibleThumbs){
		scrollable.visibleThumbs = visibleThumbs || 4;

		var thumbs = $(scrollable).find(this.thumbSelector);

		if(thumbs.length <= visibleThumbs){
			$(scrollable).next('.next').addClass('disabled');
		} else {
			$(scrollable).next('.next').removeClass('disabled');
		}
	},
	build:function(el,thumbs,mainColor,visibleThumbs){
		var node = this.getNode(el);

		if(!node){
			return false;
		}

		var thumbContainer = $(node).find(this.thumbContainerSelector);
		var template = $(node).find(this.thumbTemplateSelector).clone().removeClass('thumb-template').addClass('carousel-thumb')[0];
		var mainRendered = false;

		$.each(thumbs,function(k,thumbData){

			var newNode = $(template).clone()[0];
			newNode.colorID = thumbData.color;
			newNode.colorName = thumbData.colorName;

			$(newNode).show().find("img").attr({
				src:myshape.util.mediaSource()+myshape.util.imagePaths.thumb+'/'+thumbData.file,
				alt:thumbData.colorName,
				title:thumbData.colorName,
				colorID:thumbData.color
			});

			if(thumbData.color == mainColor){
				if(mainRendered){
					$(newNode).insertAfter(mainRendered);
				} else {
					$(newNode).prependTo(thumbContainer);
				}
				if(!mainRendered && myshape.util.typeFromSrc(thumbData.file) == 'main'){
					mainRendered = newNode;
				}
			} else {
				$(newNode).appendTo(thumbContainer);
			}
		});

		this.activateColor(node,mainColor);
		this.setupScroll($(node).find(this.thumbScrollableSelector)[0],visibleThumbs);
	},
	load:function(el,visibleThumbs){
		var node = this.getNode(el);
		if(node){
			//.find('.scrollable')
			this.setupScroll($(node)[0],visibleThumbs);
			return true;
		}
		return false;
	},
	states:{
		node:function(){return true},
		thumbChanged:function(el,oldState){
			return true
		}
	},
	activateColor:function(el,colorID){
		var z = this;
		var node = z.getNode(el);
		if(!node){
			return false;
		}

		$(node).find(z.thumbContainerSelector+" "+z.thumbSelector).each(function(){
			if(this.colorID == colorID){
				z.activateThumb(this);
				return false;//break
			}
		});
		return true
	},
	activateThumb:function(thumb){
		var img = thumb;
		if(thumb.nodeName.toLowerCase() != 'img'){
			$(thumb).addClass('active');
			img = $(thumb).find('img')[0];
		}

		if($(img).hasClass('active-image')){
			return;
		}

		var gadget = $(img).parents(this.gadgetSelector)[0];

		$(gadget).find("img.active-image").removeClass('active-image');

		$(gadget).find(".carousel-thumb.active").removeClass('active');

		$(img).addClass('active-image').parents(".carousel-thumb").addClass('active');

		this.doState($(thumb).parents(this.gadgetSelector)[0],'thumbChanged');
	},
	getActiveThumb:function(node){
		return $(node).find(this.thumbSelector+".active")[0];
	},
	getActiveColor:function(node){
		return $(this.getActiveThumb(node)).attr('colorID');
	}
};

/*****
* colorSize picker gadget
*/
myshape.gadgets.colorSizePicker = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.colorSizePicker();
	} else {
		this.init();
		return this;
	}
};

myshape.gadgets.colorSizePicker.prototype = {
	gadgetSelector:".size-and-color-picker-gadget",
	sizeInputSelector:"select.sizes",
	colorInputSelector:"select.colors",
	quantityInputSelector:"input.quantity",
	swatchHolderSelector:".swatch-image-holder",
	init:function(){
		var z = this;
		z.inherit = myshape.gadget.inherit;
		z.inherit(myshape.gadget);
	},
	//because this is not a live event we call it after the select elements are built
	activateSelectables:function(el){
		var z = this;
		$.each($(el).find(this.gadgetSelector),function(k,node){
			z.selectable($(node).find(z.sizeInputSelector));
			z.selectable($(node).find(z.colorInputSelector));
			z.reset(node);
		});
	},
	doSelectColor:function(el,color){
		var selectNode = $(this.getNode(el)).find(this.colorInputSelector)[0];

		this.doSelectSwatch(el,color);

		return this.doSelect(selectNode,color,this.selectColor);
	},
	doSelectSwatch:function(el,color){
		//var node = this.getNode(el);
		var cont = $(this.getNode(el)).find(this.swatchHolderSelector)[0];
		$(cont).find("img").hide();
		var haveColor = $(cont).find("img[data-color="+color+"]").show().length;
		if(haveColor){
			$(cont).show();
		} else {
			$(cont).hide();
		}
	},
	doSelectSize:function(el,size){
		var selectNode = $(this.getNode(el)).find(this.sizeInputSelector)[0];
		return this.doSelect(selectNode,size,this.flagColorSizeIntersection);
	},
	doSelect:function(el,key,cb){
		var newVal = $(el).find("option[key="+key+"]").eq(0).val();
		if(newVal){
			$(el).val(newVal);
			this.cb = cb;
			this.cb(el,key);
			return true;
		}
		return false;
	},
	getGadget:function(el){
		return $(el).parents(this.gadgetSelector)[0];
	},
	states:{
		node:function(){return true;},
		changed:function(el,oldState,data){
			this.flagColorSizeIntersection(el);
			this.checkSizeRec(el);
			return true;
		}
	},
	checkSizeRec:function(el){
		var node = this.getNode(el);
		var recSize = this.getRecSize(node);

		if(recSize){
			var selectedSize = this.getColorSize(node).size;
			if(recSize != selectedSize){
				this.showMessageBox(node);
			} else {
				this.hideMessageBox(node);
			}
		}
	},
	writeMessageBox:function(el,title,message){
		var box = this.getMessageBox(el);
		if(box){
			$(box).html('<span class="title">'+title+'</span><br /><br />'+message);
		}
	},
	hideMessageBox:function(el){
		$(this.getMessageBox(el)).removeClass('visible');
	},
	showMessageBox:function(el){
		$(this.getMessageBox(el)).addClass('visible');
	},
	getMessageBox:function(el){
		var node = this.getNode(el);
		return $(node).find(".style-expanded-messaging")[0];
	},
	getRecSize:function(node){
		return $(this.getNode(node)).find("input[name=recSize]").val();
	},
	setRecSize:function(node,size){
		return $(this.getNode(node)).find("input[name=recSize]").val(size);
	},
	/*
		jquery clone does not copy custom object properties attached to dom element objects 
		!NOTE the solution is to use the jquery.data method
	*/
	build:function(node,data){
		/*var sample = {
			sizes:{SROL:{id:1,name:'sample size 1'},SROM:{id:2,name:'sample size 2'}},
			colors:{CLR1:{id:3,name:'sample color 1'},CLR2:{id:4,name:'sample color 2'}},
			sizesToColors:{SROL:['CLR1','CLR2'],SROM:['CLR1']},
			colorsToSizes:{CLR1:['SROL','SROM'],CLR2:['SROL']},
			defaultSize:'SROL',
			defaultColor:'CLR1',
			message:' you do not have the default size selected'
		};

		data = sample;*/

		var el = this.getNode(node);
		el.defaultSize = data.size;
		el.suggestedSize = data.suggestedSize || data.size;
		el.defaultColor = data.defaultColor;

		//populate the shapematch rec

		var opt = $("<option/>")[0];

		var sizeSelect = $(el).find(this.sizeInputSelector).html('')[0];

		var numSizes = 0;

		//default size comes back with a value even if that size is no longer in stock
		var haveDefaultSize = false;

		$.each(data.sizes,function(k,v){
			numSizes++;
			var size = $(opt).clone();
			$(sizeSelect).append(size);

			if (k == data.size) {//|| (k == 'label' && !data.size)
				$(size).val(v.id).html(v.name).attr({key:k,selected:'selected'}).addClass('base-size');
				haveDefaultSize = true;
			} else {
				$(size).val(v.id).html(v.name).attr('key',k);
			}
			//sizeless dressing requires a special message for out of stock in color size combo
			if(v.stockmessage){
				$(size).attr('stockmessage',v.stockmessage);
			}

			if(data.sizesToColors[k]){
				$.each(data.sizesToColors[k],function(k,v){
					$(size).addClass('color-'+v);
				});
			}
		});

		if(numSizes <=1){
			$(sizeSelect).attr('disabled','disabled').css({background:'#f0f0f0'});
		} else {
			//if(!haveDefaultSize){
				//var nonSize = $(opt).clone()[0];
				//$(nonSize).appendTo(sizeSelect).addClass('base-size').html("Select a Size").val(0);
				//$(sizeSelect).val($(nonSize).val());
			//}
		}

		var colorSelect = $(el).find(this.colorInputSelector).html('')[0];
		var numColors = 0;
		var firstColor = false;


		$.each(data.colors,function(k,v){
			if(numColors == 0){
				firstColor = k;
			}
			numColors++;
			var color = $(opt).clone();
			$(colorSelect).append(color);

			if (k == data.defaultColor) {
				$(color).val(v.id).html(v.name).attr('key',k).attr('selected', 'selected');
			} else {
				$(color).val(v.id).html(v.name).attr('key',k);
			}

			if(data.colorsToSizes[k]){
				$.each(data.colorsToSizes[k],function(k,v){
					$(color).addClass('size-'+v);
				});
			}
		});

		if(numColors <=1){
			$(colorSelect).attr('disabled','disabled');
		} else {
			$(colorSelect).removeAttr('disabled');
		}

		this.buildSwatches(el,data.swatches);

		//non default size message
		if(data.message){
			this.writeMessageBox(el,'ShapeMatch® Recommendation',data.message);
			if(!haveDefaultSize || el.suggestedSize != el.defaultSize){
				this.showMessageBox(el);
			}
			this.setRecSize(el,el.suggestedSize);
		}
		var z = this;
		setTimeout(function(){
			z.flagColorSizeIntersection(el);
		},0);
	},
	reset:function(el){
		el = this.getNode(el);
		$(el).val($(el).find("option.base-size").attr('selected','selected').val());
	},
	flagColorSizeIntersection:function(el){
		$.log('flagging intersection');
		//colorize the 
		var z = this;
		var node = z.getNode(el);
		var colorSelect = $(node).find(this.colorInputSelector);
		var sizeSelect = $(node).find(this.sizeInputSelector);
		if($(sizeSelect).val().length && $(colorSelect).val()){
			var colorOption = $(colorSelect).find("option[value="+$(colorSelect).val()+"]")[0];
			var sizeOption = $(sizeSelect).find("option[value="+$(sizeSelect).val()+"]")[0];
	
			z.selectColor(node,$(colorOption).attr('key'));
			z.selectSize(node,$(sizeOption).attr('key'));
	
			var colorInvalid = $(colorOption).hasClass('intersection-invalid');
			var sizeInvalid = $(sizeOption).hasClass('intersection-invalid');
	
			if(colorInvalid || sizeInvalid){
				var sizeText = $(sizeOption).html();
				var stockMessage = $(sizeOption).attr('stockmessage');
				if(stockMessage && stockMessage.length){
					sizeText = stockMessage;
				}
				$(node).find(".not-available-messaging").html("Sorry, the color "+$(colorOption).html()+" is sold out in "+sizeText+".").fadeIn(2000);
				return;
			}
		}
		$(node).find(".not-available-messaging").hide();
	},
	selectColor:function(el,color){
		var classKey = (color == 'label'?false:'color-'+color);
		return this.selectBase($(this.getNode(el)).find(this.sizeInputSelector)[0],classKey);
	},
	selectSize:function(el,size){
		var classKey = (size == 'label'?false:'size-'+size);
		return this.selectBase($(this.getNode(el)).find(this.colorInputSelector)[0],classKey);
	},
	selectBase:function(el,classKey){
		if(classKey){
			$(el).find("option").css({color:'#FF8484'}).addClass('intersection-invalid')
	
			$(el).find("option."+classKey).css({color:''}).removeClass('intersection-invalid');

			$(el).find("option[key=label]").css({color:''}).length;
		} else {
			$(el).find("option").css({color:''});
		}
	},
	selectable:function(el){
		var z = this;
		$(el).change(function(){
			// this is here for when we enable the auto update for out of stock size in color

			var preval = $(el).val();

			z.doState(z.getNode(this),'changed');

			return true;
		});
	},
	getColorSize:function(el){
		el = this.getNode(el);
		var color = this.getSelectValue(el,this.colorInputSelector);
		var size = this.getSelectValue(el,this.sizeInputSelector);
		if(size == 'label') size = '';
		return {color:color,size:size};
	},
	getSelectValue:function(el,selector){
		selectNode = $(el).find(selector)[0];
		if(selectNode){
			return $(selectNode).find("option[value="+$(selectNode).val()+"]").attr('key');
		}
		return false;
	},
	getQuantity:function(el){
		el = this.getNode(el);
		return this.getQuantityValue(el,this.quantityInputSelector);
	},
	getQuantityValue:function(el,selector){
		return $(el).find(selector).val();
	},
	buildSwatches:function(node,swatches){
		if(swatches && swatches.length && node){
			var cont = $(node).find(this.swatchHolderSelector)[0];
			$.each(swatches,function(i,v){
				$(cont).append("<img data-color='"+v.color+"' src='"+myshape.util.imagePath('swatch',v.file)+"' alt='' style='display;none;'/>");
			});
		}
	}
};

/******
* base gadget object for color search gadgets
*/
myshape.gadgets.colorSearchBase = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.colorSearchBase();
	} else {
		this.init();
		return this;
	}
};

myshape.gadgets.colorSearchBase.prototype = {
	init:function(){
		var z = this;
		z.inherit = myshape.gadget.inherit;
		z.inherit(myshape.gadget);
	},
	getColors:function(el){
		var colors = [];
		var node = this.getNode(el);
		if(node){
			$(node).find(this.colorsSelector+" .color-node").each(function(){
				var rgb  = $(this).attr('rgb');
				if(rgb){
					colors[colors.length] = rgb;
				}
			});
		}
	},
	addColor:function(node,containerSelector,rgbString){
		if(!this.findColor(node,containerSelector,rgbString)){
			var color = this.buildColorNode(rgbString);
			$(containerSelector).append(color);
			return true;
		}
		return false;
	},
	removeColor:function(node,containerSelector,rgbString){
		var color = this.findColor(node,containerSelector,rgbString);
		if(color){
			$(color).remove();
			return true;
		}
		return false;
	},
	findColor:function(el,containerSelector,rgbString){
		var node = this.getNode(el);
		return $(node).find(containerSelector+" .color-node[rgb="+rgbString+"]")[0];
	},
	buildColorNode:function(rgbString){
		return $(".color-search-gadget .color-node-template").eq(0).clone().removeClass('color-node-template').addClass('color-node').attr('rgb',rgbString).css({background:'rgb('+rgbString+')',height:'20px',width:'20px'}).show()[0];
	}
};

/*****
* colorSearchLink gadget - the color search popup "opener" that shows selected colors
*/
myshape.gadgets.colorSearchLink = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.colorSearchLink();
	} else {
		this.init();
		return this;
	}
};

myshape.gadgets.colorSearchLink.prototype = {
	gadgetSelector:".color-search-link-gadget",
	linkSelector:".color-search-link-gadget-link",
	colorsSelector:".color-search-link-gadget-colors",
	searchpalette:"",
	init:function(){
		var z = this;
		z.inherit = myshape.gadget.inherit;
		z.inherit(myshape.getGadget('colorSearchBase'));

		$(z.gadgetSelector).show();

		z.clickable();
		z.ears();
	},
	ears:function(){
		var z= this;
		z.listen("colorSearch.state.colorAdded",function(el,key,data){
			$(z.gadgetSelector).each(function(){
				z.addColor(this,z.colorsSelector,data.data.rgb);
			});
		});
		z.listen("colorSearch.state.colorRemoved",function(el,key,data){
			$(z.gadgetSelector).each(function(){
				z.removeColor(this,z.colorsSelector,data.data.rgb);
			});
		});
	},
	states:{
		node:function(){return true},
		activated:function(){return true}
	},
	clickable:function(){
		var z = this;
		$(z.gadgetSelector).live('click',function(){
			z.doState(z.getNode(this),'activated');
		});
	},
	addOnSearchHandler:function(el,fn){
		var node = this.getNode(el);
		node.onSearch = fn;
	}
}

/*****
* colorSearch gadget - the color selector popup
*/
myshape.gadgets.colorSearch = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.colorSearch();
	} else {
		this.init();
		return this;
	}
};

myshape.gadgets.colorSearch.prototype = {
	gadgetSelector:".color-search-gadget",
	gadgetTemplateSelector:"#color-search-gadget-template",
	colorsSelector:".selected-color-holder",
	searchpalette:"",
	lastSearch:[],
	init:function(){
		var z = this;
		z.inherit = myshape.gadget.inherit;
		z.inherit(myshape.getGadget('colorSearchBase'));

		z.colorSearchLinkGadget = myshape.getGadget('colorSearchLink');

		z.lastSearch = z.getColorMatchSearch();

		z.loadDefaultPalette();
		z.ears();
		z.closeable();
		z.colorsInteractable();
		z.submitable();
	},
	ears:function(){
		var z = this;
		z.listen('colorSearchLink.state.activated',function(el,key,data){
			var gadget = z.getTemplate();
			var elDims = $(el).getDims();

			if(typeof el.onSearch == 'function'){
				gadget.onSearch = el.onSearch;
			}

			$(gadget).appendTo("body").eq(0).hide().css({zIndex:499}).top(elDims.y).left(elDims.x).fadeIn('fast');
			//get colors form the colorSearchLink if any
			//add em to the selected colors box
		});
	},
	//TODO add the abillity to fire a submit function passed from the colorLink gadget
	submitable:function(){
		var z = this;
		$(".color-search-gadget-submit").live('click',function(){
			var rgb = [];
			var node = z.getNode(this);
			$(node).find(".selected-color-holder .color-node").each(function(){
				var rgbString = $(this).attr('rgb');
				if(rgbString.length){
					rgb[rgb.length] = rgbString;
				}
			});
			if(node.onSearch){
				if(node.onSearch(rgb)){
					$(this).find(".close-link").click();
				}
			} else {
				if(rgb.length > 0){
					rgb = rgb.join('-');
					var search = location.search;
					var newColorMatch = 'colorMatch='+rgb;
					if(z.lastSearch.length > 0){
						search = search.replace('colorMatch='+z.getColorMatchString(),newColorMatch);
					} else {
						search += (location.search.length> 0?'&':'')+newColorMatch;
					}
					location.search = search;
				} else {
					var search = location.search;
					if(z.lastSearch.length > 0){
						search = search.replace('colorMatch='+z.getColorMatchString(),'');
					}

					if(search[search.length-1] == '&'){
						search[search.length-1] = '';
					}

					location.search = search;
				}
			}
		});
	},
	getColorMatchSearch:function(){
		var search = this.getColorMatchString();
		if(search.length){
			return search.split('-');
		}
		return [];
	},
	getColorMatchString:function(){
		if(location.search.length > 0){
			if(location.search.indexOf('colorMatch=') != -1){
				return location.search.split('colorMatch=')[1].split('&')[0];
			}
		}
		return '';
	},
	closeable:function(){
		var z = this;
		$(".color-search-gadget .close-link").live('click',function(){
			$(z.gadgetTemplateSelector).html($(this).parents(z.gadgetSelector).remove());
		});
		$(".color-search-gadget").liveHover(function(){},function(){
			$(z.gadgetTemplateSelector).html($(this).remove());
		},{on:0,off:800});
	},
	colorsInteractable:function(){
		var z = this;
		$(".color-holder .color-node").live('click',function(){

			var rgb = $(this).attr('rgb');
			if(z.addColor(this,z.colorsSelector,rgb)){
				z.removeColor(this,".color-holder",rgb);

				z.doState(this,'colorAdded',{rgb:rgb});
			}
			return false;
		});

		$(".selected-color-holder .color-node").live('click',function(){
			var rgb = $(this).attr('rgb');
			var node = z.getNode(this);
			if(z.removeColor(this,z.colorsSelector,rgb)){
				//color is removed so it is no longer related to the parent node
				z.addColor(node,".color-holder",rgb);
				z.doState(node,'colorRemoved',{rgb:rgb});
			}
			return false;
		});
	},
	states:{
		node:function(){return true},
		colorAdded:function(){return true},
		colorRemoved:function(){return true}
	},
	loadDefaultPalette:function(){
		var z = this;
		$(".color-search-gadget").each(function(){
			var colorGadget = this;
			var colors = $(colorGadget).find("input[name=default-palette]").val().split('-');
			if(z.lastSearch.length > 0){
				var filteredColors = colors;
				$.each(colors,function(k,rgbString){
					var pass = true;
					$.each(z.lastSearch,function(k,searchedRGB){
						if(searchedRGB == rgbString){
							pass = false;
							return false;//break;
						}
					});
					if(pass){
						filteredColors[filteredColors.length] = rgbString;
					}
				});
				colors = filteredColors;
			}
			$.each(colors,function(k,rgbString){
				z.addColor(colorGadget,".color-holder",rgbString);
			});
			if(z.lastSearch.length > 0){
				$.each(z.lastSearch,function(k,rgbString){
					if(rgbString){
						z.addColor(colorGadget,".selected-color-holder",rgbString);
					}
				});
			}
		});
	},
	getTemplate:function(){
		return $(this.gadgetTemplateSelector+" "+this.gadgetSelector).clone()[0];
	}
}

myshape.gadgets.quickBrowse = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.quickBrowse();
	} else {
		this.init();
		return this;
	}
};

myshape.gadgets.quickBrowse.prototype = {
	gadgetSelector:".quick-browse-gadget",
	init:function(){
		var z = this;
		z.inherit = myshape.gadget.inherit;
		z.inherit(myshape.gadget);
		z.closeable();

		//z.colorSearchLinkGadget = myshape.getGadget('colorSearchLink');
	},
	//main api function
	create:function(params){
		var template = this.getTemplate();
		if(template){
			this.addParams(template,params);
			this.doState(template,'created');
		}
		return template;
	},
	//live event binders
	closeable:function(){
		var z = this;
		$(this.gadgetSelector+" .close-icon").live('click',function(){
			var node = z.getNode(this);
			if(node){
				z.doState(node,'closed');
			}
		});
	},
	states:{
		created:function(el,oldState){
			var z = this;
			if($(el).find(".results .scrollable").length == 0){
				$(el).find(".results").append("<div class='scrollable' style='position:relative;overflow: hidden;width:100%;height:100%;'><div class='browse-items' style='width:20000px;position:relative;'></div></div>");
			}
			z.addFilter(el);
			z.startLoading(el);
			this.getResults(el,function(data){
				var resultCount = 0;
				$.each(data,function(){
					resultCount++;
				});
				z.stopLoading(el,resultCount);
			});
			return true;
		},
		//when i update the internal filters to change the result set
		newResults:function(el){
			var z = this;
			z.startLoading(el);
			z.emptyResults(el);
			var hits = new Number($(el).attr('hits') || 0);
			$(el).attr('hits',++hits);
			//reset the scroller to the beginning

			z.getResults(el,function(data){
				if($(el).attr('hits') == hits){
					var resultCount = 0;
					z.emptyResults(el);//if you are a quick category switcher we need to empty again
					$.each(data,function(){
						resultCount++;
					});
					z.stopLoading(el,resultCount);
				}
			});
			return true;
		},
		//when the "page" changes by scrolling near the end
		moreResults:function(el){
			if(!el.resultsComplete){

				if(!el.isLoading){
					var z = this;
					el.isLoading = true;
					el.params.page++;

					z.getResults(el,function(data){
						//$.log('more results complete');
						el.isLoading = false;
						var resultCount = 0;
						$.each(data,function(){
							resultCount++;
						});
						if(resultCount == 0){
							el.resultsComplete = 1;
						}
					});
					return true;
				}
			}
			return false;
		},
		resultsLoaded:function(el,oldState,data){
			var z = this;
			$.each(data,function(k,v){
				z.addResult(el,v);
			});
			$(el).find(".scroll-nav").removeClass("scroll-link-disabled");

			if(!$(el).find(".results-cont").hasClass('added-scrollable')){
				$(el).find(".results-cont").jToolsScrollable({
					disabledClass:"scroll-link-disabled",
					next:'.no-next',//must be overidden
					prev:'.no-prev',//must be overidden
					nextPage:".next",
					prevPage:".prev",
					items:".browse-items",
					keyboard:false,
					clickable:false,
					size:3, //the desired behavior is 3 at a time
					onBeforeSeek:function(){
						var leftToScroll = $(this.getRoot()).find(".quick-browse-style").length - (this.getIndex()+3);
						if(leftToScroll < 20 && !el.isloading){
							z.doState(el,'moreResults');
						}
					}
				}).addClass('added-scrollable');
			} else {
				var api = $(el).find(".results-cont").jToolsScrollable({api:true}).reload();
				///HACK this assumes that the browse max result set returned in one request is going to be 20 items - should be configureable
				if($(el).find(".results-cont .quick-browse-style").length <= 20){
					api.reset();
				}
			}
			return true;
		},
		closed:function(el,oldState,data){
			$(el).remove();
			return true;
		}
	},
	emptyResults:function(el){
		$(el).find(".results-cont").hide().find(".quick-browse-style").remove();
	},
	reloadAllResults:function(){
		$(".quick-browse-gadget .category-filter").change();
	},
	addFilter:function(el){
		var z = this;
		var params = this.getParams(el);
		if(params.categoriesID){
			$(el).find(".quick-browse-inner-filter").html($("#quick-browse-filter-templates .quick-browse-category-filter").clone()[0]);
			$(el).find(".quick-browse-category-filter select").val(params.categoriesID).change(function(){
				el.params.categoriesID = $(this).val();
				z.doState(el,'newResults');
			});
		}

		/*z.colorSearchLinkGadget.addOnSearchHandler($(el).find(".quick-browse-color-filter")[0],function(rgb){
			alert(rgb);
		});*/
	},
	getTemplate:function(){
		var template = $("#quick-browse-gadget-template "+this.gadgetSelector).clone()[0];
		if(template){
			return $(template).clone()[0];
		}
		return false;
	},
	getResults:function(el,cb){
		var z = this;
		var params = z.getParams(el);

		myshape.ajax.browse(params.categoriesID,params.page+1,function(data){
			if(typeof(cb) == 'function'){
				cb(data);
			}
			z.doState(el,'resultsLoaded',data);
		});
	},
	addParams:function(el,params){
		el.params = params;
	},
	getParams:function(el){
		var params = el.params || {};
		if(!params.page){
			params.page = 0;
		}
		el.params = params;
		return el.params;
	},
	startLoading:function(el){
		$(el).find(".no-results").hide();
		$(el).find(".style-container .loading").html(myshape.util.loadingImage()).show();
	},
	stopLoading:function(el,resultCount){
		$(el).find(".style-container .loading").hide();
		if(resultCount || $(el).find(".results .quick-browse-style").length > 0){
			$(el).find(".results-cont").show();
		} else {
			$(el).find(".no-results").show();
		}
	},
	clearResults:function(){

	},
	addResult:function(el,data){
		var template = this.getResultTemplate();

		template.data = data;

		var src = data.image;
		//if the image does not have http/s already
		if(data.image.indexOf(location.protocol) == -1){
			src = myshape.util.imagePath('browse',data.image);
		}

		$(template).find("img").attr('src',src);

		$(el).find(".results .browse-items").append(template);
	},
	getResultTemplate:function(){
		return $("#quick-browse-style-template .quick-browse-style").clone()[0];
	}
};


myshape.gadgets.outfit = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.outfit();
	} else {
		this.init();
		return this;
	}
};

myshape.gadgets.outfit.prototype = {
	gadgetSelector:".outfit-gadget",
	quickGadgetSelector:".outfit-gadget-quick",
	isInit:false,
	init:function(){
		var z = this;
		z.inherit = myshape.gadget.inherit;
		z.inherit(myshape.gadget);
		z.hoverable();
		z.clickable();
		z.ears();

		z.isInit = true;
	},
	states:{
		node:function(){},
		activated:function(el,oldState){
			return true;
		}
	},
	hoverable:function(){
		var z = this,speed = false;
		var settings = myshape.getGadget('popupSettings');
		if(z.isInit){
			$(this.gadgetSelector).dieHover();
			z.clickable();
		}
		switch(settings.getHoverSetting()){
			case "hs":
				speed = 2500;
			case "hf":
				speed = speed || 1300;
				$(this.gadgetSelector).liveHover(function(){
					if($(this).hasClass(z.quickGadgetSelector)) return false;
		
					z.doState(this,'activated',{id:z.getOutfitID(this)});
				},function(){},{on:speed});
		}

	},
	clickable:function(){
		var z = this;
		$(z.gadgetSelector).live('click',function(){
			z.doState(this,'activated',{id:z.getOutfitID(this)});
			$(this).removeClass('jq-hover');//cancels any hover state triggers that have not been fired yet
			return false;
		});
	},
	getOutfitID:function(el){
		var node = this.getNode(el);
		return $(node).find("input[name=styleID]").val();
	},
	ears:function(){
		var z = this;
		z.listen('popupSettings.state.settingChanged',function(el,key,data){
			z.hoverable();//reset hoverable
		});
	}
};

myshape.gadgets.outfitPopup = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.outfitPopup();
	} else {
		this.init();
		return this;
	}
};

myshape.gadgets.outfitPopup.prototype = {
	gadgetSelector:".outfit-detail-popup",
	activeSelector:".outfit-detail-popup.active",
	styleNodeSelector:".outfit-component",
	init:function(){
		var z = this;
		z.inherit = myshape.gadget.inherit;
		z.inherit(myshape.gadget);

		z.hoverable();
		z.closeable();
		z.imageZoomable();
		z.tabsClickable();
		z.componentAddToBagable();
		z.stylesPoppable();
		z.addToBagable();

		z.colorSizeGadget = myshape.getGadget('colorSizePicker');

		z.ears();
	},
	ears:function(){
		var z = this;
		z.listen('outfit.state.activated',function(el,key,data){
			z.open(data.data.id,el);
		});
		z.listen('stylePopup.state.beforeOpen',function(el,key,data){
			z.close();
		});
	},
	states:{
		node:function(){},
		building:function(el,oldState,data){
			var z = this;

			var outfitData = data;

			var src = myshape.util.imagePath('large',outfitData.image);
			var zoomSrc = myshape.util.imagePath('zoom',outfitData.image);

			//this.imageGadget.load(el,src,zoomSrc);

			$(el).find(".zoomable-image-gadget").dataset('zoomsrc',zoomSrc).find('img').attr('src',src);

			var desc = '<span style="text-align:center;color:#d4d4d4;">No description available at this time.</span>';

			if(outfitData.description){
				if(outfitData.description.length){
					desc = outfitData.description;
				}
			}

			$(el).find(".outfit-text.holder").html(desc);
			$(el).find(".style-id.holder").html(outfitData.styleID);
			
			var styleCont = $(el).find(".tab-content.styles .components")[0];
			var template = $(styleCont).find(".line-item.outfit-component")[0];

			$(styleCont).html("");

			$.each(outfitData.components,function(k,v){
				if(v.colors && v.colors[v.defaultColor]){

					var node = $(template).clone()[0];

					z.colorSizeGadget.build(node,v);
					$(node).find(".designer-name").html(v.designer);
					var price = myshape.util.money(v.price);
					if(v.salePrice){
						var priceHolder = $(node).find(".sale-price-holder").show()[0];
						$(priceHolder).find("strike").html('$'+price.split('.')[0]);
						$(priceHolder).find(".sale-price").html('$'+myshape.util.money(v.salePrice));
						price = '';
					} else {
							price = '$'+price.split('.')[0];
					}
					$(node).find(".price-holder").eq(0).html(price);

					$(node).find("img").attr('src',myshape.util.imagePath('browse',v.image));
					$(node).find("input[name=styleID]").val(v.id);
					$(node).appendTo(styleCont);

				}
			});

			z.colorSizeGadget.activateSelectables(el);

			z.activateScrollable(el);
			
			return true;// i am run only when i get the inital data
		},
		fromCache:function(el){
			//this.imageGadget.reload(el);
			this.colorSizeGadget.activateSelectables(el);
			this.activateScrollable(el);
			return true;
		},
		opened:function(el,oldState,data){
			$(el).css({opacity:''});//there seems to be a bug where the popup sometimes does not finish fading in
			return true;// i am run every time i become visible even if i have not been loaded yet
		},
		beforeOpen:function(el){
			return true;//self documenting
		},
		errored:function(){
			return true;
		}
	},
	stylesPoppable:function(){
		var z = this;
		$(this.gadgetSelector+" .outfit-component img").live('click',function(){
			var imageColor = myshape.util.colorFromSrc($(this).attr('src'));
			myshape.getGadget('stylePopup').showPopupFromData({styleID:$(this).parents(".outfit-component").find("input").val(),color:imageColor});
			return false;
		});
	},
	imageZoomable:function(){
		$(this.gadgetSelector+" .zoomable-image-gadget").liveHoverZoom(function(ev,conf){
			$(conf.zoomtarget).next().hide();
			$(conf.zoomtarget).show();
		},function(ev,conf){
			$(conf.zoomtarget).hide();
			$(conf.zoomtarget).next().show();
		},{zoomtarget:this.activeSelector+" .zoom-target",zoomloading:function(){
			return $("<div>").html(myshape.util.loadingImage()+' loading...')[0];
		}});
	},
	popLocked:false,
	hoverable:function(){
		var z = this;
		$(this.gadgetSelector).liveHover(function(){},function(){
			if(!z.popLocked){
				z.close();
			}
		},{off:900});
	},
	closeable:function(){
		var z = this;
		$(this.gadgetSelector+" .close-link").live('click',function(){
			z.close();
			return false;
		});
	},
	tabsClickable:function(){
		var z = this;
		$(this.gadgetSelector+" .tab a").live('click',function(){
			var tab = $(this).parents(".tab")[0];
			if(!$(tab).hasClass('active')){
				var node = z.getNode(this);
				var tabHolder = $(node).find(".tab-holder");

				$(tabHolder).find(".tab").removeClass('active');

				$(tab).addClass('active');

				var parts = $(this).attr('href').split('#');
				var cls = parts[1] || '';

				var tabs = $(node).find(".tab-content");

				if(cls){
					//check for tabs that are only supposed to show up if na particular tab is selected
					$(tabHolder).find(".conditional-tab").hide().filter(".tab-"+cls).show();
				}

				$(tabs).removeClass('active');
				var tabContent = $(node).find(".tab-content."+cls)[0];

				$(tabContent).addClass('active');

				$(node).windowUncolide();
			}
			return false;
		});
	},
	cache:{},
	currentPopup:false,
	open:function(id,el){
		var z = this;
		var template;
		var cached = false;
		if(!z.isCached(id)){
			template = z.buildTemplate(id);
		} else {
			cached = true;
			template = z.getFromCache(id);
		}

		//this is ugly but i need to get the dims of the passed element before the "beforeOpen" state change
		var dims = {x:0,y:0};
		if(el){
			var dims = $(el).getDims();
		}


		z.close();
		//set the current popup and flag all created popups as "active" meaning not the orig hidden template
		z.currentPopup = $(template).addClass('active')[0];

		z.doState(this,'beforeOpen');

		$(template).appendTo($("body")[0]);

		$(template).hide().css({zIndex:1000}).fadeIn('fast',function(){
			$(this).center(window);
			if(cached){
				z.doState(this,'prepare');
			}
			z.doState(this,'opened');
		});

		//if(el){
		//	$(template).top(dims.y).left(dims.x);
		//} else {
			$(template).center(window);
			
		//}

	},
	close:function(){
		if(this.currentPopup){
			$(this.currentPopup).remove();
			this.currentPopup = null;
		}
	},
	getFromCache:function(id){
		if(this.isCached(id)){
			var template = this.cache[id];
			//this.stopLoading(template); should already be stopped
			template = $(template).clone(true)[0];
			this.doState(template,'fromCache');
			return template;
		}
		return false;
	},
	isCached:function(id){
		return this.cache[id]?true:false;
	},
	buildTemplate:function(id){
		var z = this;
		var template = this.getTemplate();

		z.startLoading(template);

		myshape.ajax.getOutfitDetails(id,function(data){

			if(!data.error){
				z.doState(template,'building',data.data);
				z.stopLoading(template);
				$(template).windowUncolide();
			} else {
				z.doState(template,'errored',data);
				$(template).find(".loading").html('error loading outfit: '+data.error);
			}
			z.cache[id] = $(template).clone(true)[0];
		});

		return template;
	},
	getTemplate:function(){
		return $("#outfit-detail-popup-template "+this.gadgetSelector).clone()[0];
	},
	activateScrollable:function(node){
		scrollableCont = $(node).find(".tab-content.styles").jToolsScrollable({
			disabledClass:'scroll-nav-disabled',
			clickable:false,
			items:".components",
			size:3
		})[0];

		if($(scrollableCont).find(".line-item").length > 3){
			$(scrollableCont).find(".next").removeClass('scroll-nav-disabled');
		}
	},
	startLoading:function(template){
		$(template).find(".loading").show().find(".loading-image").html(myshape.util.loadingImage());
		$(template).find(".popup-content").hide();
	},
	stopLoading:function(template){
		$(template).find(".loading").hide();
		$(template).find(".popup-content").show();
	},
	addToBagable:function(el){
		var z = this;
		$(z.gadgetSelector+" .add-mybag").live('click',function(){
			z.addToBag(z.getNode(this));
		});
	},
	componentAddToBagable:function(){
		$(this.gadgetSelector+" input.add-single-mybag").live('click',function(){
			var z = this;
			if($(z).hasClass('pending-request')) return;

			var comp = $(z).parents(".outfit-component")[0];
			var colorSize = myshape.getGadget('colorSizePicker').getColorSize(comp);
			var styleID = $(comp).find("input[name=styleID]").val();
			if(colorSize.color && colorSize.size){

				
				var loadingBox = $(myshape.util.loadingImage()).insertAfter(z)[0];

				//this logic is duplicated from the style pop!
				$(z).addClass('pending-request')
				myshape.ajax.addToCart(styleID,colorSize.color,colorSize.size,1,function(data){
					$(loadingBox).remove();
					$(z).removeClass('pending-request');
					if(data.error){
						$(z).fadeBox("<div style='background:#fff;padding:5px;font-weight:bold;color:#999;' class='error-border'>"+data.error+"</div>");
					} else {
						if (data.redirectTo) {
							location.href = data.redirectTo;
						} else {
							myshape.getGadget('bag').updateCounter(data.data.cartCount);
							$(z).fadeBox("<div style='background:#fff;padding:5px;font-weight:bold; border:1px solid green;color:#999;'>This item has been added to your cart</div>");
						}
					}
				});
			} else {
				$(this).fadeBox("<div style='background:#fff;padding:5px;font-weight:bold;color:#999;' class='error-border'>Please select a color and size before adding to bag.</div>");
			}
		});
	},
	addToBag:function(node){
		var z = this;
		var styles = [];
		
		$(node).find(".outfit-component").each(function(){
				var colorSize = z.colorSizeGadget.getColorSize(this);
				if(colorSize.color && colorSize.size){
					styles[styles.length] =	$(this).find("input[name=styleID]").val()+','+(colorSize.color || '')+','+(colorSize.size || '');
				}
		});
		if(!styles.length) return;

		var bag = $(node).find(".add-mybag")[0];
		if(!$(bag).hasClass('loading')){
			if(styles.length){
				$(bag).addClass('loading');
				var loader = $(myshape.util.loadingImage()).insertBefore(bag)[0];
				$(node).find(".add-mybag")
				myshape.ajax.addManyToCart(styles,function(data){
					if(loader){
						$(loader).remove();
					}
					$(bag).removeClass('loading');

					var maxCount = 0;
					$.each(data,function(k,response){
						var obj = response.data;
						var styleID = false;

						if(obj.item){
							styleID = obj.item.styleID;
						} else if(response.currentStyle.split(',')[0].length > 0){
							styleID = response.currentStyle.split(',')[0];
						}

						if(obj.cartCount > maxCount){
							maxCount = obj.cartCount;
						}

						if(styleID){
							var component = $(node).find("input[value="+styleID+"]").parents(".outfit-component")[0];
							if(component){
								if(!response.error){
									var good = $("<div class='border-radius' style='border:2px solid green;padding:5px;background:#fff;'></div>")[0];
									$(component).fadeBox($(good).html('Item has been<br/>added to your cart.'),3000,node);
								} else {
									$(component).fadeBox(myshape.util.errorBox(response.error),3000,node);
								}
							}
						} else {
							$(node).find(".add-mybag").fadeBox(myshape.util.errorBox("Unknown error finding the style id of one of your components."),3000,node);
						}
					});
					myshape.getGadget('bag').updateCounter(maxCount);
				});
			} else {
				$(node).find(".add-mybag").fadeBox(myshape.util.errorBox("Unable to find any items to add to your bag."),3000,node);
			}
		}
	},
	//TODO
	selectTab:function(el,tab){
		var node = this.getNode(el);

	}
};

myshape.gadgets.popupSettings = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.popupSettings();
	} else {
		this.init();
		return this;
	}
};

myshape.gadgets.popupSettings.prototype = {
	gadgetSelector:".popup-settings-gadget",
	init:function(){
		var z = this;
		z.inherit = myshape.gadget.inherit;
		z.inherit(myshape.gadget);

		z.openable();
		z.settingsClickable();
	},
	states:{
		node:function(){},
		opened:function(){return true;},
		settingChanged:function(el,oldState,data){
			if(data.val != this.getSetting(this.popupSettingsKey)){
				this.setSetting(this.popupSettingsKey,data.val);
				return true;
			} else {
				return false;
			}
		}
	},
	settingsClickable:function(){
		var z = this;
		$(this.gadgetSelector+" input[type=radio]").live('click',function(){
			var val = $(this).val();
			var name = $(this).attr('name');
			z.doState(this,'settingChanged',{val:val,name:name});
			var el = this;
			setTimeout(function(){
				z.closeDropdown(el);
				z.doState(el,'node',{});
			},500);
		});

		$(this.gadgetSelector+" .radio-label").live('click',function(){
			$(this).prev().click();
			return false;
		});
	},
	openable:function(){
		var z = this;
		$(z.gadgetSelector+" .dropdown-handle").live('click',function(){
			if($(this).hasClass('opened')){
				z.closeDropdown(this);
				z.doState(this,'node',{});
			} else {
				z.openDropdown(this);
				z.doState(this,'opened',{});
			}
			return false;
		});
	},
	//actions
	settingsCookieName:'mys_set',
	popupSettingsKey:'hs',
	cookieLife:30,//days
	popupSettingValues:{hoverFast:'hf',hoverSlow:'hs',click:'c'},
	getHoverSetting:function(){
		return this.getSetting(this.popupSettingsKey) || this.popupSettingValues.hoverFast;
	},
	getSetting:function(k){
		var data = this.getSettings();
		return data?data.k:null;
	},
	setSetting:function(k,val){
		data = this.getSettings() || {};
		data.k = val;
		var storable = JSON.stringify(data);
		var storage = false
		try{
			if(window.localStorage){
				window.localStorage['settings'] = storable;
				storage = true;
			}
		}catch(e){storage = false;}
		if(!storage){
			myshape.util.createCookie(this.settingsCookieName,storable,this.cookieLife);
		}
	},
	getSettings:function(){
		var storage = false,currentSettings, data;
		try{
			if(window.localStorage){
				data = window.localStorage['settings'];
				storage = true;
			}
		}catch(e){storage = false;}
		if(!storage){
			data = myshape.util.readCookie(this.settingsCookieName);
		}
		if(data){
			var parsed = false;
			if(JSON && JSON.parse){
				try{
					data = JSON.parse(data);
					parsed = true;
				} catch(e){}
			}
			if(!parsed) data = false;
		}
		return data;
	},
	dropDown:false,
	openDropdown:function(el){
		var dd = this.dropDown = this.getDropdown(el);
		$(dd).css({top:'0px',left:'0px'}).show();
		//NOTE element MUST be shown here to get proper x,y! 
		//the element must also have top and left set otherwise it will ab pos where it would be rel to the document and x,y would be wrong
		//i use the 0,0 to get the origin x,y of the parent container because i cannot use el.offsetTop in IE and i want to position rel to the popup not the doc

		var handle = this.getHandle(el);
		var handleDims = $(handle).getDims(true);
		var ddDims = $(dd).getDims(true);

		handleLeft = handleDims.x-ddDims.x;
		handleTop = handleDims.y-ddDims.y;

		$(dd).left(handleLeft-(ddDims.w-handleDims.w)).top(handleTop+handleDims.h);

		$(handle).css({background:'#d4d4d4'}).addClass('opened');
		$(handle).find(".open-arrow").hide();
		$(handle).find(".close-arrow").show();

		this.initSettings(dd);
	},
	closeDropdown:function(el){
		if(this.dropDown){
			$(this.dropDown).hide();
		}
		var handle = this.getHandle(el);
		$(handle).css({background:''}).removeClass('opened');
		$(handle).find(".close-arrow").hide();
		$(handle).find(".open-arrow").show();
	},
	getHandle:function(el){
		return $(this.getNode(el)).find(".dropdown-handle")[0];
	},
	getDropdown:function(el){
		return $(this.getNode(el)).find(".dropdown")[0];
	},
	initSettings:function(dropDown){
		var popupSpeed = this.getSetting(this.popupSettingsKey);
		if(popupSpeed){
			$(dropDown).find("input[type=radio]").each(function(){
				if($(this).val() == popupSpeed){
					$(this).attr('checked',1);
				}
			});
		}
	}
};


myshape.gadgets.searchBox = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.searchBox();
	} else {
		this.init();
		return this;
	}
}

myshape.gadgets.searchBox.prototype = {
	searchRedirect:true,//set this to true to make it so the top search box redirects to the search page
	gadgetSelector:"#style-search",
	defaultText:"search...",
	init:function(){
		var z = this;
		z.inherit = myshape.gadget.inherit;
		z.inherit(myshape.gadget);

		z.activateWatermark();
		z.submitable();

		z.ears();

		z.checkHash();
	},
	loading:false,
	checkHash:function(){
		var hash = location.hash;
		if(hash.length){
			hash = hash.substr(1);//remove #
			queryString = myshape.util.parseQueryString(hash);
			if(queryString.search){
				var styleID = queryString.search;

				/*/remove search key from the queryString object
				delete queryString.search;
				queryString = $.param(queryString);
				//update the hash without the queryString
				location.hash = "#"+(queryString || '');*/

				if(styleID.length){
					$(this.gadgetSelector).val(styleID);
					this.doSearch(styleID);
				}
			}
		}
	},
	ears:function(){
		var z = this;

		var errorDetected = function(el,key,data){
			if(z.loading){
				myshape.getGadget(z.loading).close();
				z.loading = false;
				if(data.data.error){
					z.showError(data.data.error);
				} else {
					z.showError('Unknown error processing ID');
				}
			}
		};

		var loadingOff = function(el,key,data){
			z.loading = false;
		};

		z.listen('stylePopup.state.errored',errorDetected);
		z.listen('outfitPopup.state.errored',errorDetected);

		z.listen('stylePopup.state.opened',loadingOff);
		z.listen('outfitPopup.state.opened',loadingOff);
	},
	activateWatermark:function(){
		$(this.getInput()).watermark(this.defaultText);
	},
	submitable:function(){
		var z = this;
		$(this.gadgetSelector).submit(function(){
			try{
				var val = $(z.getInput()).val();
				if(val != z.defaultText && val != ''){
					z.doSearch(val);
				}
			}catch(e){
				console.error(e);
			};
			return false;
		});

	},
	states:{
		node:function(){return true}
	},
	doSearch:function(val){
		this.loading = false;
		val = $.trim(val);
		if(this.isStyleID(val)){
			this.loading = 'stylePopup';
			myshape.getGadget('stylePopup').showPopupFromData({styleID:val});
		} else if(this.isOutfitID(val)){
			this.loading = 'outfitPopup';
			myshape.getGadget('outfitPopup').open(val);
		} else {
			if(this.searchRedirect){
				location.href = "/shop/search?q="+escape(val);
				return;
			} else {
				this.showError('invalid outfit or style ID');
			}
		}
		if(this.loading){
			$(this.getInput()).val('').blur();
		}
	},
	getInput:function(){
		return $(this.gadgetSelector+" input[type=text]")[0];
	},
	setVal:function(val){
		$(this.getInput()).val(val || '').blur();
	},
	showError:function(msg){
		$(this.getInput()).fadeBox(myshape.util.errorBox(msg));
	},
	isStyleID:function(val){
		//added support for negative style ids even tho it may be a non issue
		return /^-?\d+$/.test(val);
	},
	isOutfitID:function(val){
		return /^[a-zA-Z].\d+$/.test(val);
	}
};

myshape.gadgets.baynote = function(){
	if(typeof(this.init) !== 'function'){
		return new myshape.gadgets.baynote();
	} else {
		this.init();
		return this;
	}
}

myshape.gadgets.baynote.prototype = {
	gadgetSelector:"",//maybe this should be the selector for the bn rec cont in the popup
	init:function(){
		var z = this;
		z.inherit = myshape.gadget.inherit;
		z.inherit(myshape.gadget);

		z.getBaynoteUser(function(data){});

		z.ears();
	},
	ears:function(){
		var z = this;
		//style popup opened
		z.listen('stylePopup.state.opened',function(el,key,data){
			var styleID = data.object.getStyleIDFromPopup(el);
			if(styleID){
				z.viewOpen(styleID);
			}
		});

		//style popup closed
		z.listen('stylePopup.state.closed',function(el,key,data){
			z.viewClosed();
		});

		z.listen('stylePopup.state.mostViewedClicked',function(el,key,data){
			var fromStyleID = data.object.getStyleIDFromPopup(el);
			if(fromStyleID && styleID && data.guide){
				z.viewRecommendedClicked(fromStyleID,data.styleID,data.guide,data.rank || 1);
			}
		});
	},
	policyGenerator:'/modules/thirdparty/baynote/policyrest.php',
	policyCookieName:'mysbnup',
	userPolicy:false,
	userPolicyCallbacks:[],
	gettingUserPolicy:false,
	getBaynoteUser:function(cb){
		var z = this;
		if(!z.userPolicy){
			var jsonString = myshape.util.readCookie(this.policyCookieName);
			if(jsonString){
				try{
					eval('z.userPolicy = '+$.trim(unescape(jsonString)));
				} catch(e){
					$.logWarn('failed to eval json from baynote cookie!',e);
				}
			}
		}

		if(!z.userPolicy){
			z.userPolicyCallbacks[z.userPolicyCallbacks.length] = cb;
			if(!z.gettingUserPolicy){
				z.gettingUserPolicy = true;
				$.getJSON(z.policyGenerator+'?callback=?',{},function(data){
					z.gettingUserPolicy = false;
					$.each(z.userPolicyCallbacks,function(k,v){
						v(data);
						delete z.userPolicyCallbacks[k];
					});
				});
			}
		} else {
			cb(z.userPolicy);
		}

		return this;
	},
	//hold the data related to the style here
	interactionData:false,
	//this time will wait 
	lingerTimer:false,
	viewOpen:function(styleID){
		var z = this;
		z.baynoteObserver('v',styleID,function(url){
			//alert("baynote request");
		});
		/*z.eventRest('v',styleID,function(url){
			//alert("baynote request:",styleID,url);
		});*/
		clearTimeout(z.lingerTimer);
		var totalLingerMS = (z.userPolicy.policy.dt-5)*1000;
		z.lingerTimer = setTimeout(function(){
			z.viewLingered(styleID);
		},totalLingerMS);
	},
	viewLingered:function(styleID){
		this.baynoteObserver('l',styleID,function(url){
			//$.log("baynote request: ",styleID,url);
			//alert("baynote request");
		});
		/*this.eventRest('l',styleID,function(url){
			//alert("baynote request");
		});*/
	},
	viewClosed:function(){
		clearTimeout(this.lingerTimer);
	},
	viewClicked:function(){
/*
code	www
customerId	myshape
fmt	1
len	234
msg	{"a":"c","c":"d&g&s","d":"http://myshape.lhj.com/shop/productview/22411","r":"http://myshape.lhj.com/shop/productview/22438","t":1253573804419,"u":"6922529527074121199","dd":"javascript://","de":{"ti":"myShape.com","nw":954,"nl":143}}
msgId	4
*/
	},
	viewRecommendedClicked:function(fromStyleID,styleID,guideType,rank){

		this.baynoteObserver({
			a:'c',
			d:'http://www.myshape.com/shop/productview/'+fromStyleID,
			dd:'http://www.myshape.com/shop/productview/'+styleID,
			gt:'ProductGuide',
			gr:guideType,
			rb:rank
		},styleID,function(){});
	},
	//### bay note api interaction methods ###########################
	//use baynote api in event rest mode
	eventRest:function(action,styleID,callback){
		var z = this;
		var params = this.baynoteParams(action,styleID);
		//params.key = this call is inactive because it is considered a security risk to have the api key in plain text;
		var url = "http://myshape-www.baynote.net/baynote/eventrest?"+$.param(params)+"&v=1";
		this.imageRequest(url,function(){callback.call(this,url,params)});
	},
	//use original services via baynoteListener api
	baynoteObserverMsgID:0,
	baynoteObserver:function(action,styleID,callback){
		var moreParams = false;
		if(typeof action == 'object'){
			moreParams = action;
			action = moreParams.a;
		}
		var msg = this.jsonString(this.baynoteParams(action,styleID,moreParams));
		var params = {
			code:'www',
			customerId:'myshape',
			fmt:1,
			len:msg.length,
			msg:msg,
			msgId:this.baynoteObserverMsgID++
		};

		var url = "http://myshape-www.baynote.net/baynote/tags2/baynoteObserver/listener2?"+$.param(params);
		this.imageRequest(url,function(){callback.call(this,url,params)});
	},

	//### baynote utility api methods
	baynoteParams:function(action,styleID,moreParams){
		var user = this.userPolicy;
		var params = {
			a:action || 'v',//v,l,c
			customerId:'myshape',
			code:'www',
			//fake url so we dont have to reconfigure the "guide" results
			d:"http://www.myshape.com/product_info.php?style_id="+(styleID||0),
			//referring domain
			r:window.location.href,
			t:new Date().getTime(),
			c:user.policy.cd,
			u:user.policy.userId,
			format:'json'
		};

		//if im lingering i know that i want to set the required linger time which is logically always > the linger time specified in the policy
		if(action == 'l'){
			params.du = user.policy.dt+1;
		}

		if(moreParams){
			params = $.extend(params,moreParams);
		}

		return params;
	},
	//write only IO method
	imageRequest:function(url,callback){
		var img = new Image();
		var done = function(){
			callback.apply(this,arguments);
		 	delete img;
		};
		$(img).bind('load',done).bind('error',done);
		img.src = url;
	},
	//really basic json stringify function
	jsonString:function(obj){
		return myshape.util.jsonString(obj);
	}
}

//default gadget inits
$(function(){
	//myshape.getGadget('gadgetTalkDebug');

	myshape.getGadget('popupSettings');

	myshape.getGadget('style');
	myshape.getGadget('stylePopup');

	myshape.getGadget('outfit');
	myshape.getGadget('outfitPopup');

	myshape.getGadget('searchBox');
	myshape.getGadget('liveChat');
});
