/*
 * jquery.uploadProgress
 *
 * Copyright (c) 2008 Piotr Sarnacki (drogomir.com)
 *
 *
 * Licensed under the MIT license:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 */
(function($) {
  $.fn.uploadProgress = function(options) {
	  
	options = $.extend({
		interval: 2000, 
		progressBar: "#progressbar",
		progressUrl: "/progress",
		start: function() {},
		uploading: function() {},
		complete: function() {},
		success: function() {},
		error: function() {},
		cancel: function() {},
		empty: function() {},
		preloadImages: [],
		uploadProgressPath: '/javascripts/jquery.uploadProgress.js',
		jqueryPath: '/javascripts/jquery.js',
        timer: "",
        rdmid: 1
	}, options);
	
	$(function() {
		//preload images
		
		for(var i = 0; i<options.preloadImages.length; i++)
		{
		  options.preloadImages[i] = $("<img>").attr("src", options.preloadImages[i]);
		}
		/* tried to add iframe after submit (to not always load it) but it won't work. 
		safari can't get scripts properly while submitting files */
		if(($.browser.safari || $.browser.opera) && top.document == document) {
			/* iframe to send ajax requests in safari 
			   thanks to Michele Finotto for idea */
			iframe = document.createElement('iframe');
			iframe.name = "progressFrame";
			
			$(iframe).css({width: '0', height: '0', position: 'absolute', top: '-3000px'});
			document.body.appendChild(iframe);
			
			var d = iframe.contentWindow.document;
			d.open();
			/* weird - safari won't load scripts without this lines... */
			d.write('<html><head></head><body></body></html>');
			d.close();
			
			var b = d.body;
			var s = d.createElement('script');
			s.src = options.jqueryPath;
			/* must be sure that jquery is loaded */
			s.onload = function() {
				var s1 = d.createElement('script');
				s1.src = options.uploadProgressPath;
				b.appendChild(s1);
			}
			b.appendChild(s);
		}
	});
	
	//return this.each(function(){
	//var test =	$(this).bind('submit', function() {
	$(this).submit(function() {	
		    
			var uuid = "";
			for (i = 0; i < 32; i++) { uuid += Math.floor(Math.random() * 16).toString(16); }
			
            /* update uuid */
            options.uuid = uuid;
			/* start callback */
			options.start(options.rdmid);

			/* patch the form-action tag to include the progress-id 
               if X-Progress-ID has been already added just replace it */
            if(old_id = /X-Progress-ID=([^&]+)/.exec($(this).attr("action"))) {
                var action = $(this).attr("action").replace(old_id[1], uuid);
                $(this).attr("action", action);
            } else {
			  $(this).attr("action", jQuery(this).attr("action") + "?X-Progress-ID=" + uuid);
			}
			
			/* patch make the uuid available to the interval request */
			options.progressUrl = options.progressUrl + "?X-Progress-ID=" + uuid;
			
			
			
			var uploadProgress = ($.browser.safari || $.browser.opera) ? progressFrame.jQuery.uploadProgress : jQuery.uploadProgress;
			options.timer = window.setInterval(function() { uploadProgress(this, options) }, options.interval);
			
			var jThis = $( this );
 			var strName = ("uploader" + (new Date()).getTime());
			var jFrame = $( "<iframe name=\"" + strName + "\" src=\"about:blank\" />" );
			jFrame.css( "display", "none" );
			jFrame.load(
					function( objEvent ){
						var objUploadBody = window.frames[ strName ].document.getElementsByTagName( "body" )[ 0 ];
						var jBody = $( objUploadBody );
						var objData = eval( "(" + jBody.html() + ")" );
						
						setTimeout(	function(){
								jFrame.remove();
							},100 );
						
						 
						if(objData.state == "error") {
						    alert("An error occurred please re-submit the file."); 
						    options.complete(options.rdmid);
						}	
						
						if(objData.state == "bad_zip") {
							alert(objData.file+" is not a valid zip file.");
							options.complete(options.rdmid);
						}
						
						if(objData.state == "bad_image") {
						    alert("Invalid image.");
						    options.complete(options.rdmid);
						}
						
						if(objData.state == "done") {
						   /* the view will return {'state':'done'} update all important css parts and clear the timer */
						   var bar = ($.browser.safari || $.browser.opera) ? $(options.progressBar, parent.document) : $(options.progressBar);
						   bar.css({width:'100%'});
						   $('#percents_'+options.rdmid).html('100%');
						   window.clearTimeout(options.timer);
						   options.complete(options.rdmid);
						}
					});
 
 
				$( "body:first" ).append( jFrame );
				jThis
				     .attr( "action", this.action )
					 .attr( "method", "post" )
					 .attr( "enctype", "multipart/form-data" )
					 .attr( "encoding", "multipart/form-data" )
					 .attr( "target", strName );
		});
	//});
  };

jQuery.uploadProgress = function(e, options) {
	
	jQuery.ajax({
		type: "GET",
		url: options.progressUrl,
		dataType: "json",
		beforeSend: function(xhr) {
			xhr.setRequestHeader("X-Progress-ID", options.uuid);
		},
		
		success: function(upload) {
		
			
			if (upload == null) 
			{
			     window.clearTimeout(options.timer);
			     return;
			}
		
			
		    switch(upload.state) {
		    
		        case 'uploading':
		    		upload.percents = Math.floor((upload.received / upload.size)*1000)/10;
		    		var bar = ($.browser.safari || $.browser.opera) ? $(options.progressBar, parent.document) : $(options.progressBar);
					bar.css({width: upload.percents+'%'});
			  		options.uploading(upload);
			  		break;
			  	
			  	case 'done':
			  		
			  	   	window.clearTimeout(options.timer);
					options.complete(options.rdmid);
					break;
									
				case 'error':
					window.clearTimeout(options.timer);
		    		options.error(upload);
		    		break;
		    	
		    	case 'nofile':
		    		window.clearTimeout(options.timer);
		    		options.error(upload);
		    		break;
		    }	
		}
	});
};

})(jQuery);
