///<reference path="../TESCO.js" />
///<reference path="cookie.js" />
/*
	Example:
	
	var cache = new TESCO.system.Cache();
		cache.add("myId", {});
		cache.add("myOtherId", document.createElement("div"));
		
		document.body.appendChild(cache.get("myOtherId"));
		cache.removeItem("myOtherId");
*/

TESCO.system.Cache = (function() {

    //  constructor
    function _constructor() {
        /// <summary>storage mechanism for any type</summary>
        /// <returns>instance</returns>
        this.cache = {}    
        return this;
    }

    _constructor.prototype = {
        "NAME" : "TESCO.system.Cache",
        "setItem" : function(key, value) {
            this.cache[key] = value;
        },
        "removeItem" : function(key) {
            this.cache[key] = null;
        },
        "exists" : function(key) {
            return !!this.getItem(key);
        },
        "getItem" : function(key) {
            return this.cache[key];
        }
    }

    //  return _constructor as function pointer
    return _constructor;
})();

/*
	Example:
	
	TESCO.system.event.document.addEventListener("load",
        function() {
            var _ul2 = document.getElementById("ul2");
            var _cache = new TESCO.system.Cache.Session();
            
            function _set(display) {
                _ul2.style.display = display;
                _cache.setItem(_ul2.id, display);
            }
            
            function _toggle(display) {
                _set((display === "block") ? "none" : "block");
            } 
            _set(_cache.getItem(_ul2.id) || TESCO.system.DOM.node.getStyle(_ul2, "display")); 
            
            document.getElementById("li1").onclick = function() {
                _toggle(_ul2.style.display);
                return false;
            }
        }
    );
*/

TESCO.$("system.Cache").Session = (function() {

    var _mechanism = null;
    var _supported = true;
    var _registary = [];
    
    //	create cross browser cache support
    //#region    
    if (window.sessionStorage) {
        _mechanism = function() {
            return sessionStorage;
        }
   } /*@cc_on else if (true) {	//	create session object for <= IE7 
        var _bodyLoaded = false;
        var _inputs = [];
        function _append(input) {
			document.body.insertBefore(input, document.body.firstChild);
        }
        TESCO.system.event.document.addEventListener("beforeload",
            function() {	//	append any inputs which were created before the body
                _bodyLoaded = true;
                for (var i = 0, L = _inputs.length; i < L; i++) {
					_append(_inputs[i]);
                }
            }
        );
        function _userData() {
            var _input = document.createElement("input");
            _input.setAttribute("type", "hidden");
            _input.addBehavior("#default#userData");
            if (_bodyLoaded) {
				_append(_input);
            } else {	//	created before body has loaded
                _inputs.push(_input);
            }
            //  alias userData methods
            _input.setItem = function(key, value) {
                this.setAttribute(key, value);
                this.save("oXMLBranch");
            }
            _input.getItem = function(key) {
                this.load("oXMLBranch");
                return this.getAttribute(key);
            }
            _input.removeItem = function(key) {
                this.removeAttribute(key);
            }
            return _input;
        }
        _mechanism = function() {
            return new _userData();
        } 
    } @*/ else {
        var _cookie = new TESCO.system.Cookie("jsc", null, TESCO.sites.Configuration.application.domain.cookie || null);
        //  use TESCO.system.Cookie for browsers without sessionStorage where the value must be persisted
        _mechanism = function() {
            //  alias cookie methods
            _cookie.getItem = _cookie.getValueByName;
            _cookie.setItem = _cookie.setValueByName;
            _cookie.removeItem = _cookie.removeValueByName;
            return _cookie;
        }
        _supported = false;
    }
    //#endregion

    //  constructor
    function _constructor(useCookie) {
        /// <summary>session storage for strings</summary>
        /// <param name="useCookie">use a cookie if browser does not support userData or sessionStorage (optional)</param>
        /// <returns>instance</instance>
        _constructor.base.constructor.call(this); 
        this.useCookie = useCookie && !_supported;
        this.useBase = false;
		if (this.useCookie || _supported) {
            this.mechanism = _mechanism();
        } else {
            this.useBase = true;
        }
        return this;
    }
    _constructor.extend(TESCO.system.Cache);

    _constructor.prototype.NAME = "TESCO.system.Cache.Session";

    _constructor.prototype.setItem = function(key, value) {
		_registary.push(key);
        this.useBase ? _constructor.base.setItem.call(this, key, value) : this.mechanism.setItem(key, value);
    }

    _constructor.prototype.removeItem = function(key) {
		for (var i = 0, L = _registary.length; i < L; i++) {
			if (key === _registary[i]) {
				delete _registary[i];
				break;		
			}
		}
        this.useBase ? _constructor.base.removeItem.call(this, key) : this.mechanism.removeItem(key);
    }

    _constructor.prototype.getItem = function(key) {
        return this.useBase ? _constructor.base.getItem.call(this, key) : this.mechanism.getItem(key);
	}
	
	_constructor.prototype.clear = function() {
		for (var i = 0, L = _registary.length; i < L; i++) {
			this.useBase ? _constructor.base.removeItem.call(this, _registary[i]) : this.mechanism.removeItem(_registary[i]);
		}
    }
	
    //  return _constructor as pointer
    return _constructor;
})();

TESCO.$("system.Cache.Session").DOM = (function() {
    
    function _constructor() {
        _constructor.base.constructor.call(this); 
        return this;
    }
    _constructor.extend(TESCO.system.Cache.Session);
    
    _constructor.prototype.NAME = "TESCO.system.Cache.Session.DOM";

    _constructor.prototype.setNode = function(key, node) {
		//	store node in session object as string
        this.setItem(key, TESCO.system.serialization.serializeXHTMLToString(node));
    }

    _constructor.prototype.getNode = function(key) {
        //#region
        var _result = this.getItem(key);	//	retrieve XMLised string 
        if (_result) {
			//	serialise string to XMLDocument
            _result = TESCO.system.serialization.serializeStringToXML(_result);	
            //	serialise XMLDocument to native object
            _result = TESCO.system.serialization.deserialize(_result);
			//	get node from object
            _result = _result.fragment.content.nodeValue.firstChild;
        }
        return _result;
        //#endregion
    }
    
    return _constructor;
})();