/**************************************************************************\
* 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.                     *
\**************************************************************************/

var myshape = {};

myshape.util = {
	timeStamp:function(){
		return Math.ceil(new Date().getTime()/1000);
	},
	loadingImage:function(){
		return '<img alt="loading results..." src="/modules/outfit/tpl/default/images/ajax-loader.gif" style="display:inline;width:auto;height:auto;"/>';
	},
	loadingImageBig:function(){
		return '<img alt="loading results..." src="/modules/outfit/tpl/default/images/loading.gif" style="display:inline;width:auto;height:auto;"/>';
	},
	isOdd:function(num){
		return (num%2 == 1);
	},
	baseName:function(path){
		if(path){
			var parts = path.split('/');
			path = parts[parts.length-1];
			if(path.indexOf('?') > -1){
				parts = path.split('?');
				path = parts[0];
			}
		}
		return path || '';
	},
	dirName:function(path){
		var parts = path.split('/');
		if(!parts.length) return path;
		delete parts[parts.length-1];

		path = parts.join('/');
		if(path.charAt(path.length-1) == '/'){//ie7 errors accessing string chars like an array
			path = path.substr(0,path.length-1);
		}

		return path || '';
	},
	money:function(mnt) {
		mnt -= 0;
		mnt = (Math.round(mnt*100))/100;
		return (mnt == Math.floor(mnt)) ? mnt + '.00'
			: ( (mnt*10 == Math.floor(mnt*10)) ?
				mnt + '0' : mnt);
	},
	date:function(){
		var date = new Date();
		return (date.getMonth()+1)+'-'+date.getDate()+'-'+(date.getYear()+1900);
	},
	cookieDomain:function(hostname){
		if(!hostname) hostname = location.hostname;
		if(hostname.split('.').length > 2){
			var parts = hostname.split('.');
			parts[0] = '';
			return parts.join('.');
		}
		return hostname;
	},
	createCookie:function(name,value,days) {
		if (days) {
			var date = new Date();
			date.setTime(date.getTime()+(days*24*60*60*1000));
			var expires = "; expires="+date.toGMTString();
		}
		else var expires = "";

		window.document.cookie = name+"="+value+expires+"; path=/; domain="+this.cookieDomain()+";";
	},
	readCookie:function(name) {
		var nameEQ = name + "=";
		var ca = window.document.cookie.split(';');
		for(var i=0;i < ca.length;i++) {
			var c = ca[i];
			while (c.charAt(0)==' ') c = c.substring(1,c.length);
			if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
		}
		return null;
	},
	eraseCookie:function(name) {
		this.createCookie(name,"",-1);
	},
	mediaSource:function(){
		return myshape.constants.MEDIA_SOURCE || location.protocol+'//www.myshape.com';
	},
	imagePath:function(key,file){
		if(this.imagePaths[key]){
			return this.mediaSource()+this.imagePaths[key]+'/'+file;
		}
		return '';
	},
	imagePaths:{
		thumb:'/images/products/thumb',
		browse:'/images/products/browse',
		large:'/images/products/large',
		zoom:'/images/products/zoom',
		swatch:'/images/products/swatch'
	},
	colorFromSrc:function(src){
		return ((this.baseName(src).split('-')[1] || '').split('.')[0] || '').split('_')[0] || '';
	},
	styleIdFromSrc:function(src){
		return this.baseName(src).split('-')[0];
	},
	typeFromSrc:function(src){
		return (this.baseName(src).split('.')[0] || '').split('_')[1] || 'main';
	},
	isValidEmail:function(email){
		return this.isRFC822ValidEmail(email);
	},
	isRFC822ValidEmail:function(sEmail) {
		var sQtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]';
		var sDtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]';
		var sAtom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+';
		var sQuotedPair = '\\x5c[\\x00-\\x7f]';
		var sDomainLiteral = '\\x5b(' + sDtext + '|' + sQuotedPair + ')*\\x5d';
		var sQuotedString = '\\x22(' + sQtext + '|' + sQuotedPair + ')*\\x22';
		var sDomain_ref = sAtom;
		var sSubDomain = '(' + sDomain_ref + '|' + sDomainLiteral + ')';
		var sWord = '(' + sAtom + '|' + sQuotedString + ')';
		var sDomain = sSubDomain + '(\\x2e' + sSubDomain + ')*';
		var sLocalPart = sWord + '(\\x2e' + sWord + ')*';
		var sAddrSpec = sLocalPart + '\\x40' + sDomain; // complete RFC822 email address spec
		var sValidEmail = '^' + sAddrSpec + '$'; // as whole string

		var reValidEmail = new RegExp(sValidEmail);

		if (reValidEmail.test(sEmail)) {
			return true;
		}

		return false;
	},
	isDigits:function(val){
		return /^\d+$/.test(val);
	},
	parseQueryString:function (queryString){
		var qsobj = {};
		var search = queryString;
		if(search.length){
			if(search.indexOf('?') == 0){
				search = search.substr(1);
			}
			var chunks = search.split('&');
			$.each(chunks,function(k,v){
				var keyVal = v.split('=');
				var key = keyVal[0];
				if(key){
					qsobj[key] = unescape(keyVal[1] || '');
				}
			});
		}
		return qsobj;
	},
	errorBox:function(html){
		var box = $("<div class='border-radius error-border' style='background:#fff;font-weight:bold;padding:10px;border-width:2px !important;'/>")[0];
		if(html) $(box).html(html);
		return box;
	},
	jsonString:function(obj){
		if(JSON && JSON.stringify) return JSON.stringify(obj);
		//will fail on any special chars [",\n etc] and will tostring all array values
		var out = [];
		for(i in obj){
			if(obj[i] instanceof Array){
				out[out.length] = '"'+i+'":["'+obj[i].join('","')+'"]';
			} else if(typeof obj[i] == 'object'){
				out[out.length] = '"'+i+'":'+this.jsonString(obj[i]);
			} else {
				out[out.length] = '"'+i+'":"'+obj[i]+'"';
			}
		}
		return "{"+out.join(',')+"}";
	}
};


