/**
The implementation of client side component of the cookie handler frame work.
The framework provides a wrapper around the cookie which can be used for getting
and setting multiple key value pairs in a single cookie

Methods
1.       getCookieWrapper(cookie_name) 

This method returns a wrapper object for the cookie name specified.If no cookie is there ,
it will create an empty cookie.The properties can be get or set using the dot operator. 
The wrapper object includes a built in object 'options' with the following properties
a.expires, 
b.path, 
c.domain, 
d.secure {These are the options used for creating a new cookie} 
e.empty { empty = true if the wrapper object is empty, empty= false if wrapper object is not empty}


 
2.    commitCookieWrapperChanges(wrapperObject) 

This methods write the new/changed value of the cookie to the browser i.e. it commits the
value of the wrapper object.

3. getStringValueOfCookieWrapper(wrapperObject) 

Returns a  string notation of the wrapperObject.
4.deleteCookieWrapper(wrapperObject)
This method deletes the wrapper object  sets it to null and deletes 
 the  cookie associated with it.
 
Usage: <example>
1 .var carObject = getCookieWrapper("mycar"); // Write/commit example
carObject.model="benz";
carObject.color="white";
carObject.year=2009;
carObject['license_'+userId]='2D6-0F8-DFR';
carObject.options.expires=7;//7 days for expiry
commitCookieWrapperChanges(carObject);
 
2. var emailObject = getCookieWrapper("email"); //read example
var username = emailObject.userName 

@ author Infosys
*/


/*
 The  parse routine below is responsible for conversion to the string to object conversion
  and vice versa 
  */
//IMPORTANT : Please do not edit the code between the tags 'Start of parse routine' and 'End of parse routine'

// Start of parse routine ////

if(!this.JSON){JSON={};}
(function(){function f(n){return n<10?'0'+n:n;}
if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return this.getUTCFullYear()+'-'+
f(this.getUTCMonth()+1)+'-'+
f(this.getUTCDate())+'T'+
f(this.getUTCHours())+':'+
f(this.getUTCMinutes())+':'+
f(this.getUTCSeconds())+'Z';};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');};}}());

 // End of parse routine ////

function getCookieforJSON(c_name)
{
if (document.cookie.length>0)
  {
  c_start=document.cookie.indexOf(c_name + "=");
  if (c_start!=-1)
    {
    c_start=c_start + c_name.length+1;
    c_end=document.cookie.indexOf(";",c_start);
    if (c_end==-1) c_end=document.cookie.length;
    return unescape(document.cookie.substring(c_start,c_end));
    }
  }
return "";
}

/*
This method returns a wrapper object for the cookie name specified.If no cookie is there ,
it will create an empty cookie.The properties can be get or set using the dot operator. 
The wrapper object includes a built in object 'options'
*/
function getCookieWrapper(cookie_name)
{
   
   var cookieValue = getCookieforJSON(cookie_name);
    var wrapperObject = null;
    if(cookieValue == null || cookieValue == undefined || cookieValue=="" || cookieValue =="null" ){
        wrapperObject = JSON.parse('{}');
    }else{
        try{
        wrapperObject =JSON.parse(cookieValue);
        }catch(error){
            wrapperObject =JSON.parse('{}'); 
    }
 
    }
 
    wrapperObject.options =JSON.parse('{}');
    wrapperObject.options.expires=0;
    wrapperObject.options.path=null;
     wrapperObject.options.domain=null;
     wrapperObject.options.secure=false;
     wrapperObject.options.name=cookie_name;
     if(cookieValue== null || cookieValue=="" || cookieValue=="null"){
         
       wrapperObject.options.empty=true;
    }else{
        
        wrapperObject.options.empty=false;
    }
     return wrapperObject;
    
}

/*
Returns a  string notation of the wrapperObject.
*/
function getStringValueOfCookieWrapper(wrapperObject){
    if(wrapperObject == null){
        return "";
    }else{
        try {
        return JSON.stringify(wrapperObject);
        }catch(error){
             return "";
    }
    
}

}

/*
This methods write the new/changed value of the cookie to the browser i.e. it commits the
value of the wrapper object.
*/
function commitCookieWrapperChanges(wrapperObject)
{
    var cookieOptions=null;
    var cookieOptionsforUpdate=null;
    
    if(wrapperObject.options.expires!=0 ||
        wrapperObject.options.path!=null ||
        wrapperObject.options.domain != null ||
        wrapperObject.options.secure!=false
){
        cookieOptions=wrapperObject.options;
            
    }
    cookieOptionsforUpdate=wrapperObject.options;
    var cookieName = wrapperObject.options.name;
     var cookieValue ="";
    delete wrapperObject.options;
    try{
        cookieValue = JSON.stringify(wrapperObject);
    }catch(error){
        cookieValue =null;
    }
    
    if(cookieOptions == null){
        SetCookieforJSON(cookieName,cookieValue);
        
    }else{
        SetCookieforJSON(cookieName,cookieValue,cookieOptions.expires,
        cookieOptions.path,cookieOptions.domain,cookieOptions.secure);
        
    }
    if( cookieOptionsforUpdate!= null){
        wrapperObject.options =  cookieOptionsforUpdate;
        if(cookieValue== null || cookieValue==""|| cookieValue=="null"){
            
            wrapperObject.options.empty=true;
        }else{
            
            wrapperObject.options.empty=false;
        }
        
    }
   
    
}
/*
This method deletes the wrapper object  sets it to null and deletes 
 the  cookie associated with it.
 */
function deleteCookieWrapper(wrapperObject)
{
    //var startTime =(new Date()).getMilliseconds() ;
    if(wrapperObject != null && wrapperObject != undefined ){
        var cookieOptions=null;
        var cookieName = wrapperObject.options.name;
        if(wrapperObject.options.expires!=0 ||
            wrapperObject.options.path!=null ||
            wrapperObject.options.domain != null ||
            wrapperObject.options.secure!=false
    ){
            cookieOptions=wrapperObject.options;
      
        }
        if(cookieOptions == null){
            SetCookieforJSON(cookieName,null,0);
            
        }else{
            SetCookieforJSON(cookieName,null,0,
            cookieOptions.path,cookieOptions.domain,cookieOptions.secure);
            
        }
        try{
        	delete wrapperObject;
         } catch(error){
         }
        wrapperObject = null; 
      //  alert(wrapperObject);
       
    }
     // var endTime =(new Date()).getMilliseconds() ;
   //  alert("Time for deleteCookieWrapper for"+cookieName+" (ms) = "+(endTime-startTime));
     
}
    function SetCookieforJSON( name, value, expires, path, domain, secure )
    {
        // set time, it's in milliseconds
        var today = new Date();
        today.setTime( today.getTime() );
        
        /*
		if the expires variable is set, make the correct
		expires time, the current script below will set
		it for x number of days, to make it for hours,
		delete * 24, for minutes, delete * 60 * 24
         */
        if ( expires )
        {
            expires = expires * 1000 * 60 * 60 * 24;
        }
        var expires_date = new Date( today.getTime() + (expires) );
        
        document.cookie = name + "=" +escape( value ) +
            ( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) +
            ( ( path ) ? ";path=" + path : "" ) +
            ( ( domain ) ? ";domain=" + domain : "" ) +
            ( ( secure ) ? ";secure" : "" );
    }
    
   