
/**************************************************
	JS/FLASH MULTI UPLOADER
	JORDAN WILSON 2009


	HTML EXAMPLE:

	<html xmlns="http://www.w3.org/1999/xhtml">
		<head>
			<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js"></script>
			<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.2/scriptaculous.js"></script>
			<script type="text/javascript" src="swfobject.js"></script>
			<script type="text/javascript" src="multi_uploader.js"></script>
			<script type="text/javascript">
				Event.observe(window, 'load', function() {
					var uploader01 = new multiuploader("uploader01");
					addUploader(uploader01);
	
					params = Array();
					params['isTest'] = true;
					params['maxSize'] = 1048576*2; // 2 MB
					params['bgColor'] = '#F0F0F0';
					params['fileTypes'] = 'Mp3 (*.mp3)---*.mp3';
					params['text'] = 'Files: Can only upload MP3 - 5 MB limit';

					var uploader02 = new multiuploader("uploader02", params);
					addUploader(uploader02);
				});
			</script>
			<link rel="stylesheet" href="multi_uploader.css"></link>
		</head>
		<body>
			<div id="uploader01"></div>
			<div id="uploader02"></div>
		</body>
	</html>


**************************************************/


var mUploaders = Array();								// TRACKS ALL MULTI-UPLOADERS ON PAGE

var mUpload_FileTypes = Array();						// DEFAULT FILE TYPES
 mUpload_FileTypes['all'] = '';
 mUpload_FileTypes['img'] = 'Images (*.jpg, *.jpeg, *.gif, *.png)---*.jpg;*.jpeg;*.gif;*.png';
 mUpload_FileTypes['txt'] = 'Text Files (*.txt, *.rtf)---*.txt;*.rtf';
 mUpload_FileTypes['doc'] = 'Documents (*.pdf, *.doc)---*.pdf;*.doc';
 mUpload_FileTypes['mp3'] = 'Mp3 (*.mp3)---*.mp3';
 // STRING MULITPLE TYPY LIST TOGETHER: mUpload_Params['fileTypes'] = mUpload_FileTypes['img'] + '|||' + mUpload_FileTypes['txt'];

var mUpload_Params =  Array();							// DEFAULT PARAMETERS
 mUpload_Params['text'] = 'Files';									// DISPLAY TEXT
 mUpload_Params['swfWd'] = '240';									// SWF OBJECT WIDTH
 mUpload_Params['swfHg'] = '25';									// SWF OBJECT HEIGHT
 mUpload_Params['fileTypes'] = mUpload_FileTypes['img'];
 mUpload_Params['swfPath'] = 'multi_uploader.swf'; 					// PATH TO THE SWF OBJECT (RELATIVE TO HTML)
 mUpload_Params['phpPath'] = 'uploader.php'							// PATH TO THE PHP UPLOAD FILE (RELATIVE TO HTML)
 mUpload_Params['isTest'] = false;									// IF THE SWF OBJECT IS IN TESTING MODE
 mUpload_Params['jsFunction'] = 'JS_MultiUploader';					// THE JS FUNCTION FOR THE FLASH OBJECT TO CALL
 mUpload_Params['bgColor'] = '#FFFFFF';								// DEFAULT BACKGROUND COLOR IS WHITE
 mUpload_Params['maxSize'] = (1048576*2);							// 2 MB - THE MAX FILE SIZE (CANNOT EXCEED THE PHP SETTING "upload_max_filesize")
 mUpload_Params['maxSize'] = (1048576*2);							// 2 MB - THE MAX FILE SIZE (CANNOT EXCEED THE PHP SETTING "upload_max_filesize")


// CREATE A LIST OF ALL THE UPLOADERS
addUploader = function(obj) {
	mUploaders.push(obj);
};


