/* Written by Dave Shanley <david.shanley@europe.mccann.com>
 * this javascript requires mootools, it can't be used without it.
 * This code is a complete reverse engineering of the lovely flickr uploading tool I saw,
 * I decided it was so cool, I built my own one - here it is.
*/
var CMS_UPLOAD_PREFIX = "";
var url = CMS_UPLOAD_PREFIX + '/admin/engine/uploadListener';
var CMS_GFX_PREFIX = CMS_UPLOAD_PREFIX + "/tcms/resources/gfx"

/* define timing */
var assetCounter = 0;
/* count our upload forms */


/* containers */
var uploadButtons = new Array();
var uploadPercentages = new Array();
var percentageSpinners = new Array();
var percentageBars = new Array();
var percentCompleteTexts = new Array();
var percentErrorMessages = new Array();
var uploadSpinners = new Array();
var uploadAssetForms = new Array();
var percentPixels = new Array();
var ajaxObjects = new Array();
var periodicalObjects = new Array();
var refreshObjects = new Array();
var buttonObjects = new Array();
/* upload chains */
var chainCompleted = new Array();
/* sliders */
var sliderObjects = new Array();
var sliderRemoveObjects = new Array();
var clickedArray = new Array();
var ignore = [];

var uploaders;
var slides = [];
/* create a new upload button class */
		var ButtonObj = new Class({
	 		options: {
	 			element: null,
	 			counter: 0,
	 			filename: null
	 		},
	 		uploadClick: function() {
	 			if(clickedArray[this.options.counter]==false&&!ignore[this.options.counter]) {
	 			var val = this.options.counter;
	 			uploadAssetForms[this.options.counter].setProperty('action',CMS_PREFIX + '/admin/engine/uploadAsset?fn=' + this.options.filename);
	 			percentageBars[this.options.counter].setStyle('border','1px solid black');
	 			percentCompleteTexts[this.options.counter].setHTML('Processing...');
	 			uploadSpinners[this.options.counter].setProperty('src',CMS_GFX_PREFIX + '/app/indicator_circle_ball.gif');
	 			percentErrorMessages[this.options.counter].setHTML("");
	 			sliderRemoveObjects[this.options.counter].options.effect.slideOut();	
	 			uploadPercentages[val].setStyle('display','block');
	 			uploadAssetForms[val].submit();
				this.options.filename = $('asset' + this.options.counter).getProperty('name');
	 			/* lets get ajaxy */
	 			var ajaxMe = new Ajax(url + "?fn=" + this.options.filename +"&listen="+ this.options.counter, { 
								method: 'get',
								onComplete: function(transport) {
									parseStatusJSON(transport);
								},
							});
				/* update our ajax object */			
	 			ajaxObjects[this.options.counter].options.ajax = ajaxMe;
	 			periodicalObjects[this.options.counter] = (function() { ajaxObjects[val].options.ajax.request() }).periodical(500);
	 			clickedArray[this.options.counter]=true;
	 			}
	 			
	 			/* if this form is being ignored (was removed! then skip onto the next one) */
	 			if(ignore[this.options.counter]) {
	 				invokeNextUploadInChain(this.options.counter);
	 			}
	 			
	 			
	 		},
	 		initialize: function(options){
    			this.setOptions(options);
    			this.options.element.addEvent('click',this.uploadClick.bind(this));
    		},
    		click: function() {
    			this.uploadClick();
    		},
    		
		}); 

var EffectObj = new Class({
	 		options: {
	 			element : null,
	 			effect: null
	 		},
	 		initialize: function(options){
    			this.setOptions(options);
    			this.options.effect = new Fx.Slide(this.options.element,{ duration: 1000 });
    		}
    	});