if(!myshape.constants){
	myshape.constants = {
		MEDIA_SOURCE:false
	};
}

myshape.debug = {
	lockPopups:function(){
		myshape.getGadget('stylePopup').popLocked = true;
		myshape.getGadget('outfitPopup').popLocked = true;
	}
};

// all gadgets live here
myshape.gadgets = {};

//shared, syncronous, gadget messaging with context
/*
the goals of this object are:
	to break appart functionality cleanly as it makes sense to speed development
	to provide a container agnostic environment for gadgets
how:
	gadgets have the ability to "evesdrop" on other gadgets
	no up calls - do not refrence other gadgets in a gadget unless the gadget you are writing contains them - meaning that the gadget you are writing depends on the gadget
*/
myshape.gadgetTalk = {
	listeners:{},
	listen:function(key, onlisten){
		if(!this.listeners[key]){
			this.listeners[key] = [];
		}
		this.listeners[key][this.listeners[key].length] = onlisten;
	},
	say:function(el,object,key,data){
		data = {object:object,data:data};
		if(this.listeners[key]){
			$.each(this.listeners[key],function(k,v){ v(el,key,data);});
		}
		if(key != '*' && this.listeners['*']){
			$.each(this.listeners['*'],function(k,v){ v(el,key,data);});
		}
	}
};

