/**
 * @example $('form#user').fastSerialize()
 */
$.fn.fastSerialize = function() {
    var a = [];
    $('input,textarea,select,button', this).each(function() {
        var n = this.name;
        var t = this.type;
        if ( !n || this.disabled || t == 'reset' ||
            (t == 'checkbox' || t == 'radio') && !this.checked ||
            (t == 'submit' || t == 'image' || t == 'button') && this.form.clicked != this ||
            this.tagName.toLowerCase() == 'select' && this.selectedIndex == -1)
            return;
        if (t == 'image' && this.form.clicked_x)
            return a.push(
                {name: n+'_x', value: this.form.clicked_x},
                {name: n+'_y', value: this.form.clicked_y}
            );
        if (t == 'select-multiple') {
            $('option:selected', this).each( function() {
                a.push({name: n, value: this.value});
            });
            return;
        }
        a.push({name: n, value: this.value});
    });
    return a;
};

/**
 * @version 0.35
 */
$.fn.deserialize = function(d,config) {
	var data= d;
	me  = this;

	if (d === undefined) {
		return me;
	}

	config = $.extend({ isPHPnaming	: false,
						overwrite	: true},config);

	// check if data is an array, and convert to hash, converting multiple entries of
	// same name to an array
	if (d.constructor == Array)	{
		data={};
		for(var i=0; i<d.length; i++) {
			if (typeof data[d[i].name] != 'undefined') {
				if (data[d[i].name].constructor!= Array) {
					data[d[i].name]=[data[d[i].name],d[i].value];
				} else {
					data[d[i].name].push(d[i].value);
				}
			} else {
				data[d[i].name]=d[i].value;
			}
		}
	}

	// now data is a hash. insert each parameter into the form
	$('input,select,textarea',me)
	.each(function() {
			  var p=this.name;
			  var v = [];

			  // handle wierd PHP names if required
			  if (config.isPHPnaming) {
				  p=p.replace(/\[\]$/,'');
			  }
			  if(p && data[p] != undefined) {
				  v = data[p].constructor == Array ? data[p] : [data[p]];
			  }
			  // Additional parameter overwrite
			  if (config.overwrite === true || data[p]) {
				  switch(this.type || this.tagName.toLowerCase()) {
				  case "radio":
				  case "checkbox":
					  this.checked=false;
					  for(var i=0;i<v.length;i++) {
						  this.checked|=(this.value!='' && v[i]==this.value);
					  }
					  break;
				  case "select-multiple" || "select":
					  for( i=0;i<this.options.length;i++) {
						  this.options[i].selected=false;
						  for(var j=0;j<v.length;j++) {
							  this.options[i].selected|=(this.options[i].value!='' && this.options[i].value==v[j]);
						  }
					  }
					  break;
				  case "button":
				  case "submit":
					  this.value=v.length>0?v.join(','):this.value;
						  break;
				  default:
					  this.value=v.join(',');
				  }
			  }
		  });
	return me;
};