/* looptastic - add all the elements to each element containing array - allow for multiple uploads. */
function initializeUploaders() {
	var numUploaders = $ES("form").length-1;
	EffectObj.implement(new Options);
	for(x=0; x<numUploaders; x++) {
		uploadButtons[x] = $('uploadButton' + x);
		uploadPercentages[x] = $('uploadPercentage' + x);
		percentageSpinners[x] = $('percentageSpinner' + x);
		percentageBars[x] = $('percentageBar' + x);
		percentCompleteTexts[x] = $('percentCompleteText' + x);
		percentErrorMessages[x] = $('percentErrorMessage' + x);
		uploadSpinners[x] = $('uploadSpinner' + x);
		uploadAssetForms[x] = $('uploadAssetForm' + x);
		percentPixels[x] = $('percentPixel' + x);
		periodicalObjects[x] = null;
		chainCompleted[x]=false;
		clickedArray[x]=false;
		
		var slide1 = new EffectObj({ element: $('uploadPercentage' + x)});
		var slide2 = new EffectObj({ element: $('removeButton' + x)});
			
	
		
		/* sliding mooness */
		sliderObjects[x] = slide1 ;
		sliderRemoveObjects[x] = slide2;
		
		
		var AjaxObj = new Class({
		 	options: {
		 		val: 0,
		 		url: null,
		 		file: null,
		 		ajax: null
		 	},
		 	initialize: function(options){
     			this.setOptions(options);
     	}	
		});
		
		AjaxObj.implement(new Options);
		
		/* our ajax instance */
		ajaxObjects[x] = new AjaxObj({ val: x, url: null, filename: "none", ajax: "none" });
		
		var periodical = new Class({
		 	
		 	initialize: function(val,ajax){
     		this.ajax = ajax;
     		this.val = val;
     		this.dummy = $time() + $random(0, 100);
     	}
		}); 
		
		periodicalObjects[x] = null;
		/* populate all buttons */
		
			//sliderObjects[x].options.effect.hide();
			/* create new objects and attach events */
			ButtonObj.implement(new Options, new Events);
			var button = new ButtonObj({ element: uploadButtons[x], counter: x, filename: $('asset' + x).getProperty('name') });
			/* add change event */
			buttonObjects[x] = button;
	}
		
	
	
}
var clicked=0;