// CALLED BY FLASH OBJECTS
JS_MultiUploader = function(call) {

	var action = call[0];
	var caller_id = call[1];
	var params = (call[2] != undefined ? call[2] : Array('no params'));

	// BUTTON EVENTS
		// AFTER 'BROWSE' BUTTON, IF USER HAS SELECTED FILES
		onSelect = function(i) {
			mUploaders[i].add_FileItems(params); // params: ARRAY OF SELECTED FILES
		};
	
		// IF 'UPLOAD' BUTTON WAS PRESSED AFTER FILE SELECTION
		onUpload = function(i) {
			mUploaders[i].Start_Uploading();
		};
	
		// IF 'CLEAR ALL' BUTTON WAS PRESSED AFTER FILE SELECTION
		onClearAll = function(i) {
			mUploaders[i].clearAll_FilesItems();
		};
	
		// IF 'CANCEL' BUTTON WAS PRESSED DURING UPLOAD
		onCancel = function(i) {
			mUploaders[i].Stop_Uploading();
		};


	// UPLOADING EVETNS
		onOpen = function(i) {
			mUploaders[i].starting_FileItem(params); // params: FILE ID
		};
		onLoading = function(i) {
			mUploaders[i].loading_FileItem(params[0], params[1], params[2]); // 0: FILE ID, 1: BYTES LOADED, 2: BYTES TOTAL
		};
		onError = function(i) {
			mUploaders[i].message_FileItem(params[0], params[1]); // 0: FILE ID, 1: ERROR MESSAGE
		};
		onComplete = function(i) {
			mUploaders[i].complete_FileItem(params); // params: FILE ID
			/*if(mUploaders[i].Params['onComplete']) {
				mUploaders[i].Params['onComplete']();
			}*/
		};
		onResponse = function(i) {
			mUploaders[i].message_FileItem(params[0], params[1]); // 0: FILE ID, 1: RESPONSE FROM PHP
		};
		onFinish = function(i) {
			mUploaders[i].finished_Uploading();
		};


	// SEARCH FOR THIS UPLOADER
	for (var i = 0; i < mUploaders.length; i++) {
		if (mUploaders[i].id == caller_id) {
			switch (action) {
				// BUTTON EVENTS
				case 'onSelect': onSelect(i); break;
				case 'onUpload': onUpload(i); break;
				case 'onClearAll': onClearAll(i); break;
				case 'onCancel': onCancel(i); break;

				// UPLOADING EVENTS
				case 'onOpen': onOpen(i); break;
				case 'onLoading': onLoading(i); break;
				case 'onError': onError(i); break;
				case 'onComplete': onComplete(i); break;
				case 'onResponse': onResponse(i); break;
				case 'onFinish': onFinish(i); break;
			}

			// BEFORE THE UPLOAD
			// IS THERE ANYTHING THAT NEEDS TO POSTED ALONG WITH THE FILE
			if (action == 'onPosted') {
				var post = mUploaders[i].posting_FileItem(params); // params: FILE ID
				return post;
			}
		}
	}
};


// ICON BUTTON ACTION
Icons_MultiUploader = function(action, file_id) {

	// REMOVE FILE ITEM
	onRemove = function(i) {
		mUploaders[i].remove_FileItem(file_id);
	};

	// CANCEL FILE ITEM UPLOAD
	onCancel = function(i) {
		mUploaders[i].cancel_FileItem_Upload(file_id);
	};

	// ENABLE FILE ITEM UPLOAD
	onEnable = function(i) {
		mUploaders[i].enable_FileItem_Upload(file_id);
	};

	// SEARCH FOR THE UPLOADER CONTAINING THE LIST ITEM
	for (var i = 0; i < mUploaders.length; i++) {
		for (var j = 0; j < mUploaders[i].FileItems.length; j++) {
			if (mUploaders[i].FileItems[j][1] == file_id) {
				switch (action) {
					case 'remove': onRemove(i); break;
					case 'cancel': onCancel(i); break;
					case 'enable': onEnable(i); break;
				}
			}
		}
	}

};