// this is an abstract prototype that all gadgets inherit from
myshape.gadget = {
	inherit:function(superClass){
		var z = this;
		if(!z.name){
			myshape.nameGadgets();
		}
		$.each(superClass,function(k,v){
			if(typeof(z[k]) == 'undefined'){//default is protected
				z[k] = v;
			}
		});
		//z.peer = myshape.gadgets;
		z.parent = superClass;
	},
	getHTML:function(server,action,params,complete){
		$.post(server,$.extend({action:action},params||{}),complete,'html');
	},
	getJSON:function(server,action,params,complete){
		$.post(server,$.extend({action:action},params||{}),complete,'json');
	},
	states:{
		example:function(el,oldState){
			$(el).wrap('<div class="example-wrapper"></div>');
			return true;
		}
	},
	doState:function(el,state,data){
		data = data || {};
		if(typeof(this.states[state]) == 'function'){
			this.execState = this.states[state];// copy to this object context
			if(this.execState(el,this.getState(el) ||false,data || {})){
				this.say(el,'state.'+state,data);

				this.setState(el,state);
				return true;
			}
			//no error just do nothing
			if(!this.readError(el)){
				return false;
			}
		} else {
			this.writeError(el,'cannot handle state '+state);
		}
		this.handleError(el,this.currentState || false,state);
		return false;
	},
	/*extend this to provide custom error handlers related to state change errors*/
	handleError:function(el,oldState,newState){
		this.deleteError(el);
	},
	writeError:function(el,error){
		el.error = error;
	},
	readError:function(el){
		return el.error || false;
	},
	deleteError:function(el){
		el.error = false;
	},
	getState:function(el){
		return el.state || this.getDefaultState();
	},
	setState:function(el,state){
		el.state = state || this.getDefaultState();
		return true;
	},
	getDefaultState:function(){
		if(this.defaultState){
			return this.defaultState;
		}
		var ret = false;
		$.each(this.states,function(k,v){
			ret = k;
			return false;//break
		});
		return ret;
	},
	say:function(el,key,data){
		myshape.gadgetTalk.say(el,this,this.name+'.'+key,data || {});
	},
	listen:function(key,onHear){
		myshape.gadgetTalk.listen(key,onHear);
	},
	sayAsync:function(el,key,data){
		var z = this;
		setTimeout(function(){
			this.say(el,key,data);
		},1);
	},
	getNode:function(el){
		var node = el;
		if(!$(el).hasClass(this.gadgetClass || this.gadgetSelector.replace('.',''))){
			node = $(el).find(this.gadgetSelector)[0];
			if(!node){
				if($(el).parents(this.gadgetSelector).length > 0){
					node = $(el).parents(this.gadgetSelector)[0];
				}
			}
		}
		return node;
	}
};

myshape.nameGadgets = function(){
	$.each(myshape.gadgets,function(k,v){
		myshape.gadgets[k].prototype.name = k;
	});
};

myshape.getGadget = function(cls){
	if(!myshape.loadedGadgets){
		myshape.loadedGadgets = {};
		myshape.nameGadgets();
	}
	return myshape.loadedGadgets[cls]? myshape.loadedGadgets[cls] : (myshape.loadedGadgets[cls] = new myshape.gadgets[cls]);
}