/* form adding goodness */
function addUploadForm(idOfForm) {
    var AssetUploads = $('assetUploads');
	var newId = idOfForm;
	var assetInput = $('assetInput');
	
	var newForm = new Element('form', {
		'method': 'post',
		'action': CMS_UPLOAD_PREFIX + '/admin/engine/uploadAsset?fn=asset' + newId,
		'target': 'hiddenframe' + newId,
		'id':'uploadAssetForm' + newId,
		'enctype':'multipart/form-data',
		'class':'upload'
	});
	

	var newFile = new Element('input', {
		'type': 'file',
		'name': 'uploadAssetInput',
		'id': 'assetInput',
		'class':'file hidden'
	});
	
	var newFileNameField = new Element('input', {
		'type': 'hidden',
		'name': 'asset' + newId,
		'id': 'asset' + newId,
		'value':assetInput.value
	});
	
	
	var newFrame = new Element('iframe', {
		'name': 'hiddenframe'  + newId,
		'src': CMS_UPLOAD_PREFIX + '/admin/engine/uploadListener',
		'id': 'hiddenframe'  + newId,
		'class': 'hiddenframe' 
	});
	
	var newUploadPercentage = new Element('div', {
		'id': 'uploadPercentage' + newId,
		'class': 'uploadPercentage'
	});
	
	var newPercentageSpinner = new Element('div', {
		'id': 'percentageSpinner' + newId,
		'class': 'percentageSpinner'
	});
	
	var newSpinner = new Element('img', {
		'src': CMS_GFX_PREFIX + '/app/indicator_circle_ball.gif',
		'alt': 'spinner',
		'width':' 16',
		'height':'16',
		'id':'uploadSpinner' + newId 
	});
	
	var newPercentageBar = new Element('div', {
		'id': 'percentageBar' + newId,
		'class': 'percentageBar'
	});
	
	var newPercentagePixel = new Element('img', {
		'src': CMS_GFX_PREFIX + '/app/percent-pixel.gif',
		'alt': 'completed',
		'width':' 0',
		'height':'15',
		'id':'percentPixel' + newId 
	});
	
	var newPercentCompleteText = new Element('div', {
		'id': 'percentCompleteText' + newId,
		'class': 'percentCompleteText'
	});
	
	var newPercentErrorMessage = new Element('div', {
		'id': 'percentErrorMessage' + newId,
		'class': 'percentErrorMessage'
	});
	
	var newUploadComplete = new Element('div', {
		'id': 'uploadComplete' + newId,
		'class': 'uploadComplete'
	});
	
	/* uploading button, super hot */
	var newButtonDiv = new Element('div', {
		'id': 'upload' + newId,
		'class':'hide'
	});
	
	var newUploadButton = new Element('a', {
		'id': 'uploadButton' + newId,
		'href':'#'
	});
	
	var mainContainer = $(AssetUploads).getElements('ul');  
	var container = new Element('li', {
		'id':'uploadListItem' + newId
	});
	
	container.injectInside(mainContainer[0]);
	
	var assetIconPreview = new Element('div', {
		'id': 'assetIconPreview' + newId,
		'class':'assetIconPreview'
	});
	
	/* default image types */
	var imageFileTypes = ["html","htm","jpeg", "jpg", "gif", "png", "css", "mov", "pdf",  "php", "ppt", "rm",  "swf", "txt", "wmv",  "doc", "xls",  "zip", "flv","sit","gz","tar","rtf","fla","pptx","avi"];
	var fileType = /([^\/\\]*[\/\\])*([^\/\\]+)\.(\w+)/.exec($('assetInput').value)[3].toLowerCase();
	
	if(imageFileTypes.indexOf(fileType) < 0){
		/* use file extention style */
		assetIconPreview.setProperty('class','default');
	} else {
		assetIconPreview.setProperty('class',fileType);
	}
	
	assetIconPreview.injectInside(newForm);
	
	// The file name.
	var fileName= new Element('em');
	
	var fileText = /([^\/\\]*[\/\\])*([^\/\\]+)/.exec($('assetInput').value)[2];
	var textLength = 36;
	if(fileText.length > (textLength+2))
	fileText = fileText.substr(0, textLength)+"...";
	fileName.setHTML(fileText);
	
	newForm.injectInside(container);
	
	/* move the selected upload from its current position into the new form */
	var clonedInput = assetInput.clone();
	clonedInput.addClass('hiddenFileInput');
	clonedInput.injectInside(newForm);
	newFile.addEvent('change',function() { addUploadForm(assetCounter++) });
	newFileNameField.injectInside(newForm);
	assetInput.replaceWith(newFile);
	newUploadButton.injectInside(newButtonDiv);
	newUploadButton.setHTML("Upload Single Asset!");
	newFrame.injectAfter(newForm);
	
	/* percentage bar stuff */
	newSpinner.injectInside(newPercentageSpinner);                                                                                               
	newPercentageSpinner.injectInside(newUploadPercentage);
	
	newPercentagePixel.injectInside(newPercentageBar);
	newPercentageBar.injectInside(newUploadPercentage);
	newPercentCompleteText.injectInside(newUploadPercentage);
	newPercentErrorMessage.injectInside(newUploadPercentage);
	newUploadPercentage.setStyle('display','none');
	newUploadPercentage.injectAfter(newForm);
	
	//newUploadComplete.injectAfter(newUploadPercentage);
	newUploadComplete.setHTML("Upload completed!");
	
	
	var uploadingLabel = new Element('div', {
		'id':'uploadListItemLabel' + newId,
		'class':'label'
	});
	
	/* input fields */
	var assetNameInput = new Element('input', {
		'id': 'assetName' + newId,
		'name':'assetName',
		'class':'input_text'
	});
	
	var assetPathInput = new Element('input', {
		'id': 'assetPath' + newId,
		'name':'assetPath',
		'class':'input_text'
	});
	
	
	assetNameInput.setProperty('value',fileText.substring(0,fileText.indexOf('.')));
	assetPathInput.setProperty('value',fileText);
	
	/* inject asset form stuff */
	fileName.injectInside(uploadingLabel);
	new Element('div', { 'class':'uploadInput' }).setHTML("Name: ").injectInside(newForm);
	assetNameInput.injectInside(newForm);
	new Element('br').injectInside(newForm);
	new Element('div', { 'class':'uploadInput' }).setHTML("File: ").injectInside(newForm);
	assetPathInput.injectInside(newForm);
	
	newButtonDiv.injectInside(uploadingLabel);
	
	
	
	var newRemoveButton = new Element('input', {
		'id': 'removeButton' + newId,
		'type':'button',
		'class':'buttonclass',
		'value':'cancel'
	});
	uploadingLabel.injectInside(container);
	newRemoveButton.injectInside(uploadingLabel);
	
	newRemoveButton.addEvent('click',(function() { removeUploadItem(newId,container); }));
	ignore[newId]=false;
	initializeUploaders();
	
}


