/*
 * Uploader 1.0b, jQuery plugin
 * 
 * Copyright(c) 2011, Samuel De Backer
 * http://www.typi.be
 *	
 * Uploader gives progress bars to html5 input file 
 * with multiple and accept attributes.
 * Thanks to jQuery community 
 * Licenced under the MIT Licence
 */
(function ($){
	
	var settings = {
		directUpload: true,
		maxSize: 8000000,
		dropZone: '',
		url: '',
		maxFiles: '',
		removable: true,
		initialize: function () { },
		allComplete: function (numberOfFiles) { }
	};
	var fileInput;
	var pickFiles;
	var fileSubmit;
	var fileList;
	var uploader;
	var dropZone;
	var nbOfFilesToUpload;
	var numberOfFiles;
	var bytesUploaded;
	var bytesTotal;
	var accept;
	var files;

	var methods = {
		init: function (options) {

			return this.each( function () {
				
				if (options) {
					$.extend(settings, options);
				}
				
				settings.initialize.call(this);
				
				fileInput = $(this);
				fileInput.parent().after($('<ul id="fileList"></ul>'));
				fileInput.css({'visibility':'hidden','position':'absolute'});
				fileInput.before('<a class="bouton lightGrey medium" id="pickFiles" href="#">' + 'Choose files' + '</a>');
				pickFiles = $('#pickFiles');
				fileSubmit = $('#fileSubmit');
				fileSubmit.prop('disabled',true);
				fileList = $('#fileList');
				uploader = fileInput.closest('form');
				dropZone = $('#' + settings.dropZone);
				nbOfFilesToUpload = 0;
				numberOfFiles = 0;
				bytesUploaded = 0;
				bytesTotal = 0;
				acceptAttr = fileInput.attr('accept');
				if (!acceptAttr) {
					acceptAttr = 'text/*';
				}
				acceptArray = acceptAttr.split(',');
				files = new Object();
				if (settings.url == '') {
					settings.url = uploader.attr('action');
				}
				pickFiles.click(function (e){
					fileInput.trigger('click');
					e.preventDefault();
				});
				uploader.submit(function (e){
					if (settings.directUpload === false) {
						if (files.length) {
							$('.progressBar').show();
							for (i=0; i < files.length; i += 1) {
								methods.uploadFile(files[i], i);
							}
						} else {
							alert('No file found');
						}
						e.preventDefault();
					}
				});
				if (dropZone.length) {
					dropZone.bind('dragover', function () { $(this).addClass('focus'); return false; })
						.bind("dragleave",function () { $(this).removeClass('focus'); return false; })
						.bind("dragend",function () { $(this).removeClass('focus'); return false; })
						.bind("drop", function (event) {
							files = new Object(); // remettre la liste des fichiers à zéro
							$(this).removeClass("focus");
							event.stopPropagation();
							event.preventDefault();
							for (var prop in event.originalEvent.dataTransfer.files) {
								files[prop] = event.originalEvent.dataTransfer.files[prop];
							}
							if (event.originalEvent.dataTransfer.files.length > 0) {
								methods.handleFiles();
							};
						}
					);
				}

				methods.show();
				
			});
			
		},
		show: function () {

			fileInput.change(function (){
				files = new Object(); // remettre l'objet à zéro
				for (var prop in this.files) {
					if (!files.hasOwnProperty(prop)) {
								files[prop] = this.files[prop];
					}
				}
				methods.handleFiles();
			});

		},
		hide: function () {
			
		},
		update: function (content) {
			
		},
		recreateInputFile: function () {
			
		},
		handleFiles: function () {
			
			if (settings.maxFiles != '' && files.length > settings.maxFiles) {
				alert('Max ' + settings.maxFiles + ' files at a time');
				return;
			}
	
			pickFiles.prop('disabled',true);
			fileSubmit.prop('disabled',false);
			fileList.find('li').remove();
	
			var i,l;
			for( i = 0, l = files.length; i < l; i += 1){
				
				var checkType = false;
				$(acceptArray).each(function (index) {
					if (files[i].type.match( new RegExp( $.trim(acceptArray[index]) ) )) {
						checkType = true;
					}
				});
				
				var checkSize = (files[i].size < 8000000) ? true : false ;
		
				if ( checkType && checkSize) {
					var fileSize = 0;
					if (files[i].size > 1024 * 1024) {
						fileSize = (Math.round(files[i].size * 100 / (1024 * 1024)) / 100).toString() + ' MB';
					} else {
						fileSize = (Math.round(files[i].size * 100 / 1024) / 100).toString() + ' KB';
					}
					nbOfFilesToUpload += 1;
					fileList.append('<li id="file-' + i + '" class="fileContainer"><div class="txt">' + files[i].fileName + ' (' + fileSize + ')</div><b class="percent"></b><span class="progressBar"></span></li>');
					if (settings.removable === true) {
						fileList.children('li').append('<a class="removeFile">×</a>');
					}
					$('.progressBar').hide();
					if (settings.directUpload === true) {
						methods.uploadFile(files[i], i);
					}
				} else {
					if (!checkType) {
						alert(files[i].name + ' : file type (' + files[i].type + ') not accepted');
					} else if (!checkSize) {
						alert(files[i].name + ' : too big');
					};
					delete files[i];
				}
			}
			//console.log(files);
			if (settings.removable === true) {
				methods.enableRemoveButton();
			}
		},
		enableRemoveButton: function () {
			$('.removeFile').each(function (index) {
				$(this).bind('click', function (){
					$(this).parent().slideUp(100);
					delete files[index];
				});
			});
		},
		uploadFile: function ( file, i ) {
			if (settings.removable === true) {
				$('.removeFile').remove();
			}
			var fd = new FormData();
			uploader.find('input:not(:file):not(:submit)').each(function (index) {
				fd.append(this.name, this.value);
			});
			fd.append("file[]", file);
			// var fd = document.getElementById('uploader').getFormData();
				
			var xhr = new XMLHttpRequest();
				
			xhr.upload.addEventListener("progress", function (event) {
				var percentComplete = Math.round(event.loaded * 100 / event.total);
				if (event.lengthComputable) {
					var fichier = $('#fileList li:eq(' + i + ')');
					fichier.find('.progressBar').css({'width':(percentComplete * 3.9).toString() + 'px'});
					fichier.find('.percent').html(percentComplete.toString() + ' %');
					if (percentComplete === 100) {
						$('#fileList li:eq(' + i + ')').addClass('uploaded');
					}
				} else {
					// No data to calculate on
				}
			}, false);
				
			xhr.addEventListener("load", methods.uploadComplete, false);
			xhr.addEventListener("error", methods.uploadFailed, false);
			xhr.addEventListener("abort", methods.uploadCanceled, false);
			xhr.open("POST", settings.url, true);
			xhr.setRequestHeader("Cache-Control", "no-cache");
			xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
			xhr.send(fd);

			// var data = uploader.serialize();
			// $.ajax({
			// 	type: 'POST',
			// 	url: settings.url,
			// 	data: data,
			// 	beforeSend: function (xhr)
			// 	{
			// 		//Upload progress
			// 		var xhr = new XMLHttpRequest();
			// 		xhr.upload.addEventListener("progress", function (event){
			// 			var percentComplete = Math.round(event.loaded * 100 / event.total);
			// 			if (event.lengthComputable) {
			// 				var fichier = $('#fileList li:eq(' + i + ')');
			// 				fichier.find('.progressBar').css({'width':(percentComplete * 3.9).toString() + 'px'});
			// 				fichier.find('.percent').html(percentComplete.toString() + ' %');
			// 				if (percentComplete === 100) {
			// 					$('#fileList li:eq(' + i + ')').addClass('uploaded');
			// 				}
			// 			} else {
			// 				// No data to calculate on
			// 			}
			// 		}, false);
			// 		xhr.addEventListener("load", methods.uploadComplete, false);
			// 		xhr.addEventListener("error", methods.uploadFailed, false);
			// 		xhr.addEventListener("abort", methods.uploadCanceled, false);
			// 	},
			// 	success: function (data){
			// 		alert('ok');
			// 		//Do something success-ish
			// 	}
			// });
	
		},
		uploadComplete: function () {
			numberOfFiles += 1;
			if (numberOfFiles === nbOfFilesToUpload) {
				settings.allComplete.call(this, numberOfFiles);
				fileInput.replaceWith(fileInput.clone());
				fileInput = $('#fileInput');
				files = new Object();
				fileList.find('li').remove();
				methods.show();
				numberOfFiles = 0;
				nbOfFilesToUpload = 0;
			};
		},
		uploadFailed: function () {
			alert("An error occurred while uploading the file.");	
		},
		uploadCanceled: function () {
			alert("The upload has been canceled by the user or the browser dropped the connection.");	
		}
		
	};
	
	$.fn.uploader = function (method) { // HTML5 file api infos: http://www.matlus.com/html5-file-upload-with-progress/	
		
		// Method calling logic
		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.uploader');
		}
		
	};
})( jQuery );
