jQuery.fn.extend({

	createCSSFilePicker: function(uploadFunction, autoUploadFunction, defaultvalue) {
		this.each(function() {
			var element = $(this);

			element.removeClass('required'); // required parent object not this one

			if(element.parent().hasClass('cssfilepicker')) {
				element.bind('keypress keyup keydown',function(){return false;}).bind('change', function(){ $(this).parent().parent().find('label.warning').hide(); $(this).parent().parent().find('input.warning').removeClass('warning'); $(this).parent().children('.dummybrowse').children('.dummyinput').val($(this).val()).removeClass('warning'); if(typeof autoUploadFunction == 'function') { autoUploadFunction();}}).bind('select', function(){ $(this).trigger('click');});
			} else {
				element.wrap('<div class="cssfilepicker"></div>');

				element.bind('keypress keyup keydown',function(){return false;}).bind('change', function(){ $(this).parent().parent().find('label.warning').hide(); $(this).parent().parent().find('input.warning').removeClass('warning'); $(this).parent().children('.dummybrowse').children('.dummyinput').val($(this).val()).removeClass('warning'); if(typeof autoUploadFunction == 'function') { autoUploadFunction();}}).bind('select', function(){ $(this).trigger('click');});

				var dummy = $('<div />').insertAfter(element).addClass('dummybrowse').append('<button />');
				$('<input />').appendTo(dummy).addClass(element.attr('class')+' dummyinput').val(element.val() ? element.val() : (defaultvalue != undefined ? defaultvalue : ''));

				if(typeof uploadFunction == 'function') {
					$('<input type="submit" />').insertAfter(dummy).addClass('submit').val('Toevoegen').attr('title', 'Toevoegen').bind('click', uploadFunction).bind('click', function(){this.blur()});
				}
				$('<span />').insertAfter(dummy).addClass('progressbar').css('display','none');

				element.addClass('filetoupload');
			}
		});
	},
	createCSSImageUploader: function(s) {

		var _s = $.extend({ },{ autoUpload: false, uploadUrl: '', callback: false, defaultvalue: ''},s);
		$.each(this, function() {
			var s = _s;

			if(this.type == 'file') {
				var uploadElement = $(this);
			} else {
				var element = $(this).hide();
				if(element.val() != '') {
					s.defaultvalue = element.val().substring(element.val().lastIndexOf('/') + 1);
				} else {
					s.defaultvalue = '';
				}
				var uploadElement = $('<input type="file" />').attr('size', 150).addClass(element.attr('class')).attr('id', element.attr('id')+'_ajaxupload').attr('name', element.attr('name')).insertAfter(element);
				uploadElement.attr('orgElement', element.attr('id'));
			}

			uploadElement.attr('uploading', 0);

			function autoUpload(){
				var element = uploadElement;
				var settings = s;
				if(s.autoUpload && uploadElement.val() != '' && uploadElement.attr('uploading') == 0) {
					uploadElement.attr('uploading', 1);
					uploadElement.parent().children(".dummybrowse").hide();
					uploadElement.parent().children(".progressbar").show();
					uploadElement.ajaxFileUpload(
						{
							url: s.uploadUrl,
							dataType: "json",
							success: function (data, status) {
								if(data.error) {
									alert(data.error);
								} else {
									$.each(this.data,function(name,id){
										var element = $('#'+id);
										if(data[name]) {
											if(element.attr('orgElement')) {
												var org = $('#'+element.attr('orgElement'));
											} else {
												var org = element;
											}
											if(data[name].error) {
												if(org[0].form) {
													var errors = {};
													errors[name] = data[name].error;
													$(org[0].form).validate().showErrors(errors);
												}
											} else {
												settings.defaultvalue = data[name].name;
												org.val(data[name].url);
												if(settings.callback){
													settings.callback(data[name],element);
												}
											}

											if(element.attr('id') != org.attr('id')) {
												element.parent().remove();
											} else {
												element.attr('uploading', 0);
												element.parent().children(".dummybrowse").show();
												element.parent().children(".progressbar").hide();
											}
											// re-init uploader (events aren't bind anymore)
											org.createCSSImageUploader(settings);
										}
									});
								}
							},
							error: function (data, status, e) {
								//alert('error:'+status+e);

								$.each(this.data,function(name,id){
									var element = $('#'+id);
									element.attr('uploading', 0);
									element.parent().children(".dummybrowse").show();
									element.parent().children(".progressbar").hide();
									settings.defaultvalue = '';
									// re-init uploader (events aren't bind anymore)
									if(element.attr('rel')) {
										$('#'+element.attr('rel')).createCSSImageUploader(settings);
									} else {
										element.createCSSImageUploader(settings);
									}
								});
							}
						});
				}
			}
			uploadElement.createCSSFilePicker(false, autoUpload, s.defaultvalue);
		});

	}
});

(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);

	  $.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";

    s.element = this;
    var id = (new Date().getTime());
    var frameId = 'jUploadFrame' + id;
    var formId = 'jUploadForm' + id;

	if(!s.data) {
		s.data = {};
		s.data[this.attr('name')] = this.attr('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) {
        $(oldElems[i]).before(newElems[i]);
      });

    oldElems.appendTo(form);

    // 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;
            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);