/*

 * jQuery.upload v1.0.2

 *

 * Copyright (c) 2010 lagos

 * Dual licensed under the MIT and GPL licenses.

 *

 * http://lagoscript.org

 */

(function($) {



	var uuid = 0;



	$.fn.upload = function(url, data, callback, type) {

		var self = this, inputs, checkbox, checked,

			iframeName = 'jquery_upload' + ++uuid,

			iframe = $('<iframe name="' + iframeName + '" style="position:absolute;top:-9999px" />').appendTo('body'),

			form = '<form target="' + iframeName + '" method="post" enctype="multipart/form-data" />';



		if ($.isFunction(data)) {

			type = callback;

			callback = data;

			data = {};

		}



		checkbox = $('input:checkbox', this);

		checked = $('input:checked', this);

		form = self.wrapAll(form).parent('form').attr('action', url);



		// Make sure radios and checkboxes keep original values

		// (IE resets checkd attributes when appending)

		checkbox.removeAttr('checked');

		checked.attr('checked', true);



		inputs = createInputs(data);

		inputs = inputs ? $(inputs).appendTo(form) : null;



		form.submit(function() {

			iframe.load(function() {

				var data = handleData(this, type),

					checked = $('input:checked', self);



				form.after(self).remove();

				checkbox.removeAttr('checked');

				checked.attr('checked', true);

				if (inputs) {

					inputs.remove();

				}



				setTimeout(function() {

					iframe.remove();

					if (type === 'script') {

						$.globalEval(data);

					}

					if (callback) {

						callback.call(self, data);

					}

				}, 0);

			});

		}).submit();



		return this;

	};



	function createInputs(data) {

		return $.map(param(data), function(param) {

			return '<input type="hidden" name="' + param.name + '" value="' + param.value + '"/>';

		}).join('');

	}



	function param(data) {

		if ($.isArray(data)) {

			return data;

		}

		var params = [];



		function add(name, value) {

			params.push({name:name, value:value});

		}



		if (typeof data === 'object') {

			$.each(data, function(name) {

				if ($.isArray(this)) {

					$.each(this, function() {

						add(name, this);

					});

				} else {

					add(name, $.isFunction(this) ? this() : this);

				}

			});

		} else if (typeof data === 'string') {

			$.each(data.split('&'), function() {

				var param = $.map(this.split('='), function(v) {

					return decodeURIComponent(v.replace(/\+/g, ' '));

				});



				add(param[0], param[1]);

			});

		}



		return params;

	}



	function handleData(iframe, type) {

		var data, contents = $(iframe).contents().get(0);



		if ($.isXMLDoc(contents) || contents.XMLDocument) {

			return contents.XMLDocument || contents;

		}

		data = $(contents).find('body').html();



		switch (type) {

			case 'xml':

				data = parseXml(data);

				break;

			case 'json':

				data = window.eval('(' + data + ')');

				break;

		}

		return data;

	}



	function parseXml(text) {

		if (window.DOMParser) {

			return new DOMParser().parseFromString(text, 'application/xml');

		} else {

			var xml = new ActiveXObject('Microsoft.XMLDOM');

			xml.async = false;

			xml.loadXML(text);

			return xml;

		}

	}



})(jQuery);

