///<reference path="TESCO.js" />
///<reference path="exception.js" />
/*
	Example:
	
	var greeting = new TESCO.system.Cookie("myCookie");
		greeting.setValueByName("message", "hi");
		
	var message = greeting.getValueByName("message");
		greeting.expire();
*/

TESCO.system.Cookie = (function() {

    //  private instance
    function _set(value) {  //	creates the cookie if it doesn't exist and sets the value
        document.cookie = this.name + "=" + value +
            ((this.expires) ? "; expires=" + this.expires : "") +
            ("; path=" + this.path) +
            ((this.domain) ? "; domain=" + this.domain : "") +
            ((this.secure) ? "; secure" : "")
    }
    
    function _get() {
        //	return null or the cookie's value
        var _results = document.cookie.match('(^|;) ?' + this.name + '=([^;]+)(;|$)');
        return _results ? _results[2] : null;
    }

    //  private static
    function _getNameValuePair(name, allValues) {
        var _pair = null;
        if (allValues) {
            var _pairs = allValues.split("&");
            var _nv;
            for (var i = 0, L = _pairs.length; i < L; i++) {
                var _nv = _pairs[i].split("=");
                if (_nv[0] === name) {
                    _pair = _nv;
                    break;
                }
            }
        }
        return _pair;
    }

    function _replaceValueByName(name, newValue, allValues) {
        var _pair = _getNameValuePair(name, allValues);
        if (_pair) {    //  name value pair exists, replace
            var _oldValue = _pair[0] + "=" + _pair[1];
            if (allValues.indexOf(_oldValue + "&") != -1) {
                _oldValue += "&";
            }
            allValues = allValues.replace(_oldValue, newValue);
        }
        return allValues;
    }

    function _constructor(name, expires, domain) {  //  constructor
        /// <summary>this function returns a cookie with a name and an expiry date</summary>
        /// <param name="name">cookie's name</param>
        /// <param name="expires">Optional. Expiration date of the cookie in GMT.</param>
        /// <returns>instance</returns>
        this.name = name;
        this.expires = expires ? expires.toGMTString() : null;
        this.path = "/";
        this.domain = domain || null;
        this.secure = false;
        return this;
    }

    //	public methods
    _constructor.prototype = {
        "NAME": "TESCO.system.Cookie",
        "expire": function() { //	kill it
            if (_get.call(this)) {
                this.expires = "Thu, 01-Jan-70 00:00:01 GMT";
                _set.call(this);
            }
        },
        "removeValueByName": function(name) {
            var _allValues = _get.call(this);
            if (_allValues) {
                _replaceValueByName(name, "", _allValues);
            }
        },
        "getValueByName": function(name) {
            var _pair = _getNameValuePair(name, _get.call(this));
            return _pair ? unescape(_pair[1]) : null;
        },
        "setValueByName": function(name, value) {
            var _allValues = _get.call(this);
            var _newValue = escape(name) + "=" + escape(value);
            if (_allValues) {   //  cookie exists
                _allValues = _replaceValueByName(name, "", _allValues);
                if (_allValues.length > 0) {
                    _newValue = _newValue + "&" + _allValues;
                }
            }
            _set.call(this, _newValue);
        },
        "getAllValues": function() {
            return _get.call(this);
        },
        "setAllValues": function(values) {   //	set all the values
            _set.call(this, values);
        }
    }

    //  return _constructor as function pointer
    return _constructor;
})();
