/**
*davidflanagan.com/javascript5
*Example 19-2 from JavaScript: The Definitive Guide, Fifth Edition
*Buy The Book
*This example is posted here for the convenience of my readers.
*Tip the Author
*Found a helpful example, but don't own the book?
*Advertising
*Table of Examples
*/

/**
 * This is the cookieclass() constructor function.
 *
 * This constructor looks for a cookieclass with the specified name for the
 * current document.  If one exists, it parses its value into a set of
 * name/value pairs and stores those values as properties of the newly created
 * object.
 *
 * To store new data in the cookieclass, simply set properties of the cookieclass
 * object.  Avoid properties named "store" and "remove" since these are 
 * reserved as method names.
 * 
 * To save cookieclass data in the web browser's local store, call store().
 * To remove cookieclass data from the browser's store, call remove().
 *
 * The static method cookieclass.enabled() returns true if cookieclasss are
 * enabled and returns false otherwise.
 */
function cookieclass(name) {
    this.$name = name;  // Remember the name of this cookieclass

    // First, get a list of all cookieclasss that pertain to this document
    // We do this by reading the magic Document.cookieclass property
    // If there are no cookieclasss, we don't have anything to do 
    var allcookieclasss = document.cookie;

    if (allcookieclasss == "") return -1;

    // Break the string of all cookieclasss into individual cookieclass strings
    // Then loop through the cookieclass strings, looking for our name
    var cookieclasss = allcookieclasss.split(';');
    var cookieclass = null;
    for(var i = 0; i < cookieclasss.length; i++) {
        // Does this cookieclass string begin with the name we want?
        if (cookieclasss[i].substring(0, name.length+1) == (name + "=")) {
            cookieclass = cookieclasss[i];
            break;
        }
    }

    // If we didn't find a matching cookieclass, quit now
    if (cookieclass == null) return;

    // The cookieclass value is the part after the equals sign
    var cookieclassval = cookieclass.substring(name.length+1);

    // Now that we've extracted the value of the named cookieclass, we
    // must break that value down into individual state variable 
    // names and values. The name/value pairs are separated from each
    // other by ampersands, and the individual names and values are
    // separated from each other by colons. We use the split() method
    // to parse everything.
    var a = cookieclassval.split('&'); // Break it into an array of name/value pairs
    for(var i=0; i < a.length; i++)  // Break each pair into an array
        a[i] = a[i].split(':');

    // Now that we've parsed the cookieclass value, set all the names and values
    // as properties of this cookieclass object. Note that we decode
    // the property value because the store() method encodes it
    for(var i = 0; i < a.length; i++) {
        this[a[i][0]] = decodeURIComponent(a[i][1]);
    }
}

/**
 * This function is the store() method of the cookieclass object.
 *
 * Arguments:
 *
 *   daysToLive: the lifetime of the cookieclass, in days. If you set this
 *     to zero, the cookieclass will be deleted.  If you set it to null, or 
 *     omit this argument, the cookieclass will be a session cookieclass and will
 *     not be retained when the browser exits.  This argument is used to
 *     set the max-age attribute of the cookieclass.
 *   path: the value of the path attribute of the cookieclass
 *   domain: the value of the domain attribute of the cookieclass
 *   secure: if true, the secure attribute of the cookieclass will be set
 */
cookieclass.prototype.store = function(daysToLive, path, domain, secure) {
    // First, loop through the properties of the cookieclass object and
    // put together the value of the cookieclass. Since cookieclasss use the
    // equals sign and semicolons as separators, we'll use colons
    // and ampersands for the individual state variables we store 
    // within a single cookieclass value. Note that we encode the value
    // of each property in case it contains punctuation or other
    // illegal characters.
    var cookieclassval = "";
    for(var prop in this) {
        // Ignore properties with names that begin with '$' and also methods
        if ((prop.charAt(0) == '$') || ((typeof this[prop]) == 'function')) 
            continue;
        if (cookieclassval != "") cookieclassval += '&';
        cookieclassval += prop + ':' + encodeURIComponent(this[prop]);
    }

    // Now that we have the value of the cookieclass, put together the 
    // complete cookieclass string, which includes the name and the various
    // attributes specified when the cookieclass object was created
    var cookieclass = this.$name + '=' + cookieclassval;
    //cookieclass += "; max-age=" + (daysToLive*24*60*60);
    
//    if (daysToLive || daysToLive == 0) { 
//        cookieclass += "; max-age=" + (daysToLive*24*60*60);
//    }

    if (path) cookieclass += "; path=" + path;
    if (domain) cookieclass += "; domain=" + domain;
    if (secure) cookieclass += "; secure";

    // Now store the cookieclass by setting the magic Document.cookieclass property
    document.cookie = cookieclass;
}

/**
 * This function is the remove() method of the cookieclass object; it deletes the
 * properties of the object and removes the cookieclass from the browser's 
 * local store.
 * 
 * The arguments to this function are all optional, but to remove a cookieclass
 * you must pass the same values you passed to store().
 */
cookieclass.prototype.remove = function(path, domain, secure) {
    // Delete the properties of the cookieclass
    for(var prop in this) {
        if (prop.charAt(0) != '$' && typeof this[prop] != 'function') 
            delete this[prop];
    }

    // Then, store the cookieclass with a lifetime of 0
    this.store(0, path, domain, secure);
}

/**
 * This static method attempts to determine whether cookieclasss are enabled.
 * It returns true if they appear to be enabled and false otherwise.
 * A return value of true does not guarantee that cookieclasss actually persist.
 * Nonpersistent session cookieclasss may still work even if this method 
 * returns false.
 */
cookieclass.enabled = function() {
    // Use navigator.cookieclassEnabled if this browser defines it
    if (navigator.cookieclassEnabled != undefined) return navigator.cookieclassEnabled;

    // If we've already cached a value, use that value
    if (cookieclass.enabled.cache != undefined) return cookieclass.enabled.cache;

    // Otherwise, create a test cookieclass with a lifetime
    document.cookie = "testcookieclass=test; max-age=10000";  // Set cookieclass

    // Now see if that cookieclass was saved
    var cookieclasss = document.cookie;
    if (cookieclasss.indexOf("testcookieclass=test") == -1) {
        // The cookieclass was not saved
        return cookieclass.enabled.cache = false;
    }
    else {
        // cookieclass was saved, so we've got to delete it before returning
        document.cookie = "testcookieclass=test; max-age=0";  // Delete cookieclass
        return cookieclass.enabled.cache = true;
    }
}