myshape.ajax = {
	getStyleDetails:function(styleID,callBack){
		this.getSuperAction(styleID,callback);
	},
	getSuperAction:function(styleID,callBack){
		var params = styleID;
		if(typeof styleID != 'object'){
			params = {styleID:styleID};
		}
		$.each(params,function(k,v){
			if(!v){
				delete params[k];
			}
		});
		myshape.gadget.getJSON('/shop/styleserver','super',params,function(data){
			this.callBack = callBack || function(){};
			this.callBack(data);
		});
	},
	getOutfitDetails:function(styleID,callBack){
		myshape.gadget.getJSON('/shop/styleserver','outfitDetail',{styleID:styleID},function(data){
			this.callBack = callBack || function(){};
			this.callBack(data);
		});
	},
	//i think you have to be logged in to access these ajax calls - test first
	getPixelFromImage:function(src,x,y,callBack){
		myshape.gadget.getJSON('/trendsetter/server','getPixelFromImage',{image:src,x:x,y:y},function(data){
			this.callBack = callBack || function(){};
			this.callBack(data);
		});
	},
	getLighterDarkerFromPixel:function(src,x,y,callBack){
		myshape.gadget.getJSON('/trendsetter/server','getLighterDarkerFromPixel',{image:src,x:x,y:y},function(data){
			this.callBack = callBack || function(){};
			this.callBack(data);
		});
	},
	getLighterDarkerFromRGB:function(r,g,b,callBack){
		myshape.gadget.getJSON('/trendsetter/server','getLighterDarkerFromPixel',{rgb:[r,g,b].join(',')},function(data){
			this.callBack = callBack || function(){};
			this.callBack(data);
		});
	},
	//http://lazy.localhost/shop/cartaddajax?responseType=json&mode=style&styleID=15225&color=101&size=R0M
	addToCart:function(styleID,color,size,quantity,callBack){
		myshape.gadget.getJSON('/shop/cartaddajax','1',{mode:'style',responseType:'json',styleID:styleID,color:color,size:size,quantity:quantity},function(data){
			this.callBack = callBack || function(){};
			if(data.data && data.data.redirectTo){

			} else {}
			this.callBack(data);
		});
	},
	//styles must be an array or "-" delimited string of csv "styleID,color,size,quantity,[optional itemID],[optional wishlistID]"
	// color may be empty
	// size may be empty if a customer is logged in and customer has a reccomended size
	addManyToCart:function(styles,callBack){
		myshape.gadget.getJSON('/shop/cartaddajax','1',{mode:'style',responseType:'json','styles[]':styles||[]},function(data){
			this.callBack = callBack || function(){};
			this.callBack(data);
		});
	},
	//http://lazy.localhost/shop/wishlistadd?responseType=json&mode=style&ajax=1&styleID=15225&color=101&size=R0M
	addToWishlist:function(styleID,color,size,callBack){
		myshape.gadget.getJSON('/shop/wishlistadd','1',{mode:'post',responseType:'json',ajax:1,styleID:styleID,color:color,size:size},function(data){
			this.callBack = callBack || function(){};
			this.callBack(data);
		});
	},
	addComment:function(shopID,styleID,comment,callBack){
		myshape.gadget.getJSON('/shop/commentsave','1',{mode:'post',responseType:'json',ajax:1,styleID:styleID,comment:comment,shopID:shopID},function(data){
			this.callBack = callBack || function(){};
			this.callBack(data);
		});
	},
	//http://locallazy.myshape.com/shop/outfit-builder?action=saveOutfit&components=11603-,13198-301
	createCustomerOutfit:function(title,styleColors,callBack){
		var styleColorsFormatted = [];
		$.each(styleColors,function(k,v){
			if(typeof v == 'object' && v.length){
				styleColorsFormatted[styleColorsFormatted.length] = v.join('-');
			}
		});
		myshape.gadget.getJSON('/shop/outfit-builder','saveOutfit',{title:title,'components[]':styleColorsFormatted},function(data){
			this.callBack = callBack || function(){};
			this.callBack(data);
		});
	},
	//http://locallazy.myshape.com/shop/outfit-builder?action=deleteOutfit&customersOutfitsID=1
	deleteCustomerOutfit:function(outfitsID,callBack){
		myshape.gadget.getJSON('/shop/outfit-builder','deleteOutfit',{customersOutfitsID:outfitsID},function(data){
			this.callBack = callBack || function(){};
			this.callBack(data);
		});
	},
	browse:function(categoryID,page,callBack,extraParams){
		params = {responseType:'json'};
		params = $.extend(params,extraParams||{});
		if(categoryID) params['current-category'] = categoryID;
		if(+page) params['current-page'] = +page;
		//?colorMatch=234,196,52-215,180,81-234,194,25-244,208,86-216,177,27
		myshape.gadget.getJSON('/shop/browseserver','1',params,function(data){
			this.callBack = callBack || function(){};
			this.callBack(data);
		});
	},
	browseHTML:function(categoryID,page,callBack,extraParams){
		params = {};
		params = $.extend(params,extraParams||{});
		if(categoryID) params['current-category'] = categoryID;
		if(+page) params['current-page'] = +page;
		myshape.gadget.getHTML('/shop/browseserver','1',params,function(data){
			this.callBack = callBack || function(){};
			this.callBack(data);
		});
	},
	//http://locallazy.myshape.com/shop/register?action=ajax&firstname=flame&lastname=pants&emailaddress=email@email.com&password=my
	register:function(email,firstname,lastname,password,optIn,callBack){
		myshape.gadget.getJSON('/shop/register','ajax',{emailaddress:email,firstname:firstname,lastname:lastname,password:password,'subscribe-partner':(optIn?1:0)},function(data){
			this.callBack = callBack || function(){};
			this.callBack(data);
		});
	},
	//http://locallazy.myshape.com/shop/register?action=ajax&firstname=flame&lastname=pants&emailaddress=email@email.com&password=my
	login:function(email,password,remember,callBack){
		myshape.gadget.getJSON('/shop/login','ajax',{emailaddress:email,password:password,rememberlogin:(remember?'yes':'')},function(data){
			this.callBack = callBack || function(){};
			this.callBack(data);
		});
	},
	goSizeless:function(value,callBack){
		myshape.gadget.getJSON("/shop/processprofile","update",{attribute:238,value:value},function(data){
			this.callBack = callBack || function(){};
			this.callBack(data);
		});
	}
};

