/**
 * File Uplaoder
 * 
 * Requried Variables
 * URL.FR.UPLOADR.UP : upload url
 * URL.FR.UPLOADER.STATUS : get status url
 */
 
function uploadStart(virtualForm, callbackFunc, viewContainer) {
	window.uploader = new FileUploader(virtualForm, callbackFunc, viewContainer);
	var func = uploader.start.bind(uploader);
	func();
}

function uploadComplete(files) {
	window.uploader.uploadComplete(files);
}

function uploadError(code, message) {
	var func = uploader.uploadError.bind(uploader);
	func(code, message);
}


var FileFormQueue = Class.create();
FileFormQueue.prototype = {
	initialize:function(fileList ){
		this.fileList = fileList;
		this.step = 0;
		this.total = fileList.size();
	},
	updateAndNext:function() {
		if(this.step >= this.fileList.size()) {
			this.step++
			return false;
		}
		return this.fileList[this.step++];
	},hasNext:function() {
		if(this.step < this.fileList.size()) {
			return true;
		}else {
			return false;
		}
	},getProcessPercent:function() {
		if(this.step <= 1) {
			return 0;
		}else {
			return Math.floor(((this.step-1) /this.total) * 100);
		}
	},getFileList:function() {
		return this.fileList;
	}
}

var FileUploader = Class.create();
FileUploader.prototype = {
	initialize:function(form, callbackFunc, container){
		this.form = $(form);
		this.callbackFunc = callbackFunc;
		this.container = container;
		
		//var files = $A($$('input[type="file"]'));
		var files = $A($$('form[enctype="multipart/form-data"]'));
		this.uploadQueue = new FileFormQueue(files);
		this.returnTargetId = null;
		this.upater = null;
		var rand_no = Math.random();
		rand_no = rand_no * 10000;
		this.job = '_job_'+rand_no;
		this.uploadList = new Array();
	}
	
	
	,start:function() {
		var func1 = this._startStatusCheck.bind(this);
		func1();
		this._fetch.bind(this)();
	},_startStatusCheck:function() {
		
		if($(this.container)) {
			$(this.container).innerHTML = "";
		}
		
		// $('submitButton').disabled = true;
	    var viewStatusFunc = this._viewStatus.bind(this);
	    this.updater = new PeriodicalExecuter(function() {
	    	viewStatusFunc();
			},0.3);
			
		this.updater.execute();
	},
	_uploadFile:function(fileElement) {

		/*
		if(!fileElement || !fileElement.value) {
			return false;
		}
		
		var did = false;
		this.uploadList.each(function(didForm) {
			if(did == fileElement) {
				did = true;
			}
		});
		if(did) {
			return false;
		}else {
			this.uploadList.push(fileElement);
		}
		*/
		var form = fileElement;
		var files = form.select('input[type="file"]');
		if(files.size() == 0) {
			return false;
		}
		
		var uploadHiddenFrameId = "_target_upload";
		var iframe = new Element('iframe', {id:'_target_upload', name:uploadHiddenFrameId,width:0, height:0}) ;
		
		
		this.returnTargetId = files[0].getAttribute("target");
		//this.returnTargetId = fileElement.getAttribute("target");
		var rand_no = Math.random();
		rand_no = rand_no * 10000;
		
		var newId = '_random_id_'+rand_no;
		
		//var form = fileElement.up('form');
		form.appendChild(iframe);
		form.action = URL.FR.UPLOADER.UP + '?job='+this.job;
		form.target = uploadHiddenFrameId;
		
		
		
		/*
		var form = new Element('form', {
			'id':newId,
			'method':'post', 
			'enctype':'multipart/form-data', 
			'target':uploadHiddenFrameId,
			'action':'${CONTEXT }/action/file/upload/result.do?job='+this.job});
		
		var upper = fileElement.up();
		*/
		var jobElement = new Element('input', {type:'hidden', id:'_job_'+rand_no, name:'job'});
		jobElement.value = this.job;
		// upper.update(form);
		form.appendChild(jobElement);
		
		// form.appendChild(fileElement);
		form.submit();
		return true;
	},
	uploadComplete:function(files) {
		files = $A(files);
		var returnTargetId = this.returnTargetId;
		if(files) {
			files.each(function(item) {
				$(returnTargetId).value = $(returnTargetId).value +item.key+";";
			});
		}
		this._fetch();
	},
	_fetch:function() {
		var fileElement = this.uploadQueue.updateAndNext();
		if(fileElement) {
			var callUpload = this._uploadFile(fileElement);
			if(!callUpload) {
				this._fetch();
			}
		}else {
			this._finish();
		}
	},
	uploadError:function(code, message) {
		if(this.updater && this.updater.stop) {
			this.updater.stop();
		}
		alert(code, message);
	},
	_viewStatus:function() {
		var totalPercentFunc = this.uploadQueue.getProcessPercent.bind(this.uploadQueue);
		var viewContainer = $(this.container);
		
				
		new Ajax.Request(
		URL.FR.UPLOADER.STATUS, {
			asynchronous:true, 
			parameters:{'job':this.job},
			method: 'POST', 
			onFailure: function(rsp) {
				alert(rsp);
				if(this.updater && this.updater.stop) {
					this.updater.stop();
				}
			}, 
			onComplete:function(rsp) {
				var text = rsp.responseText;
				var json = text.evalJSON();


				if(json.data.result == "true") {
					var status = json.data.status;
					var sumWidth = totalPercentFunc();
					status.sumWidth = sumWidth;
					var tpl = new Template(
						'<div class="prog-border"><div class="prog-bar" style="width: ' + '#{width}' + '%;">'+
							'#{complete}' + ' MB / '+ '#{total}' + ' MB ( '+'#{percent}'+'% )'+
						'</div></div>'+
						'<div class="prog-border"><div class="prog-bar" style="width: ' + '#{sumWidth}' + '%;"></div></div>'+
						'<table>'+
							'<tr><td class="st" width="250px;">'+'#{timeLeft}'+
							' (at ' + '#{speed}' + 'kb/sec)</td><td class="st">'+
							'</td></tr>'+
						'</table>'
						);
					var viewContainer = $$('.upload_container')[0];
					if(viewContainer) {
						viewContainer.update(tpl.evaluate(status));
					}
					
				}else {
					uploadError(json.data.err.code, json.data.err.message);
				}
			}
		});
	},
	_finish:function() {
		if(this.updater && this.updater.stop) {
			this.updater.stop();
			this._viewStatus();
		}
		if(this.callbackFunc) {
			var action = $(this.form).getAttribute("action");
			var generateForm = $(this.form).wrap('form', {id:'generate_form', action:action, method:'POST'});
			this.callbackFunc(generateForm, this.resetFunc.bind(this));
		}
	},resetFunc:function() {
		this.uploadQueue.getFileList().each(function(fileElement) {
			var targetField = fileElement.getAttribute("target");
			$(targetField).value = '';			
		});
		ScreenDirector.closeFullScreen();
	}
}