/*
 * jQuery.upload v1.0.3
 *
 * Copyright (c) 2013 Bass Jobsen
 * http://www.w3masters.nl/
 * Dual licensed under the MIT and GPL licenses.
 *
 * Original written by Lagos (http://lagoscript.org/)
 *
 * Contributors:
 * Mr Rogers http://rcode5.wordpress.com/
 */
 
(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);
    self.after('<input type="submit" formnovalidate style="display:none">');
    // 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);
      });
    }).find(':submit').click(); //.submit();

    return this;
  };

  function createInputs(data) {
    return $.map(param(data), function(param) {
    var e = $(document.createElement('input'));
	e.attr('type', 'hidden');
	e.attr('name', param.name);
	e.attr('value', param.value);
	return e;
    });
  }

  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').text();
    switch (type) {
    case 'xml':
      data = parseXml(data);
      break;
    case 'json':
      data = $.parseJSON(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);