var syncSessionCookies = function(){
	//var sessid = myshape.util.readCookie('id');
	var cookieData = window.document.cookie.split(';');
	hits = 0;
	cookies = [];
	$.each(cookieData,function(k,v){
		v = $.trim(v);
		if(v.indexOf('id=') === 0) {
			cookies[cookies.length] = v;
			hits++;
			if(hits == 2){
				return false;
			}
		}
	});

	if(hits == 2){
		if(cookies[0] != cookies[1]){
			var days = 1;
			var date = new Date();
			date.setTime(date.getTime()+(days*24*60*60*1000));
			window.document.cookie = cookies[0]+"; expires="+date.toGMTString()+"; path=/;";
			window.document.cookie = cookies[0]+"; expires="+date.toGMTString()+"; path=/; domain="+myshape.util.cookieDomain()+";";
		}
	}
};

var setupFormSubmitWatch = function (){
	var formSelector = 'form.load-block';
	$(formSelector).each(function(){
		var loading = false;
		$(this).submit(function(){
			if(loading) return false;

			loading = true;
			return true;
		});
	});
};

var addPrintPage = function() {
	$('#js-printpage')
		.html('<a href="#">Print this page</a>')
		.find('a')
		.click(function() { window.print(); });
}

var activateSizeless = function() {
	$('#go-sizeless .save-button').live("click", function() {
		myshape.ajax.goSizeless($(this).parents("form").find("input:checked").val(), function(data) {
			$("#nyroModalBg").click();
		});
	});
}

$(function(){
syncSessionCookies();
setupFormSubmitWatch();
addPrintPage();
activateSizeless();
});


//douglas crockford version of the JSON api
if(!this.JSON){this.JSON={};}
(function(){function f(n){return n<10?'0'+n:n;}
if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+
f(this.getUTCMonth()+1)+'-'+
f(this.getUTCDate())+'T'+
f(this.getUTCHours())+':'+
f(this.getUTCMinutes())+':'+
f(this.getUTCSeconds())+'Z':null;};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}
var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}
function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}
if(typeof rep==='function'){value=rep.call(holder,key,value);}
switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}
v=partial.length===0?'[]':gap?'[\n'+gap+
partial.join(',\n'+gap)+'\n'+
mind+']':'['+partial.join(',')+']';gap=mind;return v;}
if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==='string'){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}
v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+
mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}
if(typeof JSON.stringify!=='function'){JSON.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}
rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}
return str('',{'':value});};}
if(typeof JSON.parse!=='function'){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}
return reviver.call(holder,key,value);}
cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+
('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}
if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}
throw new SyntaxError('JSON.parse');};}}());