/**
 * @author firejune, jhlee
 * 
 * Depends:
 *   jquery.js
 *   jquery.json.js
 *   
**/
/* Local Storage Helper Class */
/*
 * $H(this.data).toJSON() : obj -> string
 * $jq.toJSON(this.data)  : obj -> string
 * JSON.stringify         : obj -> string 
 * 
 * this.data.evalJSON()    : string -> obj 
 * $jq.evalJSON(this.data) : string -> obj
 * JSON.parse              : string -> obj
 */
var Storage = function() {
  return {
    init: function(name, options){
      /*
      this.options = Object.extend({
          clearable: true, // automatically clear data if an error occurred
          delay: 2000, // save data to localStorage after the allotted time
          maximum: 5 // the maximum size in megabytes
        }, options);
      */
      options           = options || {};
      options.clearable = options.clearable || true;// automatically clear data if an error occurred
      options.delay     = options.delay || 2000;// save data to localStorage after the allotted time
      options.maximum   = options.maximum || 5;// the maximum size in megabytes
      this.options = options;

      if (typeof localStorage == "undefined" && typeof globalStorage != "undefined") 
        window.localStorage = globalStorage[location.hostname];
      this.localStorage = window.localStorage;
      // undefined localStorage if it doesn't already exist
      
      if (!this.localStorage)
        this.localStorage = {
          getItem: function(name){
            this.data = window.name ? $jq.evalJSON(window.name) : {};
            return $jq.toJSON(this.data[name] || (this.data[name] = {}));
          },
          setItem: function(name, data){
            this.data[name] = $jq.evalJSON(data);
            window.name = $jq.toJSON(this.data);
          },
          removeItem: function(name){
            delete this.data[name];
            window.name = $jq.toJSON(this.data);
          }
        };
        
      this.name = name || 'unnamed';
      this.data = this.get();
    },    
    // get item from localStorage
    get: function(){
      try {
        return $jq.evalJSON((this.localStorage.getItem(this.name) || '{}').toString());
      }
      catch (e) {
        this.options.clearable && this.set({});
      }
    },
    // set item to localStorage
    set: function(data){
      if (data) 
        this.data = data;
      this.timer && clearTimeout(this.timer);
      var self = this;
      this.timer = setTimeout(function(){
        if (self.size(true) > self.options.maximum * 1048576) 
          return;
        try {
          self.localStorage.setItem(self.name, $jq.toJSON(self.data));
        }
        catch (e) {
          self.options.clearable && self.set({});
        }
      }, this.options.delay)
    },
    // remove item
    remove: function(name){
      this.localStorage.removeItem(name || this.name);
    },
    // remove all items
    clear: function(){
      if (!this.localStorage.length) 
        window.name = '{}';
      else
        for (i = 0; i < this.localStorage.length; i++) 
          this.remove(this.localStorage.key(i));
    },
    // size of localStorage
    size: function(bytes){
      var data = $jq.toJSON(this.data).length;
    
      return bytes ? data : data > 1024 ? (function(){
        data = (data / 1024).round().toString();
        var reg = /(^[+-]?\d+)(\d{3})/;
        while (reg.test(data))
          data = data.replace(reg, '$1' + ',' + '$2');
        return data + 'kb';
      })() : data + 'bytes';
    }
  }
}

