/*global define,encodeURIComponent*/
/*jslint white:true,browser:true*/
/* based on https://developer.mozilla.org/en-US/docs/Web/API/document.cookie?redirectlocale=en-US&redirectslug=DOM%2Fdocument.cookie */
define([], function () {
    'use strict';
    var Cookie = Object.create({}, {
        init: {
            value: function () {
                this.cookies = [];
                this.importCookies();
                return this;
            }
        },
        importCookies: {
            value: function () {
                this.cookies = this.readCookies();
            }
        },
        readCookies: {
            value: function () {
                var cookieString = document.cookie;
                if (cookieString) {
                    return cookieString.split(';')
                        .map(function (cookie) {
                            var pieces = cookie.split('='),
                                name = pieces[0].trim(' '),
                                value = pieces[1].trim(' ');
                            return {
                                name: name,
                                value: decodeURIComponent(value)
                            };
                        });
                }
                return [];
            }
        },
        findCookie: {
            value: function (key) {
                return this.cookies.filter(function (cookie) {
                    if (cookie.name === key) {
                        return true;
                    }
                });
            }
        },
        getItem: {
            value: function (key) {
                if (!key) {
                    return null;
                }
                this.importCookies();
                var cookie = this.findCookie(key), value;
                if (cookie.length > 1) {
                    throw new Error('Too many cookies returned, expected 1');
                }
                if (cookie.length === 0) {
                    return;
                }
                return cookie[0].value;
            }
        },
        getItems: {
            value: function (key) {
                if (!key) {
                    return null;
                }
                this.importCookies();
                return this.findCookie(key).map(function (cookie) {
                    return cookie.value;
                });
            }
        },
        setItem: {
            value: function (sKey, sValue, vEnd, sPath, sDomain, bSecure, bNoEncode) {
                if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) {
                    return false;
                }
                var sExpires, maxAge;
                if (vEnd) {
                    switch (vEnd.constructor) {
                        case Number:
                            if (vEnd === Infinity) {
                                sExpires = 'Fri, 31 Dec 9999 23:59:59 GMT';
                            } else {
                                maxAge = vEnd;
                            }
                            break;
                        case String:
                            sExpires = vEnd;
                            break;
                        case Date:
                            sExpires = vEnd.toUTCString();
                            break;
                    }
                }
                var newCookie = {
                    name: sKey,
                    value: sValue,
                    expires: sExpires,
                    'max-age': maxAge,
                    domain: sDomain,
                    path: sPath,
                    secure: bSecure,
                    noEncode: bNoEncode
                };
                this.cookies.push(newCookie);
                this.setCookie(newCookie);
                return true;
            }
        },
        setCookie: {
            value: function (cookie) {
                var cookieProps, propString,
                    cookieString;
                cookieProps = ['domain', 'path', 'secure', 'expires', 'max-age']
                    .map(function (key) {
                        if (cookie[key]) {
                            return {
                                key: key,
                                value: cookie[key]
                            };
                        }
                    })
                    .filter(function (prop) {
                        if (prop) {
                            return true;
                        }
                    });

                if (cookie.noEncode) {
                    // For compatability with services which do not decode cookies yet create cookies
                    // save for not encoding. Aka - Globus.
                    propString = cookieProps.map(function (prop) {
                        return [prop.key, prop.value].join('=');
                    }).join(';');
                    cookieString = [cookie.key, [cookie.value, propString].join(';')].join('=');
                } else {
                    propString = cookieProps.map(function (prop) {
                        return [prop.key, prop.value].join('=');
                    }).join(';');
                    cookieString = [encodeURIComponent(cookie.name), [encodeURIComponent(cookie.value), propString].join(';')].join('=');                    
                }
                document.cookie = cookieString;
                this.importCookies();
            }
        },
        removeItem: {
            value: function (sKey, sPath, sDomain) {
                this.setCookie({
                    name: sKey,
                    value: '*',
                    domain: sDomain,
                    path: sPath,
                    expires: '01 Jan 1970 00:00:00 GMT'
                });
                this.importCookies();
            }
        },
        hasItem: {
            value: function (key) {
                if (this.cookies[key]) {
                    return true;
                }
                return false;
            }
        },
        keys: {
            value: function () {
                return Object.keys(this.cookies);
            }
        }
    });
    return Cookie.init();
});
@@ -318,32 +318,39 @@
 alue: function (
+options
 ) %7B%0A            
@@ -362,58 +362,37 @@
 his.
-cookies = %5B%5D;%0A                this.importCookies()
+doc = options.doc %7C%7C document
 ;%0A  
@@ -505,140 +505,8 @@
 ) %7B%0A
-                this.cookies = this.readCookies();%0A            %7D%0A        %7D,%0A        readCookies: %7B%0A            value: function () %7B%0A
     
@@ -536,24 +536,24 @@
 tring = 
-document
+this.doc
 .cookie;
@@ -1137,32 +1137,157 @@
    %7D%0A        %7D,%0A
+        getCookies: %7B%0A            value: function () %7B%0A                return this.importCookies();%0A            %7D%0A        %7D,%0A
         findCook
@@ -1344,28 +1344,75 @@
         
+var cookies = this.importCookies();%0A                
 return 
-this.
 cookies.
@@ -1714,33 +1714,32 @@
                %7D
-%0A
                 
@@ -1738,37 +1738,16 @@
         
-this.importCookies();
 %0A       
@@ -2227,46 +2227,8 @@
   %7D%0A
-                this.importCookies();%0A
     
@@ -3687,54 +3687,8 @@
  %7D;%0A
-                this.cookies.push(newCookie);%0A
     
@@ -5316,24 +5316,24 @@
         
-document
+this.doc
 .cookie 
@@ -5352,46 +5352,8 @@
 ng;%0A
-                this.importCookies();%0A
     
@@ -5695,46 +5695,8 @@
 %7D);%0A
-                this.importCookies();%0A
     
@@ -5791,17 +5791,64 @@
     
-if (this.
+var cookies = this.importCookies();%0A                if (
 cook
@@ -6006,32 +6006,84 @@
 : function () %7B%0A
+                var cookies = this.importCookies();%0A
                 
@@ -6101,21 +6101,16 @@
 ct.keys(
-this.
 cookies)
@@ -6164,15 +6164,8 @@
 okie
-.init()
 ;%0A%7D)

improve cookie to be stateless, state is in the browser after all.