/// <reference path="../references.js" />

rwthapp.Storage = function (prefix) {
    /// <summary>Initialises a new Storage instance with a prefixed namespace.</summary>
    /// <param name="prefix" type="String">Prefix to use for namespace, values will be stored as 'rwthapp.<prefix>.<key>'.</param>

    if (typeof prefix !== "string" || prefix === "") {
        prefix = "general";
    }

    this.getPrefix = (function () {
        var _prefix = prefix;
        return function () {
            return _prefix;
        };
    })();
};

rwthapp.Storage.prototype.setItem = function (key, value) {
    /// <summary>Stores an item in storage.</summary>
    /// <param name="key" type="String">Key of entry to store.</param>
    /// <param name="value">Value to be stored, has to be serializable.</param>

    localStorage.setItem(this.getCompleteKey(key), JSON.stringify(value));
};

rwthapp.Storage.prototype.getItem = function (key, defaultValue) {
    /// <summary>Retrieves an item from storage.</summary>
    /// <param name="key" type="String">Key of entry to retrieve.</param>
    /// <param name="defaultValue">If no entry is found, this value is returned.</param>
    /// <return>Entry for specified key</returns>

    var retValue = localStorage.getItem(this.getCompleteKey(key));
    if(retValue === null) {
        return defaultValue !== undefined ? defaultValue : null;
    } else {
        return JSON.parse(retValue);
    }
};

rwthapp.Storage.prototype.removeItem = function (key) {
    /// <summary>Removes an item from the storage.</summary>
    /// <param name="key" type="String">Key of entry to remove.</param>

    localStorage.removeItem(this.getCompleteKey(key));
};

rwthapp.Storage.prototype.clear = function () {
    /// <summary>Removes all entries of the storage. WARNING: Entries of storage instances with the same prefix are removed as well.</summary>

    var keyPrefix = this.getCompleteKey("");
    var prefixLength = keyPrefix.length;
    for (var i = localStorage.length - 1; i >= 0; i--) {
        var keyName = localStorage.key(i);
        if (keyName.substr(0, prefixLength) === keyPrefix) {
            localStorage.removeItem(keyName);
        }
    }
};

rwthapp.Storage.prototype.getKeysForCategory = function (category) {

    var result = [];

    $.each(localStorage, function (index, value) {

        if (index && index.indexOf("rwthapp." + category) >= 0) {

            result.push(index.substr(index.indexOf(category + ".") + (category + ".").length, index.length));
        }
    });

    return result;
};

rwthapp.Storage.prototype.getCompleteKey = function (key) {
    return "rwthapp." + this.getPrefix() + "." + key;
};

rwthapp.Storage.prototype.addAttribute = function (name) {
    /// <summary>Adds setter and getter methods to the instance.</summary>
    /// <param name="name" type="String">Name of the attribute.</param>

    var nameCapitalised = name.charAt(0).toUpperCase() + name.slice(1);

    // Item should not be used 
    if (nameCapitalised === 'Item') {
        return;
    }

    var setterName = 'set' + nameCapitalised;
    var getterName = 'get' + nameCapitalised;
    var removerName = 'remove' + nameCapitalised;

    this[setterName] = function (value) {
        this.setItem(name, value);
    };

    this[getterName] = function (defaultValue) {
        return this.getItem(name, defaultValue);
    };

    this[removerName] = function () {
        this.removeItem(name);
    };
};

rwthapp.Storage.prototype.addAttributes = function (nameArray) {
    /// <summary>Adds setter and getter methods to the instance.</summary>
    /// <param name="name" type="Array">Array containing the names of the attributes.</param>

    for (var i = 0; i < nameArray.length; i++) {
        this.addAttribute(nameArray[i]);
    }
};

// Initialize general purpose storage instance
rwthapp.localStorage = new rwthapp.Storage();