/*!
 * jQuery AXuploader
 * Alban Xhaferllari
 * albanx@gmail.com
 * Copyright 2010, AUTHORS.txt (http://www.albanx.com)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * 
 */

(function($)
{
    var settings = {
  	      'fileList': this,
  	      'uploadPath' : 'js/',
  	      'url':'upload.php',
  	      'data':'',
  	      'async':true,
  	      'maxFiles':9999,
  	      'allowedExtensions':'avi,mov,mp4,flv,swf,wmv,docerd',
  	      'uploadAllClass':'',
  	      'uploadAllText':'Upload all',
  	      'uploadClass':'',
  	      'uploadText':'Upload',
  	      'abortClass':'',
  	      'abortText':'Abort',
  	      'removeClass':'',
  	      'removeText':'X',
  	      'clearClass':'',
  	      'clearText':'Clear',
  	      'showSize':'Mb',
  	      'showProgress':'%',
  	      'success':function(msg) {},
  	      'finish':function(msg) {},
  	      'abort':function(e){ },
  	      'beforeUpload':function(){},
  	      'error':function(e){},
  	      'autoStart':false,
  	      'listClass':'',
  	      'showButtons':['','','','','',''],
  	      'uploadOn':false
  	    };
	var methods =
	{
		init : function(options)
		{

    	    return this.each(function() 
    	    {
    	    	
				if(options)
					$.extend(settings,options);
				
				var $this=$(this);//applied element
				$this.data('settings',settings).html('');
				$this.NUMFILES=0;
				$this.TOTALDONE=0;
				
				var uploadall=$('<input type="button" />').css('display',settings.showButtons[0]);
				var clearbutt=$('<input type="button" />').css('display',settings.showButtons[1]);
				var browse=$('<input type="file" name="ax-files[]" multiple="multiple" />');

				var filestoup=new Array();
				
				/********************test multiupload select html5 **************************/
				var input = document.createElement('input');
			    input.type = 'file'; 
			    var supportxhrupload=('multiple' in input &&  typeof File != "undefined" &&  typeof (new XMLHttpRequest()).upload != "undefined" );
			    //supportxhrupload=false;
			    /******************************************************************************/
			   
			    var mainform="";
			    if(!supportxhrupload)
			    	mainform=$('<div />').appendTo(this);
			    
			 	/****************table with the file list***********************************/
			    var tablefiles=$('<table />').addClass(settings.listClass)
    										.append('<tr style="display:'+settings.showButtons[5]+';">'+
										 	'<th>File</th>'+
										 	'<th>Size</th>'+
										 	'<th>Progress</th>'+
										 	'<th style="display:'+settings.showButtons[2]+';">Remove</th>'+
										 	'<th style="display:'+settings.showButtons[3]+';">Abort</th>'+
										 	'<th style="display:'+settings.showButtons[4]+';">Upload</th>'+
										 '</tr>').appendTo($this);
				/****************************************************************************/
				
				/******************upload all files button***********************************/
				uploadall.attr('disabled',true)
						  .addClass(settings.uploadAllClass)
						  .val(settings.uploadAllText)
						  .click(function(){
							  $this.TOTALDONE=0;
							  $this.find('input.ax-abort-up').attr('disabled',false);
							  $this.find('input.ax-up-file').trigger('click');
							  settings.beforeUpload();
							  $(this).attr('disabled',true);
							  clearbutt.attr('disabled',true);
						  });
				/**************************************************************************/
				
				/**************clear list of files button**********************************/
				clearbutt.attr('disabled',true)
						  .val(settings.clearText)
						  .addClass(settings.clearClass)
						  .click(function(){
							  $(this).attr('disabled',true);
							  uploadall.attr('disabled',true);
							  tablefiles.find('tr.ax-n-file').remove();
							  browse.val('').attr('disabled',false);
							  if(!supportxhrupload)
							  {
								  mainform.find('input[type=file][name="ax-files[]"]').attr('disabled',false);
								  mainform.find('form[target^="ax-n-frame"]').remove();
								  $this.find('iframe[name^="ax-n-frame"]').remove();
							  }
							  $this.NUMFILES=0;
						  });
				/************************************************************************/
				
							 
				/*********************browse file button*********************************/			
				browse.change(function(){
					   if(supportxhrupload)
					   {
						    uploadall.attr('disabled', this.files.length==0);
						    clearbutt.attr('disabled', this.files.length==0);
							for (var i = 0; i < this.files.length; i++) 
							{
							   	if($this.NUMFILES<settings.maxFiles)
							   	{
									$this.NUMFILES++;
									
									/******************1.tr for new file added********************/
									var newfile=$('<tr class="ax-n-file" />').appendTo(tablefiles);
									/***********************************************************/
									
									/********************2.file name*********************************/
									var filename=this.files[i].name;
									
									var url="";
									if(settings.data!="")
										settings.data="&"+settings.data;
									if(settings.url.indexOf('?')==-1)
										url=settings.url+'?ax-file-name='+encodeURIComponent(filename)+'&ax-upload-path='+encodeURIComponent(settings.uploadPath)+'&ax-allowed-ext='+encodeURIComponent(settings.allowedExtensions)+settings.data;									 
									else
										url=settings.url+'&ax-file-name='+encodeURIComponent(filename)+'&ax-upload-path='+encodeURIComponent(settings.uploadPath)+'&ax-allowed-ext='+encodeURIComponent(settings.allowedExtensions)+settings.data;									 

									//var filenametd=$('<td />').html(filename).appendTo(newfile);
									var filenametd=$('<input />').val(filename).attr('name', 'file').attr('type', 'hidden').appendTo(newfile);
									filestoup[i]=filename;
									/**********************************************************/

									/*******************3.file size*****************************/
									var filesize=0;
									switch(settings.showSize.toLowerCase())
									{
										case 'mb':
											filesize=(Math.round((this.files[i].size/(1024*1024))*10))/10;
											break;
										case 'kb':
											filesize=(Math.round((this.files[i].size/(1024))*10))/10;
											break;
										case 'gb':
											filesize=(Math.round((this.files[i].size/(1024*1024*1024))*10))/10;
											break;
										default:
											filesize=this.files[i].size;
									}
									var filesizetd=$('<td />').html(filesize+' '+settings.showSize).appendTo(newfile);
									/**************************************************************/
									
									/******************4.progress bar******************/
									var progress=$('<div style="display:none;" />');
									var progresstd=$('<td />').appendTo(newfile);
									if(settings.showProgress.toLowerCase()=='progressbar')
										progress=$('<div />').progressbar().appendTo(progresstd);
									else if(settings.showProgress=='%')
										progress=$('<div />').appendTo(progresstd);
									else
										progresstd.css('display','none');
									/***************************************************/
									
									/****************upload xmlhttp object*********************/
									 var xhr = new XMLHttpRequest();//xml object 
									/*********************************************************/														
									
									/**************5.remove button********************************/
									var removebut=$('<input type="button" />')//remove button
												  .data('ax-my-file',{_xhr:xhr,_this:$(this)})
												  .addClass(settings.removeClass)
												  .val(settings.removeText)
												  .click(function(){
													  var dat2=$(this).data('ax-my-file');
													  
													  dat2._xhr=null;
													  $this.NUMFILES--;
													  uploadall.attr('disabled', $this.NUMFILES==0);
													  clearbutt.attr('disabled', $this.NUMFILES==0);
													  dat2._this.attr('disabled',$this.NUMFILES>=settings.maxFiles);
													  $(this).parents('tr:first').remove();//remove tr list of file from table
												  });
									var removebuttd=$('<td style="display:'+settings.showButtons[2]+'"  />').append(removebut).appendTo(newfile);
									/**************************************************************/
									
									/***************6.Abort button****************************/
									var abort=$('<input type="button" />')
											  .addClass('ax-abort-up')
											  .addClass(settings.abortClass)
											  .val(settings.abortText)
											  .attr('disabled',true)
											  .data('ax-my-file',{_removebut:removebut,_xhr:xhr, _progress:progress })
											  .click(function(){
												  var dat=$(this).data('ax-my-file');
												  dat._removebut.attr('disabled',false);
												  $(this).attr('disabled',true);
												  dat._xhr.abort();
												  dat._progress.html('Aborted');
												 
											  });
									var aborttd=$('<td style="display:'+settings.showButtons[3]+'" />').append(abort).appendTo(newfile);
									/*********************************************************/
									
									/**********************7.upload the file button****************/
									var upsingle=$('<input type="button" />')
												 .addClass('ax-up-file')
												 .addClass(settings.uploadClass)
												 .val(settings.uploadText)
												 .data('ax-my-file',{_url:url,_abort:abort,_progress:progress, _removebut:removebut,_xhr:xhr,_filename:filename, _file:this.files[i] })
												 .click(function(){
													 settings.beforeUpload();
													 uploadall.attr('disabled', true);	    
													 clearbutt.attr('disabled', true);
													 var dat2=$(this).data('ax-my-file');
													 dat2._removebut.attr('disabled',true);
													 dat2._abort.attr('disabled',false);
													 dat2._xhr.onreadystatechange = function(){ 
														 if(dat2._xhr.readyState == 4 && dat2._xhr.status == 200) 
														 {
															 uploadall.attr('disabled', false);	    
															 clearbutt.attr('disabled', false);
															 dat2._removebut.attr('disabled',false);
															 dat2._abort.attr('disabled',true);
															 
															 settings.success(dat2._xhr.responseText);
															 $this.TOTALDONE++;
															 if($this.TOTALDONE==$this.NUMFILES)
															 {
																 settings.finish(filestoup,$this);
															 }
														 } 
													 };  
													 
													 dat2._xhr.upload.onload=function(){
														  if(settings.showProgress=='loader')
															  dat2._progress.progressbar("option", "value", 100);
														  else if(settings.showProgress=='%')
															  dat2._progress.html('100%');
													 }; 
													 
													 dat2._xhr.upload.onerror=function(e){ settings.error(e);	 };   
													 
													 dat2._xhr.upload.onabort=function(e){
														 uploadall.attr('disabled', false);	    
														 clearbutt.attr('disabled', false);
														 dat2._removebut.attr('disabled',false);
														 dat2._abort.attr('disabled',true);
														 dat2._progress.progressbar('destroy').html('Aborted');
														 settings.abort(e);
													 };  
													 
													 dat2._xhr.upload.onprogress=function(e){  
														 if (e.lengthComputable) 
														 {  
															 var perc = Math.round((e.loaded * 100) / e.total);  
															 if(settings.showProgress.toLowerCase()=='progressbar')
																 dat2._progress.progressbar("option", "value", perc);
															 else if(settings.showProgress=='%')
																 dat2._progress.html(perc+'%');
														 }  
													 }; 
													 dat2._xhr.open("POST", dat2._url,settings.async);  
													 dat2._xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
													 dat2._xhr.setRequestHeader("X-File-Name", encodeURIComponent(dat2._filename));
													 dat2._xhr.setRequestHeader("X-File-Size", dat2._file.fileSize);
													 dat2._xhr.setRequestHeader("Content-Type", "multipart/form-data");
													 dat2._xhr.send(dat2._file);
												 });
									var upsingletd=$('<td style="display:'+settings.showButtons[4]+'" />').append(upsingle).appendTo(newfile);
									/**************************************************************/
									if($this.NUMFILES>=settings.maxFiles)
								   		$(this).attr('disabled',true);
									
								} 
							}
					   }
					   else
					   {
						   	if($this.NUMFILES>=settings.maxFiles)
						   	{
						   		return;
						   	}
						   	$this.NUMFILES++;

						    uploadall.attr('disabled', $this.NUMFILES==0);
						    clearbutt.attr('disabled', $this.NUMFILES==0);
	
							var url="";
							if(settings.data!="")
								settings.data="&"+settings.data;
							if(settings.url.indexOf('?')==-1)
								url=settings.url+'?ax-upload-path='+encodeURIComponent(settings.uploadPath)+'&ax-allowed-ext='+encodeURIComponent(settings.allowedExtensions)+settings.data;									 
							else
								url=settings.url+'&ax-upload-path='+encodeURIComponent(settings.uploadPath)+'&ax-allowed-ext='+encodeURIComponent(settings.allowedExtensions)+settings.data;									 
							
							
							var form=$('<form method="POST" action="'+url+'" encType="multipart/form-data" />')
										.attr('target','ax-n-frame'+$this.NUMFILES)
										.append(this)//append this browse
										.css('display','none')
										.prependTo(mainform);
						    
							var iframe = $('<iframe src="javascript:false;" />')// src="javascript:false;" removes ie6 prompt on https
									.attr('name','ax-n-frame'+$this.NUMFILES)
									.css('display','none')
									.appendTo(mainform);
							/******************1.tr for new file added********************/
							var newfile=$('<tr class="ax-n-file" />').appendTo(tablefiles);
							/***********************************************************/
							
							/********************2.file name*********************************/
							var filename = $(this).val().replace(/^.*\\/, '');

							var filenametd=$('<td />').html(filename).appendTo(newfile);
							
							/**********************************************************/
							filestoup[$this.NUMFILES-1]=filename;

							/*******************3.file size*****************************/
							var filesize=0;
							/*switch(settings.showSize.toLowerCase())
							{
								case 'mb':
									filesize=(Math.round((this.files[i].size/(1024*1024))*10))/10;
									break;
								case 'kb':
									filesize=(Math.round((this.files[i].size/(1024))*10))/10;
									break;
								case 'gb':
									filesize=(Math.round((this.files[i].size/(1024*1024*1024))*10))/10;
									break;
								default:
									filesize=this.files[i].size;
							}*/
							var filesizetd=$('<td />').html(filesize+' '+settings.showSize).appendTo(newfile);
							/**************************************************************/
							
							/******************4.progress bar******************/
							var progresstd=$('<td />').appendTo(newfile);
							var progress=$('<div />').appendTo(progresstd);
							/***************************************************/
							
							/**************5.remove button********************************/
							var removebut=$('<input type="button" />')//remove button
										  .data('ax-my-file',{_input:$(this)})
										  .addClass(settings.removeClass)
										  .val(settings.removeText)
										  .click(function(){
											  $this.NUMFILES--;
											  var dat2=$(this).data('ax-my-file');
											  dat2._input.remove();
											  uploadall.attr('disabled', $this.NUMFILES==0);
											  clearbutt.attr('disabled', $this.NUMFILES==0);
											
											  $(this).parents('tr:first').remove();//remove tr list of file from table
										  });
							var removebuttd=$('<td style="display:'+settings.showButtons[2]+'" />').append(removebut).appendTo(newfile);
							/**************************************************************/						
							
							/***************6.Abort button****************************/
							var abort=$('<input type="button" />')
									  .addClass('ax-abort-up')
									  .addClass(settings.abortClass)
									  .val(settings.abortText)
									  .attr('disabled',true)
									  .data('ax-my-file',{ _removebut:removebut, _progress:progress, _iframe:iframe })
									  .click(function(){
										  var dat2=$(this).data('ax-my-file');
										  dat2._removebut.attr('disabled',false);
										  dat2._progress.html('Aborted');
										  dat2._iframe.attr('src','javascript:false;');
										  dat2._progress.html('');
										  $(this).attr('disabled',true);
									  });
							var aborttd=$('<td style="display:'+settings.showButtons[3]+'" />').append(abort).appendTo(newfile);
							/*********************************************************/
							
							/**********************7.upload the file button****************/
							var upsingle=$('<input type="button" />')
										 .addClass('ax-up-file')
										 .addClass(settings.uploadClass)
										 .val(settings.uploadText)
										 .data('ax-my-file',{_abort:abort,_form:form, _input:this,_progress:progress, _removebut:removebut,_filename:filename })
										 .click(function(){
											 var dat2=$(this).data('ax-my-file');
											 dat2._removebut.attr('disabled',true);
											 dat2._abort.attr('disabled',false);
											 dat2._progress.html('<img src="loader.gif" />');
											 clearbutt.attr('disabled',true);
											 uploadall.attr('disabled',true);
											 dat2._form.submit();
											 $this.TOTALDONE++;
											 

										 });
							var upsingletd=$('<td style="display:'+settings.showButtons[4]+'" />').append(upsingle).appendTo(newfile);
							/**************************************************************/
						 

							iframe.data('ax-my-file',{_progress:progress,_filesizetd:filesizetd,_abort:abort,_removebut:removebut,_upsingle:upsingle})
								.load(function(){
									var dat2=$(this).data('ax-my-file');
									dat2._abort.attr('disabled',true);
									dat2._upsingle.attr('disabled',false);
									dat2._removebut.attr('disabled',false);
									dat2._progress.html('');
									clearbutt.attr('disabled',false);
									uploadall.attr('disabled',false);

									if($this.TOTALDONE>0)
									{
										var fs=parseInt(this.contentWindow.document.getElementById('filesize').value);
										var fn=this.contentWindow.document.getElementById('filename').value;
										settings.success(fn);
										
										switch(settings.showSize.toLowerCase())
										{
											case 'mb':
												fs=(Math.round((fs/(1024*1024))*10))/10;
												break;
											case 'kb':
												fs=(Math.round((fs/(1024))*10))/10;
												break;
											case 'gb':
												fs=(Math.round((fs/(1024*1024*1024))*10))/10;
												break;
											default:
												fs=fs;
										}
										dat2._filesizetd.html(fs+settings.showSize);
									}
									if($this.TOTALDONE==$this.NUMFILES)
									{										 
										 settings.finish(filestoup,$this);
									}
								});
							
							$(this).clone(true).appendTo(mainform).val('').attr('disabled',$this.NUMFILES>=settings.maxFiles);
					   }
					   if(settings.autoStart && supportxhrupload)
							uploadall.trigger('click');

				   });
				
				if(settings.uploadOn!=false)
				{
					var bindto=false;
					if(typeof settings.uploadOn != 'function')
					{
						bindto=settings.uploadOn;
					}
					else
					{
						bindto=settings.uploadOn(this);
					}
					if(bindto)
					{
						$(bindto).unbind('click').click(function(){
							uploadall.trigger('click');
							if($this.NUMFILES<=0)
							{
								settings.finish(false,$this);
							}
						});
					}
				}
				if(supportxhrupload)
				{
					$(this).prepend(browse).prepend(uploadall).prepend(clearbutt);
				}
				else
				{
					$(browse).attr('multiple',false);
					mainform.prepend(browse).prepend(uploadall).prepend(clearbutt);
					$(this).prepend(mainform);
				}

    	    });
		},
		enable:function()
		{
			return this.each(function()
			{
				var $this = $(this);
				var setts=$this.data('settings');
				$this.find('input').attr('disabled',false);
				$this.find('input').attr('disabled',false);
			});
		},
		disable:function()
		{
			return this.each(function()
			{
				var $this = $(this);
				var settings=$this.data('settings');
				$this.find('input').attr('disabled',true);
				$this.find('input').attr('disabled',true);
			});
		},
		destroy : function()
		{
			return this.each(function()
			{
				var $this = $(this);
				$this.removeData('settings');
				$this.html('');
			});
		}
	};

	$.fn.axuploader = function(method, options)
	{
		if(methods[method])
		{
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		}
		else if(typeof method === 'object' || !method)
		{
			return methods.init.apply(this, arguments);
		}
		else
		{
			$.error('Method ' + method + ' does not exist on jQuery.axuploader');
		}
	};

})(jQuery);

