(function(){
   var Storage = function( engine ){

     return {
       save : function(vals){
	 if(arguments.length==2&&typeof arguments[0]=='string'){
	   this.engine.save(arguments[0],arguments[1]);
	 }
	 else {
	   for(var i in vals){
	     this.engine.save(i,vals[i]);
	   }
	 }

       },
       load : function(vals){
	 return this.engine.load(vals);
       },
       del : function(vals){
	 return this.engine.del(vals);
       },
       init : function(){
	 this.engine.init();
       }
     };
   };

   var interfaces = {
     html5 : {
       save : function(key, val){
	 return localStorage[key] = val;
       },
       load : function(key){
	 return localStorage[key];
       },
       del : function(key){
	 return delete localStorage[key];
       },
       init : function(){

       }
     },
     globalStorage : {
       host : window.location.host,
       save : function(key, val){
	 return globalStorage[this.host][key] = val;
       },
       load : function(key){
	 try {
	   return globalStorage[this.host][key].value;
	 } catch(e){
	   return null;
	 }
       },
       del : function(key){
	 return delete globalStorage[this.host][key];
       },
       init : function(){

       }
     },
     ie : {
       host : window.location.host,
       init : function(){
	 if(!this.sElement){
	   var d=document.createElement('div');
	   d.id='iestorage';
	   d.style.display='none';
	   d.addBehavior('#default#userdata');
	   document.body.appendChild(d);
	   this.sElement = d;
	 }
	 this.sElement.load(this.host);
       },
	   
       save : function(key, val){
			try {
				this.init();
				this.sElement.setAttribute( key, val );
				return this.sElement.save(this.host);
			} catch(e){ return null; }
       },
       load : function(key){
			try {
				this.init();
				return this.sElement.getAttribute( key );
			} catch(e){ return null; }
       },
       del : function(key){
	 this.init();
	 return this.save(key, null);
       }
     },

     cookie : {
       init : function(){

       },
       save : function(k, v ){
	   var date = new Date();
	   date.setTime(date.getTime()+10368000000);/* 120 days to expire */
	   var expires = "; expires="+date.toGMTString();
	   document.cookie = k+"="+v+expires+"; path=/";
       },
       load : function(k){
	   k += "=";
	   var ca = document.cookie.split(';');
	   for(var i=0,j=ca.length;i<j;i++) {
	     var c = ca[i];
	     while (c.charAt(0)==' ') c = c.substring(1,c.length);
	     if (c.indexOf(k) == 0) return c.substring(k.length,c.length);
	   }
	   return null;
       },
       del :function(k){
	 return this.save(k, '');
       }
     }
   };

   var storage = new Storage();
   storage.engine = (function(){
		       if(typeof window.localStorage !='undefined'){
			 return interfaces['html5'];
		       }
		       else if(typeof window.globalStorage != 'undefined'){
			 return interfaces['globalStorage'];
		       }
		       else if(typeof document.documentElement.addBehavior != 'undefined'){
			 return interfaces['ie'];
		       }
		       else return interfaces['cookie'];
     }());

   if(jQuery){
     jQuery.storage = storage;
   }
   else {
     window.storage = storage;
   }

}());