/* THE MULTI-UPLOADER CLASS
**************************************************/
multiuploader = function(cont, p) {
	var This = this;
	this.id = cont;						// THE ID OF THE CURRENT CONTAINER
	this.FileItems = Array();			// EACH INDEX CONTAINS: [File Name, File ID]
	this.nofiles = '<li class="none">No Files Selected.</li>';


	// SETTINGS
		if (p == null) { p = Array(); }
		this.Params = Array();
		this.Params['form'] = (p['form'] != null) ? p['form'] : false;
		this.Params['text'] = (p['text'] != null) ? p['text'] : mUpload_Params['text'];
		this.Params['isTest'] = (p['isTest'] != null) ? p['isTest'] : mUpload_Params['isTest'];
		this.Params['phpPath'] = (p['phpPath'] != null) ? p['phpPath'] : mUpload_Params['phpPath'];
		this.Params['maxSize'] = (p['maxSize'] != null) ? p['maxSize'] : mUpload_Params['maxSize'];
		this.Params['fileTypes'] = (p['fileTypes'] != null) ? p['fileTypes'] : mUpload_Params['fileTypes'];
		this.Params['jsFunction'] = (p['jsFunction'] != null) ? p['jsFunction'] : mUpload_Params['jsFunction'];
		this.Params['bgColor'] = (p['bgColor'] != null) ? p['bgColor'] : mUpload_Params['bgColor'];
		this.Params['swfPath'] = (p['swfPath'] != null) ? p['swfPath'] : mUpload_Params['swfPath'];
		this.Params['swfWd'] = (p['swfWd'] != null) ? p['swfWd'] : mUpload_Params['swfWd'];
		this.Params['swfHg'] = (p['swfHg'] != null) ? p['swfHg'] : mUpload_Params['swfHg'];
		this.Params['onComplete'] = (p['onComplete'] != null) ? p['onComplete'] : null;
		this.Params['onResponse'] = (p['onResponse'] != null) ? p['onResponse'] : null;
		


	// BEFORE UPLOAD
		// POST DATA ALONG WITH THE FILE, RETURN 'false' TO FORCE A SKIP
		this.posting_FileItem = function(file_id) {

			// IF THERE IS A FUNCTION TO TARGET
			if (this.Params['form'] != false) {
				out = this.Params['form']('validate', file_id);

				// IF VALIDATING RETURNED AN ARRAY: 0: false, 1: MESSAGE
				if (out[0] == false) {
					$(file_id).className = 'attention';
					remove = '<a onclick="Icons_MultiUploader(\'remove\', \'' + file_id + '\')" title="File Uploaded">&nbsp;</a>';
					$(file_id).down('.icon').update(remove);
					$(file_id).down('.note').update(out[1]);
					$(file_id).down('.note').show();
					return false;

				// ELSE IT RETURNED THE POSTED DATA
				} else { return out; }

			// ELSE RETURN NOTHING AND DON'T POST ANYTHING ELSE
			} else { return ''; }
		};		


	// UPLOADING
		// START: SHOW ICONS AS 'ENABLE'
		this.Start_Uploading = function() {
			var i = 0;
			This.FileList_UL.childElements('li').each( function(elem) {
				file_id = elem.id;
				if (!elem.hasClassName('loading') && !elem.hasClassName('complete') && !elem.hasClassName('attention')) {
					elem.className = 'enable';
					cancel = '<a onclick="Icons_MultiUploader(\'cancel\', \'' + file_id + '\')" title="Skip File">&nbsp;</a>';
					elem.down('.icon').update(cancel);
				}
			});
		};

		// STOP: SWAP ICONS FOR 'REMOVE'
		this.Stop_Uploading = function() {
			var i = 0;
			This.FileList_UL.childElements('li').each( function(elem) {
				file_id = elem.id;
				if (!elem.hasClassName('complete') && !elem.hasClassName('attention')) {
					elem.className = 'remove';
					remove = '<a onclick="Icons_MultiUploader(\'remove\', \'' + file_id + '\')" title="Remove File">&nbsp;</a>';
					elem.down('.icon').update(remove);
				}
			});
		};

		// FINISHED: RESET ANY THAT WERE SKIPPED
		this.finished_Uploading = function() {
			var i = 0;
			This.FileList_UL.childElements('li').each( function(elem) {
				file_id = elem.id;
				if (elem.hasClassName('cancel')) {
					elem.className = 'remove';
					remove = '<a onclick="Icons_MultiUploader(\'remove\', \'' + file_id + '\')" title="Remove File">&nbsp;</a>';
					elem.down('.icon').update(remove);
				}
			});
		};


	// DURING UPLOAD
		// LOADING ICON
		this.starting_FileItem = function(file_id) {
			$(file_id).className = 'loading';
			loading = '<a title="File is Uploading">&nbsp;</a>';
			$(file_id).down('.icon').update(loading);
		};

		// UPDATE LOAD PERCENTAGE
		this.loading_FileItem = function(file_id, bLoaded, bTotal) {
			perc = Math.round((bLoaded / bTotal) * 100);
			$(file_id).down('.load').update(perc + '%');
		};

		// COMPLETE ICON
		this.complete_FileItem = function(file_id) {
			$(file_id).className = 'complete';
			complete = '<a onclick="Icons_MultiUploader(\'remove\', \'' + file_id + '\')" title="File Uploaded">&nbsp;</a>';
			$(file_id).down('.icon').update(complete);
			$(file_id).down('.load').update('100%');
		};

		// ERROR / RESPONSE FROM PHP UPLOAD
		this.message_FileItem = function(file_id, message) {
			
			if (message == 'ok') {
				$(file_id).down('.note').update('');
				$(file_id).down('.note').hide();
				
			// IF RESPONSE IS A NUMBER
			} else if (isFinite(message)) {
				$(file_id).down('.note').update('');
				$(file_id).down('.note').hide();
				if (This.Params['onResponse']) { This.Params['onResponse'](message); }
				
			} else {
				// IF RESPONSE BEGINS WITH 'success:'
				if (message.substr(0,8) == 'success:') {
					remove = '<a onclick="Icons_MultiUploader(\'remove\', \'' + file_id + '\')" title="File Uploaded">&nbsp;</a>';
					$(file_id).down('.note').update(message.substr(8));
				} else {
					$(file_id).className = 'attention';
					remove = '<a onclick="Icons_MultiUploader(\'remove\', \'' + file_id + '\')" title="File Uploaded">&nbsp;</a>';
					$(file_id).down('.note').update(message);
				}
				$(file_id).down('.icon').update(remove);
				$(file_id).down('.note').show();
			}
		};


	// CANCEL FILE ITEM UPLOAD
		// SHOW ICONS AS 'CANCEL'
		this.cancel_FileItem_Upload = function(file_id) {
			$(file_id).className = 'cancel';
			enable = '<a onclick="Icons_MultiUploader(\'enable\', \'' + file_id + '\')" title="Include File">&nbsp;</a>';
			$(file_id).down('.icon').update(enable);

			// UPDATE THE FLASH OBJECT AND HAVE IT SKIP THIS FILE
			swf = document.getElementById(This.SwfObject);
			swf.SendToAS('cancel', file_id);
		};


	// ENABLE FILE ITEM UPLOAD
		// SHOW ICONS AS 'ENABLE'
		this.enable_FileItem_Upload = function(file_id) {
			$(file_id).className = 'enable';
			cancel = '<a onclick="Icons_MultiUploader(\'cancel\', \'' + file_id + '\')" title="Skip File">&nbsp;</a>';
			$(file_id).down('.icon').update(cancel);

			// UPDATE THE FLASH OBJECT AND HAVE IT INCLUDE THIS FILE
			swf = document.getElementById(This.SwfObject);
			swf.SendToAS('enable', file_id);
		};


	// ADD FILE ITEMS
		this.add_FileItems = function(files) {
			for (i = 0; i < files.length; i++) {

				// SENT FROM SWF - 0: FILE NAME, 1: FILE ID, 2: FILE SIZE
				name = files[i][0];
				file_id = files[i][1];
				size = files[i][2];

				// INCREMENT THE ARRAY
				This.FileItems.push([name, file_id]);

				// CREATE AND ADD THE LIST ITEM
				if (this.FileList_UL) {
					// REMOVE 'NO ITEMS'
					if (This.FileList_UL.down().classNames() == 'none') { This.FileList_UL.down().remove(); };

					// CHECK FILE SIZE
					if (size < this.Params['maxSize']) {
						
						// CREATE THE HTML FOR THE <LI>
						li = '<li id="' + file_id + '" class="remove">';
							li += '<div class="name">' + name + '</div>';
							li += '<div class="load"> - </div>';
							li += '<div class="icon">';
								li += '<a onclick="Icons_MultiUploader(\'remove\', \'' + file_id + '\')" title="Remove File">&nbsp;</a>';
							li += '</div>';

							// ADD ANY INPUT DATA IF THERE IS SOME TO PASS ALONG WITH THE FILE
							if (this.Params['form'] != false) { li += '<div class="post" >' + this.Params['form']('input') + '</div>'; }

							li += '<div class="note" style="display:none" ></div>';
						li += '</li>';

					// IF IT'S TO LARGE YOU CAN ONLY REMOVE IT
					} else {
						li = '<li id="' + file_id + '" class="attention">';
							li += '<div class="name">' + name + '</div>';
							li += '<div class="load"> - </div>';
							li += '<div class="icon">';
								li += '<a onclick="Icons_MultiUploader(\'remove\', \'' + file_id + '\')" title="Remove File">&nbsp;</a>';
							li += '</div>';
							li += '<div class="note" style="display:none" >File is too Large.</div>';
						li += '</li>';
					}
					This.FileList_UL.insert(li);
					if (size > this.Params['maxSize']) { $(file_id).down('.note').show(); }
				}
			}

		};


	// CLEAR ALL FILE ITEMS
		this.clearAll_FilesItems = function() {
			if (confirm('Are you sure you want to remove all the files from the list below?')) {
				// FADE OUT THE 'ul', UPDATE IT WITH THE 'NO ITEMS' DIV, THEN SHOW IT
				new Effect.Fade(This.FileList_UL, {duration: 0.5, afterFinish: function() {
					This.FileList_UL.update(This.nofiles);
					This.FileList_UL.show();
				}});

				// CLEAR THE ARRAY, THEN HAVE THE FLASH OBJECT CLEAR ITS ARRAY
				This.FileItems = Array();
				swf = document.getElementById(This.SwfObject);
				swf.SendToAS('clear all');
			}
		};


	// REMOVE FILE ITEMS
		this.remove_FileItem = function(file_id) {
			if (confirm('Are you sure you want to remove this file from the list below?')) {
				// FADE OUT THE ITEM
				new Effect.Fade(file_id, {duration: 0.5, afterFinish: function() {
					// REMOVE IT FROM THE LIST AND THE ARRAY
					$(file_id).remove();

					// SEARCH FOR THE FILE IN THE ARRAY AND REMOVE IT
					for (i = 0; i < This.FileItems.length; i++) {
						if (This.FileItems[i][1] == file_id) { index = i; }
					}
					This.FileItems.splice(index, 1);

					// IF THE ARRAY IS BLANK, ADD THE 'NO ITEMS' DIV
					if (This.FileItems.length == 0) { This.FileList_UL.update(This.nofiles); }

					// UPDATE THE FLASH OBJECT AND HAVE IT REMOVE THIS FILE
					swf = document.getElementById(This.SwfObject);
					swf.SendToAS('remove', file_id);
				}});
			}
		};


	// EMBED THE FLASH OBJECT
		this.embedFlashObject = function(swfobj_id) {
			flashvars = {};
			flashvars.id = cont;
			 flashvars.url = this.Params['phpPath'];
			 flashvars.test = this.Params['isTest'];
			 flashvars.size = this.Params['maxSize'];
			 flashvars.type = this.Params['fileTypes'];
			 flashvars.func = this.Params['jsFunction'];
			params = {};
			 params.quality = "high";
			 params.bgcolor = this.Params['bgColor'];
			attributes = {};
			 attributes.id = swfobj_id;
			 attributes.name = swfobj_id;
			swfobject.embedSWF(this.Params['swfPath'], swfobj_id, this.Params['swfWd'], this.Params['swfHg'], "9.0.0", false, flashvars, params, attributes);
		};


	// UPDATE THE HTML CONTAINER
		// HTML OBJECTS
		this.div_SwfObject = '<div class="uploader-swfobject-cont"><div id="mUploaderSWF_' + Math.round((Math.random() * 8999) + 1000) + '" class="uploader-swfobject"><p style="color:#990000"><img src="/admin/includes/multi_uploader/icons/attention.png" align="absmiddle" /> The File Uploader did not initiate. Try updating your <a href="http://www.adobe.com/products/flashplayer/" target="_blank" style="color:#990000">Adobe Flash Player</a>.<p></div></div>';
		this.div_FileList = '<div class="file-list"><div class="list-head">' + this.Params['text'] + '</div><ul class="files"></ul></div>';
		$(cont).update(this.div_FileList + this.div_SwfObject);

		// THE FLASH OBJECTS: BROWSE, UPLOAD, CLEAR ALL, AND CANCEL BUTTONS
		this.SwfObject = $(cont).down('.uploader-swfobject').id;
		if (this.SwfObject) { this.embedFlashObject(this.SwfObject); }

		// THE ul TO ADD THE li ITEMS TO
		this.FileList_UL = $(cont).down('.file-list ul');
		if (this.FileList_UL) { this.FileList_UL.update(this.nofiles); }
};



/* END OF FILE
**************************************************/

