;
(function ($) {
  $.ajaxUpload = {
    createUploadIframe: function(frameId)
    {
      var io = $('<iframe id="' + frameId + '" name="' + frameId + '" />');
      
      io.attr('src', 'javascript:false');
      io.css('position', 'absolute');
      io.css('top', '-1000px');
      io.css('left', '-1000px');


      io.appendTo(document.body);

      return io.get(0);
    },
    createUploadForm: function(formId, frameId, url, data)
    {
      //create form 
      var form = $('<form action="" target="' + frameId + '" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>'); 
      
      //set attributes
      form.attr('action', url)
          .attr('enctype', 'multipart/form-data')
          .attr('encoding', 'multipart/form-data')
          .css('position', 'absolute')
          .css('top', '-1200px')
          .css('left', '-1200px')
          .appendTo(document.body);
	  
	  //Set X_REQUESTED_WITH flag in POST
      $('<input type="hidden" />').attr('name', 'X_REQUESTED_WITH').attr('value', 'XMLHttpRequest').appendTo(form);
	  
      $.each(data, function(name, val) {
          $('<input type="hidden" />').attr('name', name).attr('value', val).appendTo(form);
        });
      
      return form.get(0);
    }
  };
  
  $.fn.ajaxFileUpload = function(s) {
    s = $.extend({ }, $.ajaxSettings, s, 
                                      {
                                        contentType: 'multipart/form-data',
                                        cache: false,
                                        type: 'POST',
                                        async: true,
                                        username: null,
                                        password: null
                                      }); // Some forced options
      
    if ( s.data && s.processData && typeof s.data === "string" )
      throw "Can't use a string as data - sorry";
    
    var id = (new Date().getTime());
    var frameId = 'jUploadFrame' + id;
    var formId = 'jUploadForm' + id;    
    
    var io = $.ajaxUpload.createUploadIframe(frameId);
    var form = $.ajaxUpload.createUploadForm(formId, frameId, s.url, s.data);
    
    var oldElems = $(this);
    var newElems = oldElems.clone();
	
    oldElems.attr('id', '');
    $.each(oldElems, function(i) {
    	if ($(oldElems[i]).attr('type') == 'radio') {
			if ($(oldElems[i]).attr('checked')) 
				$(form).append('<input type="radio" name="' + $(oldElems[i]).attr('name') + '" value="' + $(oldElems[i]).val() + '" checked="checked"  />');
			else 
				$(form).append('<input type="radio" name="' + $(oldElems[i]).attr('name') + '" value="' + $(oldElems[i]).val() + '" />');
		}else if (oldElems[i].tagName == 'SELECT'){
			
		}
		
	  });
    
    $.each(oldElems, function(i) {
        $(oldElems[i]).before(newElems[i]);
      });
    
    var grepElems = $.grep(oldElems, function(a,k){
	    return true;
    });
    
    $(grepElems).appendTo(form);
    
    $.each(oldElems, function(i) {
        if (oldElems[i].tagName=='TEXTAREA')$(newElems[i]).val($(oldElems[i]).val());
		else if (oldElems[i].tagName=='INPUT' && (oldElems[i].type!='file' && oldElems[i].type!='checkbox' && oldElems[i].type!='radio'))$(newElems[i]).val($(oldElems[i]).val());
//		else if (oldElems[i].tagName=='SELECT') $(newElems[i]).html($(oldElems[i]).html());
    });
	
	oldElems.each(function(k){
		if (oldElems[k].tagName == 'SELECT'){
			$(this).find("option:selected").each(function(i){
				$(newElems[k]).find("option[value='"+$(this).val()+"']").attr('selected','selected');
			});
		}
	});
    // Watch for a new set of requests
    if ( s.global && ! $.active++ ) $.event.trigger( "ajaxStart" );
    
    var getDocument = function(io) {
        if (io.contentWindow)
          return io.contentWindow.document;
        else if (io.contentDocument)
          return io.contentDocument.document;
        
        return null;
      };
        
    // Create the request object
    var xml = {
                timeoutTimer: null,
                clearTimer: null,
                requestDone: false,
                
                getResponseHeader: function(str) {
                  if (str.toLowerCase() == 'content-type') {
                    try {
                      var doc = getDocument(io);
                      
                      // The firefox way
                      if (doc && doc.contentType)
                        return doc.contentType;
                    }
                    catch (ex) { }

                    //We have to guess...
                    if (s.dataType == 'xml' && this.responseXML && this.responseXML.documentElement && this.responseXML.documentElement.nodeName != 'HTML')
                      return 'text/xml';
                    
                    return 'text/html';
                  }
                  
                  throw "Unknown response header " + str;
                },
                getAllResponseHeaders: function() {
                  return [this.getResponseHeader('content-type')];
                },
                abort: function() {
                  if (this.clearTimer) return;
                  if (this.timeoutTimer) {
                    window.clearTimeout(this.timeoutTimer);
                    this.timeoutTimer = null;
                  }
                  
                  this.requestDone = true;
                  
                  // The request was completed
                  if( s.global )
                      $.event.trigger( "ajaxComplete", [xml, s] );

                  // Handle the global AJAX counter
                  if ( s.global && ! --$.active )
                      $.event.trigger( "ajaxStop" );
                  
                  var that = this;
                  
                  this.clearTimer = setTimeout(function() { 
                      try {
                        $(io).remove();
                        $(form).remove();
                      } 
                      catch(e) {
                        $.handleError(s, that, null, e);
                      }
                      finally {
                        that.clearTimer = null;
                      }
                    }, 100);
                }
              };
              
    if ( s.global )
        $.event.trigger("ajaxSend", [xml, s]);
    
    // Wait for a response to come back
    var uploadCallback = function(reason)
      {
        if (xml.requestDone) return;
        xml.requestDone = true;
        
        try {
          var doc = getDocument(io);
          
          if (doc) {
            if (doc.location.href != s.url && doc.location.href == 'about:blank') {
              throw "Bad HTTP status";
            }
            
            // IE is EVIL!
            if (doc.XMLDocument && s.dataType == 'xml')
              doc = doc.XMLDocument;
            
            if (s.dataType == 'html' && doc.documentElement && doc.documentElement.innerHTML)
              //xml.responseText = doc.documentElement.innerHTML;
			  xml.responseText = doc.documentElement.lastChild.innerHTML;//get the contents from the body
            else if (s.dataType == 'json' && doc.documentElement && doc.documentElement.innerHTML)
              xml.responseText = doc.documentElement.lastChild.innerHTML;
            else if (doc.documentElement && 
                      (doc.documentElement.textContent || doc.documentElement.innerText))
              xml.responseText = doc.documentElement.innerText ? doc.documentElement.innerText : doc.documentElement.textContent;
            else
              xml.responseText = '';
              
            xml.responseXML = doc;
          }
        }
        catch(e) {
          $.handleError(s, xml, null, e);
        }
          
        var status;
        
        status = reason != "" ? reason : "success";
        
        // Make sure that the request was successful or notmodified
        if ( status == "success" ) {
          // process the data (runs the xml through httpData regardless of callback)
          try {
            var data = $.httpData( xml, s.dataType, s.dataFilter);
          }
          catch (ex) {
          	status = "parseerror";
          }
        }
        if ( status == "success" ) {
          // If a local callback was specified, fire it and pass it the data
          if ( s.success )
            s.success( data, status );
  
          // Fire the global callback
          if( s.global )
            $.event.trigger( "ajaxSuccess", [xml, s] );
        } 
        else
            $.handleError(s, xml, status);

        // Process result
        if ( s.complete )
            s.complete(xml, status);

        xml.abort();
      };
    
    // Timeout checker
    if ( s.timeout > 0 ) {
      xml.timeoutTimer = setTimeout(function(){
        // Check to see if the request is still happening
        if( !xml.requestDone ) uploadCallback( "timeout" );
      }, s.timeout);
    }
    
    $(io).load(function() { uploadCallback(""); });
    
    try {
      form.submit();
    } 
    catch(e) {
      $.handleError(s, this, null, e);
    }
    
    return xml;
 }
})(jQuery);