// Refer to https://gist.github.com/remy/350433
try {
    // Test webstorage existence.
    if (!window.localStorage || !window.sessionStorage) {
    	throw "exception";
    }
    // Test webstorage accessibility - Needed for Safari private browsing.
    localStorage.setItem('storage_test', 1);
    localStorage.removeItem('storage_test');
} catch (e) {
    (function (window, document) {
        var Storage = function (type) {
            function createCookie(name, value, days) {
                var date, expires;

                if (days) {
                    date = new Date();
                    date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
                    expires = "; expires=" + date.toGMTString();
                } else {
                    expires = "";
                }
                document.cookie = name + "=" + value + expires + "; path=/";
            }

            function readCookie(name) {
                var nameEQ = name + "=",
                    ca = document.cookie.split(';'),
                    i, c;

                for (i = 0; i < ca.length; i++) {
                    c = ca[i];
                    while (c.charAt(0) === ' ') {
                        c = c.substring(1, c.length);
                    }

                    if (c.indexOf(nameEQ) === 0) {
                        return c.substring(nameEQ.length, c.length);
                    }
                }
                return null;
            }

            function getSessionName() {
                // If there is no name for this window, set one.
                // To ensure it's unquie use the current timestamp.
                if (!window.name) {
                    window.name = new Date().getTime();
                }
                return 'sessionStorage' + window.name;
            }
            
            function setData(data) {
                // Convert data into JSON and encode to accommodate for special characters.
                data = JSON.stringify(data);
                // Create cookie.
                if (type === 'session') {
                    createCookie(getSessionName(), data, 0);
                } else {
                    createCookie('localStorage', data, 0);
                }
            }

            function clearData() {
                if (type === 'session') {
                    createCookie(getSessionName(), '', 0);
                } else {
                    createCookie('localStorage', '', 0);
                }
            }

            function getData() {
                // Get cookie data.
                var data = type === 'session' ? readCookie(getSessionName()) : readCookie('localStorage');
                // If we have some data decode, parse and return it.
                return data ? JSON.parse(decodeURIComponent(data)) : {};
            }

            // Initialise if there's already data.
            var data = getData();

            return {
                length: 0,
                clear: function () {
                    data = {};
                    this.length = 0;
                    clearData();
                },
                getItem: function (key) {
                    return data[key] === undefined ? null : data[key];
                },
                key: function (i) {
                    // not perfect, but works
                    var ctr = 0;
                    for (var k in data) {
                        if (ctr == i) {
                        	return k;
                        } else {
                        	ctr++;
                        }
                    }
                    return null;
                },
                removeItem: function (key) {
                    delete data[key];
                    this.length--;
                    setData(data);
                },
                setItem: function (key, value) {
                    data[key] = value + ''; // forces the value to a string
                    this.length++;
                    setData(data);
                }
            };
        };

        // Replace window.localStorage and window.sessionStorage with out custom
        // implementation.
        var localStorage = new Storage('local');
        var sessionStorage = new Storage('session');
        window.localStorage = localStorage;
        window.sessionStorage = sessionStorage;
        // For Safari private browsing need to also set the proto value.
        window.localStorage.__proto__ = localStorage;
        window.sessionStorage.__proto__ = sessionStorage;
    })(window, document);
}