/* 
   object for handling, parsing, printing, etc of cgi strings

   this is fairly dumb just now needs work on multiple values etc
   */

// Added a try catch, for some reason, I would get an error in IE without it.
try{
    if(console == undefined){
        console = new Object();
    }
    if(console.log == undefined){
        console.log = function(){};
    }
}
catch(err){
    console = new Object();
    console.log = function(){};
}


CGI = Class.create();




CGI.fromCookies= function(){
    var string = document.cookie.replace(/\s/,"");
    string = string.replace(/\W+$/,"");
    var cgiCookies = new CGI(string);
    return cgiCookies;
}



Object.extend(CGI.prototype,Hash.prototype);



Object.extend(CGI.prototype, {
    isCGI: true,
    options : {
    },
    gettingQueryString: false,
    initialize: function(string,options){
        if(options){
            Object.extend(this.options,options);//overwrite default options with custom ones
        }
        if(string == undefined){
            string = document.location.href;
            string = string.replace(/^[^?]*\??/,"");
            this.parseString(string);
        }
        else if(string instanceof String){ //its a string
            this.parseString(string);
        }
        else if(string.toQueryString){
            this.parseString(string.toQueryString());
        }
        else{
            //try our best
            this.parseString(string.toString());
        }
    },
    toString: function(){
        return this.toQueryString();
    },
    toQueryString: function() {
        this.gettingQueryString = true;
        var parts = [];
        parts.add = Hash.toQueryString.addPair;

        this._each(function(pair) {
            if (!pair.key) return;
            var value = pair.value;
            if(value == undefined){
                return;
            }

            if (value && typeof value == 'object') {
                if (value.constructor == Array) value.each(function(value) {
                    parts.add(pair.key, value);
                });
                if (value.isCGI && ! value.gettingQueryString) {
                    parts.add(pair.key, value.toQueryString());
                }
                return;
            }
            parts.add(pair.key, value);
        });

        this.gettingQueryString = false;
        return parts.join('&');
    },
    parseString: function(string){
        var me = this;
        string = string.replace(/\+/g," ");
        var bits = string.split(/[\&\;]/);
        for (var i = 0; i < bits.length; i++){
            var bit = bits[i];
            this.parseBit(bit);
        };
    },
    parseBit: function(bit){
        if(bit == undefined || bit == ""){
            return;
        }
        var match = bit.match(/(.*)=(.*)/);
        if(match){
            var key = match[1];
            var value = unescape(match[2]);
            if(! this.options.noNesting){
                var equals = value.match(/=/g);
                if(equals){
                    var splits = value.match(/[\&\;]/g);
                    splits = splits ? splits : [];
                    if(equals.length == splits.length + 1 || equals.length == splits.length){
                        value = new CGI(value);
                    }
                }
            }
            this[key] = value;
        }
        else{
            console.log("error parsing: " + bit);
        }
    },
    _each: function(iterator) { //need to overload this from hash to hide cgi stuff
        for (var key in this) {
            var value = this[key];
            if (value != undefined && ( value == CGI.prototype[key] || ( typeof value == "boolean" && CGI.prototype[key] != undefined && value == !CGI.prototype[key] ) )) continue;
            var pair = [key, value];
            pair.key = key;
            pair.value = value;
            iterator.call(this,pair);
        }
    },
    recursiveEach: function( iterator ){
        this._each( function(pair){
            try{
                if(pair.value && pair.value.recursiveEach){
                    pair.value.recursiveEach(iterator);
                }
                else{
                    iterator.call(this,pair);
                }
            }
            catch(err){
                console.log("recursiveEach Error :");
                console.log(err);
            }
        });
    }
});

