/*----------------------------------------------------------
cookieMonster Object
Description: This object allows you to save and load javascript objects to and from the browser cookies. The object transform any object into JSON format to be stored in cookie. If the cookieMonster detects that the objectJSONstringis larger than 4092 it splits it and make sure to write the object in as many cookie as it needs. 
Remark: IE6 don't allow more than 4092 cookie size for the same domain, while other browsers enforce the 4092 per cookie but will allow other cookies to be wirtten on the same domain
Author: Amir Harel
twitter: @amir_harel 
------------------------------------------------------------------*/
var cookieMonster = {
	getObjProperties: function(obj)
	{
		var val = "";
		var c= "";
		
		//we need to know if the obj is an array
		if( obj instanceof Array )
			val = "[";
		else val = "{";		
		
		for( var prop in obj )
		{
			//we need to ignore functions
			if( typeof(obj[prop]) == 'function' )
				continue;
			if( val != "" && val != "[" && val != "{" ) val += ',';
			if( typeof(obj[prop]) == "object" )
			{
				val += prop + ":";
				val += this.getObjProperties(obj[prop]);
			}
			else
			{
				val += prop + ":" + encodeURIComponent(obj[prop]);
			}
		}
		
		if( obj instanceof Array )
			val += "]";
		else val += "}";
		return val;		
	} ,	
	
	prepareCookiesForSave: function(str)
	{
		var strArr = new Array();
		var tmpStr = str;
		var tmp;
		while( tmpStr.length >= 4092 )
		{
			tmp = tmpStr.substring(4091);
			tmpStr = tmpStr.substring(0,4091);
			strArr.push(tmpStr);
			tmpStr = tmp;
		}
		strArr.push(tmpStr);
		return strArr;
	},
	
	isBrowser: function( browsers )
	{
		var index = 0;
		var nav = navigator.userAgent;
		
		for(var i=0;i<browsers.length;i++)
		{
			var browser = browsers[i].name;
			var ver = browsers[i].ver;
			switch(browser)
			{
				case 'IE': 	
					index = nav.indexOf("MSIE");
					if( index != -1 )
					{
						var bVer = parseInt(nav.charAt(index+5));
						alert("Found: MSIE Ver="+bVer);
						if( ver == bVer ) return true;
					}
					break;
			}
		}
		return false;
	}, 
	
	
	
	save: function( name, obj, expireDays, path, domain )
	{
		var val = this.getJSONFromObj(obj);
		
		var cookies = this.prepareCookiesForSave(val);
		
		if( cookies.length > 1) //it means that we need more than one cookie to save the object. 
		{
			if( this.isBrowser([{name:"IE",ver:6}]) ) return "Error: Object exceed cookie limit";
		}
		
		for( var i=0;i<cookies.length;i++)
		{
			var cookie = 
				(i>0?("__"+i):"") + 
				name + 
				"=" +
				cookies[i];
			
			if( expireDays )
			{
				cookie += "; max-age=" + (expireDays*60*60*24);
			}
			if( path ) cookie += "; path="+path;
			if( domain )  cookie += "; domain="+domain;

			document.cookie = cookie;	
		}	
	}, 
	
	getJSONFromObj: function( obj )
	{
		var val = "";
		if( typeof(obj) == "string" ||
			typeof(obj) == "number" ||
			typeof(obj) == "boolean" )
		{
			val = ""+obj;
		}
		else
		{					
			val = this.getObjProperties(obj);
		}
		return val;		
	} ,
	
	
	setValue: function(obj,key,val,debug)
	{
		if(isNaN(parseFloat(key)) || parseInt(key) == parseFloat(key) )
		{
			if( val == undefined )
				return isNaN(parseFloat(key))?key:parseFloat(key);
			obj[key] = val;
		}
		else
		{
			if( val == undefined )
				return parseFloat(key);
			obj[parseInt(key)] = val;
		}
	},
	
	populateObj: function(cookie)
	{
		var obj = null;
		var key = "";
		var val = "";
		var objArray = new Array();
		var isKey = true;		
		
		for( var i=0;i<cookie.length;i++)
		{
			if(cookie.charAt(i) == "{" ) 
			{
				var obj1 = new Object();
				if( obj == null ) obj = obj1;
				else (objArray[objArray.length-1])[key] = obj1;
				objArray.push(obj1);
				isKey = true;
				key = "";
				val = "";
			}
			else if( cookie.charAt(i) == "[" )
			{
				var obj1 = new Array();
				if( obj == null ) obj = obj1;
				else (objArray[objArray.length-1])[key] = obj1;
				objArray.push(obj1);
				isKey = true;
				key = "";
				val = "";
			}
			else if( cookie.charAt(i) == ":" )
			{
				isKey = false;
			}	
			else if( cookie.charAt(i) == "," )
			{
				if( key != "" )
					this.setValue(objArray[objArray.length-1],key,decodeURIComponent(val),"144");
				key="";
				val="";
				isKey = true;
			}	
			else if( cookie.charAt(i) == "]" )
			{
				this.setValue(objArray[objArray.length-1],key,decodeURIComponent(val),"151");
				key="";
				val="";
				isKey = true;
				objArray.pop();
				
			}	
			else if( cookie.charAt(i) == "}" )
			{
				this.setValue(objArray[objArray.length-1],key,decodeURIComponent(val),"160");
				key="";
				val="";
				isKey = true;
				objArray.pop();
			}
			else if( isKey )
			{
				key += cookie.charAt(i);
			}
			else val += cookie.charAt(i);
		}
		if( obj == null && key != "" )
		{
			obj = this.setValue(obj,key,undefined,"174");
		}
		return obj;
	},
	

	remove: function(name)
	{
		var cookie = name + "=0";		
		cookie += "; max-age=0";
		document.cookie = cookie;
		//TODO: clear all cookie parts: __x<cookie name> created by long cookies.
	},
	
	load: function(name)
	{
		var obj = null;		
		var cookie = this.getCookieByName(name);
		if( cookie != "" )
		{
			for( var i=1;i<1000;i++)
			{
				var partName = "__"+i+name;
				var cookiePart = this.getCookieByName(partName);
				if( cookiePart == "" ) break;
				cookie += cookiePart;
			}
			obj = this.populateObj(cookie );
		}		
		return obj;
	},
	
	getCookieByName: function(name)
	{
		var allCookies = document.cookie;
		if( allCookies == "" ) return ""; 
		var cookies = allCookies.split(';');
		var cookie = null;
		for( var i=0; i< cookies.length;i++)
		{
			cookie = cookies[i];
			//some browsers put a space after the semicolon
			if( cookie.charAt(0) == " " ) cookie = cookie.substring(1);
			if( cookie.substring(0,name.length+1) == (name+"=")) break;
		}
		
		if( i >= cookies.length ) return "";
		
		return cookie.substring(name.length+1);		
	}
};