jQuery.fn.extend({
    clear : function(params) {
        if(!this.is('select')) return false;
        if(typeof(params)=='undefined') { 
            this.each(function(i,o) {
                while(o.options.length > 0) o.options[o.options.length-1] = null;
            });
        }
    },
    reset : function() { 
        if(!this.is('select')) return false;
        this.each(function(i,o) { 
            o.selectedIndex = 0;
        });
    },
    serializeF : function(post, defaults) { 
        if(typeof(post)=='undefined') post = true;
        if(typeof(defaults) == 'undefined') defaults = new Array();
        
        var params = post ? this._serializePost(defaults) : this._serializeGet(defaults)
        return params
    },
    _serializePost : function(defaults) {
        var params = this._collectParams();
        for(i in defaults) {
            if(params[defaults[i].name] == encodeURIComponent(defaults[i].text))
                params[defaults[i].name] = '';
        }
        return params;
        
        // var params_attrs = {};
        //         var params = this._collectParams();
        //         for (var i = 0; i < params.length; i++) { 
        //             var attrs = params[i].split('=');
        //             params_attrs[attrs[0]] = attrs[1];
        //         }
        //         return params_attrs;
    },
    _serializeGet : function(defaults) {
        get_str = '';
        var params = this._collectParams();
        for(i in defaults) {
            params[defaults[i].name] = '';
        }
        var params_a = new Array();
        for(x in params) {
            params_a.push(x + '=' + params[x])
        }
        return params_a.join('&')
    },
    _collectParams : function() { 
        var key_params = {};
        this.find('select').each(function(i,o) { 
            if(typeof(o)=='undefined') return;
            $o = $(o);
            if($o.attr("name") !=='') {
                var attr = $o.serialize().split('=')
                key_params[attr[0]] = attr[1];
            }
        });
        
        this.find('input').each(function(i,o) { 
            if(typeof(o)=='undefined') return;
            $o = $(o);
            
            if($o.attr("name") !=='') {
                var attr = $o.serialize().split('=')
                key_params[attr[0]] = attr[1];
            }
        });
        this.find('textarea').each(function(i,o) { 
            if(typeof(o)=='undefined') return;
            $o = $(o);
            if($o.attr("name") !=='') {
                var attr = $o.serialize().split('=')
                key_params[attr[0]] = attr[1];
            }
        });
        return key_params;
    },
    /*submit : function() {
        this.each(function(i,o) { 
            o.submit();
        })
    },*/
    switchContent : function(options,effects) { 
        if(typeof(effects) == 'undefined') effects = {}
        if(typeof(options) == 'undefined') {
            alert('switchContent: you must specify options');
            return false;
        }
        if(typeof(options.url) == 'undefined') {
            alert('switchContent: $url is missing');
            return false;
        }
        if(typeof(options.parameters) == 'undefined' && typeof(options.params) !='undefined') {
            options.parameters = options.params;
        }
        if(typeof(options.parameters) == 'undefined') {
            options.parameters = '';
        }
        else if(typeof(options.parameters) == 'object') {
            var parameters = options.parameters.serializeF();
            options.parameters = parameters;
        }
        if(typeof options.onlyIfUpdated == 'undefined') options.onlyIfUpdated = false;
        if(typeof(effects.before) === 'undefined') effects.before = '';
        if(typeof(effects.after) === 'undefined') effects.after='';
        if(typeof(effects.speed) === 'undefined') effects.speed=1000;
        
        
        
        /* build execution function */
        exec = function(o, result) {
            /* if options.onlyIfUpdated is set,
             * the content is only updated, if the
             * content really changed */
            /* alert($(result).html());
             alert(this.html());*/
            /* alert($(o).html() == $(result).html()); */
            if(options.onlyIfUpdated && $(result).html() == $(o).html()) return false;
            
            if(typeof options.processData != 'undefined') options.processData(result);
            
            if (effects.before === '' && effects.after === '') $(o).html(result);
            callback = null;
            if (effects.after !== '') {
                var script = "function() {$(o).html(result)." + effects.after + "(" + effects.speed + ")}";
            }
            if (effects.before) {
                var script2="$(o).";
                if (effects.after === '') {
                    script2 += "html(result).";
                }
                script2 += effects.before + "(" + effects.speed;
                if (effects.after) script2 += ", " + script;
                script2 += ");";
                eval(script2);
            }
        };
        
        this.each(function(i,o){
            $.post(options.url, options.parameters, function(result) { exec(o, result) }, "html");
        });
    },
    defaultTo : function(field, txt) {
        /* if field is an array, then it's assumed
         * that the first element is an array
         * containing configurations, for different
         * fields of the form
         *
         * form: [{'name' : 'name', 'text' : 'Your name is here...'}...]
         */
        if(typeof(field) != 'object') {
            this._defaultTo(field, txt); 
            return
        }
        
        for(x in field) {
            var dict = field[x];
            this._defaultTo(dict['name'], dict['text'], dict['type'])
        }
    },
    _defaultTo : function(field, txt, type) {
        if(typeof(type) == 'undefined') type = null;
        if(this.is("input") || this.is("textarea"))
            context = this;
        else {
            if(!type) {
                context = this.find('input[@name="' + field + '"]')
            }
            else {
                context = this.find('textarea[@name="' + field + '"]')
            }
        }
        
        context.each(function(i,o){
            var x = o;
            $(o).focus(function() {
                if(o.value == txt)
                    x.value = '';
            })
            $(o).blur(function() {
                if(x.value == '' || x.value == txt)
                    x.value = txt;
            })
        })
    },
    rowHover : function(klass) {
        $('tr', this).hover(function() {
            $('td', this).addClass(klass);
            $('td *', this).addClass(klass);
        }, function() {
            $('td', this).removeClass(klass);
            $('td *', this).removeClass(klass);
        })
    },
    tableHover : function(klass) {
        this.each(function() {
            var table = this;
            $('tr', this).hover(function() {
                $('td', table).addClass(klass);
                $('td *', table).addClass(klass);
            }, function() {
                $('td', table).removeClass(klass);
                $('td *', table).removeClass(klass);
            })
        });
        
        /*this.hover(function() {
            $('td', this).addClass(klass);
            $('td *', this).addClass(klass);
        }, function() {
            $('td', this).removeClass(klass);
            $('td *', this).removeClass(klass);
        });*/
    }
});