/* remove an entire block from the tree */
function removeUploadItem(buttonId,container) {
	container.setStyle('display','none');
	ignore[buttonId]=true;
}

var doChainUploads = false; 

/* parse JSON object passed back by the uploading listener servlet */
function parseStatusJSON(jsonObj) {
	/* process JSON data */
	var loaderData = Json.evaluate(jsonObj);
	var bytes = loaderData.bytes;
	var percent = loaderData.percent;
	var total = loaderData.total;
	var pixelSize = loaderData.pixelsize;
	var kilobytes = loaderData.filesizekb;
	var megabytes = loaderData.filesizemb;
	var kilobytesTotal = loaderData.totalkb;
	var megabytesTotal = loaderData.totalmb;
	var val = loaderData.listening;
	
	/* check for error */
	var error = loaderData.error;
	var errorMessage = loaderData.errormessage;
 	var errorMessageFull = loaderData.errordescription;
	/* process data */
	if(error == "false") {
		//percentErrorMessage.setStyle('display','none');
    	/* process the pixel and percentages */
    	percentPixels[val].setProperty('width',pixelSize);
    	percentCompleteTexts[val].setHTML(percent + " (" + megabytes + " / " + megabytesTotal + ")");
    	/* chainingUploads start when we have at least half the previous upload completed */
    	if(pixelSize>125) {
    		if(doChainUploads) {
    			if(!chainCompleted[val]) {
    				chainCompleted[val]=true;
        			invokeNextUploadInChain(val);
        		}	
			}
    	}	
    	
    	/* check for completion */
    	if(pixelSize>249) {
        	/* change the spinner */
			uploadSpinners[val].setProperty('src',CMS_GFX_PREFIX + '/app/ok-small.png');
			$clear(periodicalObjects[val]); 
			if(ajaxObjects[val]) {
				ajaxObjects[val].options.ajax.cancel();
			}
			/* slide out! */
			sliderObjects[val].options.effect.toggle();
			$('uploadListItem' + val).setStyle('border','1px dotted #009900');
			$('uploadListItem' + val).setStyle('background','url(' + CMS_GFX_PREFIX + '/app/tick.gif) right bottom no-repeat');
			
		}
    } else {
    	/* change the border color on the percentage bar */
    	percentageBars[val].setStyle('border','1px solid red');
    	percentCompleteTexts[val].setHTML("Yikes! (" + errorMessage + ")");
    	uploadSpinners[val].setProperty('src',CMS_GFX_PREFIX + '/app/close-small.png');
    	percentErrorMessages[val].setHTML("<strong>Sorry, bit of a problem</strong><br/>" + errorMessageFull);
    	percentErrorMessages[val].setStyle('display','block');
	}
}

/* press the green button son! */
function activateUploadSystem() {
	uploadButtons = new Array();
	uploadPercentages = new Array();
	percentageSpinners = new Array();
	percentageBars = new Array();
	percentCompleteTexts = new Array();
	percentErrorMessages = new Array();
	uploadSpinners = new Array();
	uploadAssetForms = new Array();
	percentPixels = new Array();
	ajaxObjects = new Array();
	periodicalObjects = new Array();
	refreshObjects = new Array();
	buttonObjects = new Array();
	chainCompleted = new Array();
	sliderObjects = new Array();
	sliderRemoveObjects = new Array();
	clickedArray = new Array();
	ignore = [];
	assetCounter = 0;
	
	$('chainUpload').addEvent('click',chainUploads);
	$('assetInput').addEvent('change',function() { addUploadForm(assetCounter++) });
}

function invokeNextUploadInChain(buttonVal) {
	var buttonValue =++buttonVal;
	var button = buttonObjects[buttonValue];
	if(button) { 
		button.options.element.fireEvent('click');
	} else {
		/* display well done message */
		loadStatus('good job! looks like we got them added.');			

	}
}

function chainUploads(e) {
	new Event(e).stop(); 
	/* hide upload button */
	$('uploadButton').setStyle('display','none');
	doChainUploads=true;
	/* start the very first upload, the parser will fire the rest */
	buttonObjects[0].options.element.fireEvent('click');
}

