
// ===========================================================================
// function processCookie(
//      cookieName  ,
//      func        ,
//      name        ,
//      value       ,
//      days
//      )
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Do stuff with cookies.  In particular, support "stacked cookies" (=
// multiple "name=value" pairs in the one cookies proper).
//
// NOTE!
// -----
// 1.   To create/use use a stacked cookie; make 'cookieName' and 'name'
//      different.
//
// 2.   The operations available are:-
//      o   Kill    (delete),
//      o   Clear   (non-stacked - delete, stacked - remove name/value pair),
//      o   Set     (add/update the name/value pair creating cookie if needs
//                  be),
//      o   Read    (return the value, if present, of the provided named
//                  element)
//
//      cookieName  [required]  -   The name of the cookie.
//
//      func        [required]  -   What processing on the cookie is required,
//                                  i.e. kill (delete), clear (non-stacked -
//                                  delete, stacked - remove name/value pair),
//                                  set (add/update the name/value pair creating
//                                  cookie if needs be), read (return the value,
//                                  if present, of the provided named element)
//
//      name        [required]  -   Identifies the name/value pair to be
//                                  operated on. If the same as cookieName
//                                  indicates a non-stacked cookie.
//
//      value       [optional]  -   Supplies the data the be associated with the
//                                  identified named cookie element.
//
//      days        [optional]  -   In cases where a cookie is created or
//                                  updated, this sets the period of validity.
//                                  Defaults to 365 days.
//
// See: "Javascript/PHP Cookies"
//      kos Haks
//      http://cass-hacks.com/articles/discussion/js_php_cookies/
//
// RETURNS
//      o   If func == 'read'
//          - - - - - - - - -
//          cookie value = Cookie read OK!
//          null         = Read ERROR (NO error message issued)!
//      o   Otherwise
//          - - - - -
//          true  = Cookie killed, cleared or set OK!
//          false = ERROR (NO error message issued)!
// ===========================================================================

function processCookie(
    cookieName  ,
    func        ,
    name
    ) {

    // -----------------------------------------------------------------------
    // The way that this function is defined is that value and days are
    // OPTIONAL parameters.  They're not required if 'func' = 'read', for
    // example.
    //
    // According to Douglas Crockford:-
    //
    //      "When calling a function, it is not required that you pass a fixed
    //      number of parameters.  Excess parameters are ignored.  Missing
    //      parameters are given the value undefined.  This makes it easy to
    //      write functions that deal with optional arguments.
    //
    //      A function has access to an arguments array.  It contains all of
    //      the parameters that were actually sent by the caller.  It makes it
    //      easy to deal with functions taking a variable number of arguments.
    //      For example,
    //
    //          //  Take any number of parameters and return the sum...
    //          function sum() {
    //              var total = 0;
    //              for (var i = 0; i < arguments.length; ++i) {
    //                  total += arguments[i];
    //                  }
    //              return total;
    //              }"
    //
    //          "A Survey of the JavaScript Programming Language"
    //          Douglas Crockford
    //          http://javascript.crockford.com/survey.html
    //
    // However, Firefox will generate "missing formal parameter" errors...
    // -----------------------------------------------------------------------

    // -----------------------------------------------------------------------
    // Local variables...
    // -----------------------------------------------------------------------

    var software_bug__detected_in =
        "\n\nThis is almost certainly a SOFTWARE BUG!  Please COMPLAIN!" +
        "\n\nThis error was detected during cookie processing."

    // -----------------------------------------------------------------------

    var success_return = false ;
    var failure_return = true  ;

    // -----------------------------------------------------------------------
    // Default the optional arguments...
    // -----------------------------------------------------------------------

    var value = '' ;
    var days  = 0  ;

    // -----------------------------------------------------------------------

    if ( arguments.length == 4 ) {
        value = arguments[3] ;

    } else if ( arguments.length == 5 ) {
        value = arguments[3] ;
        days  = arguments[4] ;

    } else if ( arguments.length > 5 ) {
        alert( 'Too many arguments!' + software_bug__detected_in ) ;
        return failure_return ;

    } else if ( arguments.length < 3 ) {
        alert( 'Not enough arguments!' + software_bug__detected_in ) ;
        return failure_return ;

        }

    // -----------------------------------------------------------------------
    // Could perhaps check the argument values.
    //
    // NOT YET IMPLEMENTED!
    // -----------------------------------------------------------------------

// alert( func + ' ' + cookieName + ':' + name + ' to: ' + value )

    // -----------------------------------------------------------------------
    // Delete the cookie?
    // -----------------------------------------------------------------------

    if ( func == 'kill' || ( cookieName == name && func == 'clear' ) ) {
        document.cookie = cookieName + '=; expires=-86400000';
        return success_return ;
        }

    // -----------------------------------------------------------------------
    // General initialisation...
    // -----------------------------------------------------------------------

    // -----------------------------------------------------------------------
    // document.cookie
    // - - - - - - - -
    // Get and set the cookies associated with the current document.
    //
    //      Get
    //      ---
    //      allCookies = document.cookie;
    //          allCookies is a string containing a semicolon-separated list of
    //          cookies (i.e. key=value pairs).  Eg:-
    //
    //              'myname=John; yourname=kars10; mypet=dog; yourpet=rodent'
    //
    //      Set
    //      ---
    //      document.cookie = updatedCookie;
    //          updatedCookie is a string of form key=value, optionally
    //          followed by cookie attribute values, specifying the cookie to
    //          set/update. Note that you can only set/update a single cookie
    //          at a time using this method.  Eg;
    //
    //              document.cookie = 'NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure' ;
    //              document.cookie = 'ppkcookie1=testcookie; expires=Thu, 2 Aug 2001 20:47:11 UTC; path=/'
    // -----------------------------------------------------------------------

//  var nameQuery = cookieName == name ? name + '=' : name + '-';
        //  nameQuery is used for searching for the required named value. If
        //  the cookie is a stacked cookie, the name/value separator is a "-",
        //  if non-stacked, "=". This makes searching for the required string
        //  in different places easier.

    var name_plus_name_value_separator = ( cookieName == name ) ? name + '=' : name + '-';

//  var thisCookie = '';
        //  thisCookie is used to contain the targetted cookie, if it exists.

    var input_cookie_value = '' ;

    var cookies = document.cookie.split(';') ;
        //  cookies is an array of strings, each of which is a separate cookie.
        //  Javascript acesses all cookies for a given document through a
        //  single string with each cookies separated from each other using the
        //  ";" symbol.

    for ( var x = 0 ; x < cookies.length ; x++ ) {

        if ( cookies[x].indexOf(cookieName) != -1 ) {
            input_cookie_value = cookies[x].substring(cookies[x].indexOf('=') + 1);
            input_cookie_value = URLDecode(input_cookie_value);
            }

        }
        //  The for loop is used to cycle through existing cookies to find the
        //  required cookie string.
        //
        //  As PHP will URL encode the value of a given cookie, we must
        //  URLDecode the packed value of our cookie. During the PHP URL
        //  encoding, the "|" character we use for name/value pair separation
        //  is encoded to %7C.

//  var cookieString = '';
        //  cookieString is used to contain data that will eventually be
        //  written to a cookie.

    var output_cookie_value = '' ;

    // -----------------------------------------------------------------------
    // Set/Clear...
    // -----------------------------------------------------------------------

    if ( func == 'clear' || func == 'set' ) {

        // -------------------------------------------------------------------

        if ( func == 'clear' ) {

            // ---------------------------------------------------------------
            // Clear
            // ---------------------------------------------------------------

            var myregexp = new RegExp( '(\\|' + name_plus_name_value_separator + '[\\w]*|' +
                                        name_plus_name_value_separator + '[\\w]*\\||' +
                                        name_plus_name_value_separator + '[\\w]*)');
                //  Construct a regular expression object to search for
                //  |name-value, if the name/value pair is at the end of the
                //  list, name-value|, if it is in the middle of the list or
                //  name-value if it is the only name/value pair.

            output_cookie_value = input_cookie_value.replace( myregexp , '' ) ;
                //  Use String.replace to execute the regex on thisCookie.

            // ---------------------------------------------------------------

        } else if ( func == 'set' ) {

            // ---------------------------------------------------------------
            // Set
            // ---------------------------------------------------------------

if ( name == 'scc_ctn' && cookieName == 'issues' ) {
    alert( 'COOKIE SET ERROR!  name: ' + name + '    cookieName: ' + cookieName )
console.trace() ;
    }

            //  Check to see if we are dealing with a regular cookie or a
            //  stacked but empty cookie and if so, simply set the name/value
            //  pair

            if ( cookieName == name || input_cookie_value == '' ) {

                output_cookie_value = name_plus_name_value_separator + value;

            } else {

                var myregexp = new RegExp('(' + name_plus_name_value_separator + '[\\w]*)');
                    //  Create a regex to search for an existing value for the
                    //  given name.

                var match    = myregexp.exec( input_cookie_value ) ;
                    //  Execute the regex.

                if ( match != null && match.length > 1 && match[1] != '' ) {

                    output_cookie_value = input_cookie_value.replace(
                                                match[1] ,
                                                name_plus_name_value_separator + value
                                                ) ;
                        //  If there is a match, replace it with the new
                        //  name/value pair.

                } else {

                    output_cookie_value = input_cookie_value +
                                            ( input_cookie_value != '' ? '|' : '' ) +
                                            name_plus_name_value_separator + value ;
                        //  If there is no match, the name does not currently
                        //  exist, add the name/value pair with the '|'
                        //  separator as needed.

                    }

                }

            }

        // -------------------------------------------------------------------
        // Write the updated cookie value to disk...
        // -------------------------------------------------------------------

//  alert( document.title )

//  alert( 'Output cookie value:  ' + output_cookie_value )

        var expires = '';

        if (days) {
            var date = new Date() ;
            date.setTime( date.getTime() + (days*24*60*60*1000) ) ;
//          var expires = '; expires=' + date.toGMTString();
            expires = '; expires=' + date.toGMTString();
            }

        // -------------------------------------------------------------------

/*
        document.cookie = cookieName +
                            '=' +
                            URLEncode(output_cookie_value) +
                            expires +
                            '; path=/; domain=.' +
                            window.location.hostname ;
*/

        // -------------------------------------------------------------------

        var domain = '' ;

        if ( window.location.hostname != 'localhost' ) {
            domain = '; domain=.' + window.location.hostname ;
            }

        // -------------------------------------------------------------------

        var set_string = cookieName +
                            '=' +
                            URLEncode(output_cookie_value) +
                            expires +
                            '; path=/' +
                            domain ;

//  alert( set_string ) ;

        document.cookie = set_string ;

//  alert( document.cookie )

        // -------------------------------------------------------------------

        return success_return ;

        // -------------------------------------------------------------------

        }

    // -----------------------------------------------------------------------
    // Read
    // -----------------------------------------------------------------------

    if ( func == 'read' ) {

        //  Check to see if there is any cookie data at all, if not, return
        //  null.

        if ( input_cookie_value != '' ) {

            var myregexp = new RegExp(name_plus_name_value_separator + '([\\w]*)');
                //  Construct a regex to search for the value of the requested
                //  name/value pair.

            var match    = myregexp.exec(input_cookie_value);
                //  Execute the regex and return any matched value.

            if ( match != null && match.length > 1 && match[1] != '' ) {
                return match[1];
                }

            //  If nothing matches, return null.

            }

        return null;

        }

    // -----------------------------------------------------------------------
    // ERROR!
    // -----------------------------------------------------------------------

    alert( 'Bad \'func\' (must be \'read\', \'set\', \'clear\' or \'kill\')' +
            software_bug__detected_in ) ;

    return failure_return ;

    // -----------------------------------------------------------------------

    }

