(function($){
	// we need jQuery to run
	if ( ! $) return;

	$.ajax_upload = function(button, options){
		// make sure it is jquery object
		button = $(button);
		
		if (button.size() != 1 ){
			console.error('You passed ', button.size(),' elements to ajax_upload at once');
			return false;
		}
			
		return new Ajax_upload(button, options);		
	};

	var get_uid = function(){
		var uid = 0;
		return function(){
			return uid++;
		}
	}();

	var Ajax_upload = function(button, options){
		this.button = button;
				
		this.wrapper = null;
		this.form = null;
		this.input = null;
		this.iframe = null;		

		this.disabled = false;
		this.submitting = false;
				
		this.settings = {
			// Location of the server-side upload script
			action: 'upload.php',			
			// File upload name
			name: 'userfile',
			// Additional data to send
			data: {},
			// Fired when user selects file
			// You can return false to cancel upload
			onSubmit: function(file, extension) {},
			// Fired when file upload is completed
			onComplete: function(file, response) {},
			// Fired when server returns the "success" string				
			onSuccess: function(file){},
			// Fired when server return something else
			onError: function(file, response){}
		};

		// Merge the users options with our defaults	
		$.extend(this.settings, options);
		
		this.create_wrapper();
		this.create_input();
		
		if (jQuery.browser.msie){
			// fix ie transparent background bug
			this.make_parent_opaque();
		}
	}
	// assigning methods to our class
	Ajax_upload.prototype = {
		set_data : function(data){
			this.settings.data = data;
		},
		disable : function(){
			this.disabled = true;
			if ( ! this.submitting){
				this.input.attr('disabled', true);			
			}			
		},
		enable : function(){
			this.disabled = false;
			this.input.attr('disabled', false);							
		},
		create_wrapper : function(){
			// Shorten names			
			var button = this.button, wrapper;

			wrapper = this.wrapper = $('<div></div>')
				.insertAfter(button)
				.append(button);
				
			$('<input type="text" id="fname" readonly="readonly" />').insertBefore(this.wrapper);
			
			// wait a bit because of FF bug
			// it can't properly calculate the outerHeight
			setTimeout(function(){
				wrapper.css({
					position: 'relative'
					,display: 'block'
					,overflow: 'hidden'
					
					,height: button.outerHeight(true)
					,width: button.outerWidth(true)
				});						
			}, 1);
			
			var self = this;
			wrapper.mousemove(function(e){
				// Move the input with the mouse, so the user can't misclick it
				if (!self.input) {
					return;
				}
									
				self.input.css({
					top: e.pageY - wrapper.offset().top - 5 + 'px'
					,left: e.pageX - wrapper.offset().left - 170 + 'px'
				});
			});

	
		},

		create_input : function(){
			var self = this;

			this.input = 
				$('<input type="file" />')
				.attr('name', this.settings.name)				
				.css({
					'position' : 'absolute'
					,'margin': 0
					,'padding': 0
					,'width': '220px'
					,'heigth': '10px'										
					,'opacity': 0								
				})
				.change(function(){
					if ($(this).val() == ''){
						// there is no file
						return;
					}
				})
				.appendTo(this.wrapper)
				
				// Emulate button hover effect				
				.hover(
					function(){self.button.addClass('hover');}
					,function(){self.button.removeClass('hover');}
				);
				
			if (this.disabled){
				this.input.attr('disabled', true);
			}

		},
		file_from_path : function(file){
			var i = file.lastIndexOf('\\');
			if (i !== -1 ){
				return file.slice(i+1);
			}			
			return file;				
		},
		get_ext : function(file){
			var i = file.lastIndexOf('.');
			
			if (i !== -1 ){
				return file.slice(i+1);				
			}			
			return '';	
		},
		make_parent_opaque : function(){
			// ie transparent background bug
			this.button.add(this.button.parents()).each(function(){				
				var color = $(this).css('backgroundColor');
				var image = $(this).css('backgroundImage');
	
				if ( color != 'transparent' ||  image != 'none'){
					$(this).css('opacity', 1);
					return false;
				}
			});			
		}
		
	};
})(jQuery);