var FileUploader = {
	sid: null,
	form: null,
	iframe: null,
	statsCont: null,
	_lastDataUploaded: null,
	_stalled: 0,
	_cgi: 0,
	_proxied: 0,
	_proxiedStarted: 0,
	_proxiedElapsed: 0,
	_bodyLoaded: 0,
	_keepAliveInterval: null,

	setSessionId: function(sid) {
		this.sid = sid;
	},

	isProxied: function(f) {
		this._proxied = f?1:0;
	},

	isCGI: function(f) {
		this._cgi = f?1:0;
	},

	keepAlive: function() {
		sys.fireEvent('system:keep-alive');

	        if (window.sessExpAskInterval) {
			clearInterval(window.sessExpAskInterval);
			window.sessExpAskInterval = null;
		}

		if (window.sessExpLogoutTimeout) {
			clearTimeout(window.sessExpLogoutTimeout);
			window.sessExpLogoutTimeout = null;
		}
	},


	loadStats: function() {
		if (this._proxied || this._cgi) {
			var url = "/scripts/common.tags/fup/progress.cgi?X-Progress-ID="+this.sid;
		} else {
			var url = "/scripts/common.tags/fup/stat.php?s="+this.sid;
		}

		var _this = this;
		sysCommon.sendXMLHTTPRequest('GET', url, true, false, function(res) { _this.loadStatsCallback(res.responseText); });
	},

	loadStatsCallback: function(d) {
		var _dd = eval(d);
		if (!_dd) {
			setTimeout(function() {FileUploader.loadStats();}, 1000);
			return;
		}


		if ((FileUploader._proxied||FileUploader._cgi) && _dd.state) {
			var now = new Date();
			if (!FileUploader._proxiedStarted) {
				FileUploader._proxiedStarted = Math.round(now.getTime() / 1000);
			}
			FileUploader._proxiedElapsed = Math.round(now.getTime() / 1000) - FileUploader._proxiedStarted;

			switch (_dd.state) {
				case "done":
					return FileUploader.doFormSubmit();
				break;
				case "error":
					// alert("Error during file upload. Error status: "+_dd.status);
					return FileUploader.doFormSubmit();
				break;
				case "staring":
					setTimeout(function() {FileUploader.loadStats();}, 1000);
					return;
				break;
				case "uploading":
					var data = {};
					data.total = _dd.size;
					data.uploaded = _dd.received;
					data.rate = (FileUploader._proxiedElapsed ? _dd.received / FileUploader._proxiedElapsed : 0);
					data.elapsed = FileUploader._proxiedElapsed;
					data.remains = data.rate ? Math.ceil((_dd.size - _dd.received)/data.rate) : 0;

					if (_dd.size) {
						data.perc = Math.floor(_dd.received / _dd.size * 100);
					} else data.perc = 0;
				break;
			}
			
		} else {
			var data = _dd;
		}

		var eMin = Math.floor(data.elapsed / 60);
		var eSec = data.elapsed % 60;
		if (eMin < 10) eMin = '0'+eMin;
		if (eSec < 10) eSec = '0'+eSec;

		var rMin = Math.floor(data.remains / 60);
		var rSec = data.remains % 60;
		if (rMin < 10) rMin = '0'+rMin;
		if (rSec < 10) rSec = '0'+rSec;

		if (data.uploaded) {
			if (FileUploader._lastDataUploaded == data.uploaded) {
				FileUploader._stalled++;
			} else {
				FileUploader._lastDataUploaded = data.uploaded;
				FileUploader._stalled=0;
			}
		}



		FileUploader.statsCont.innerHTML = '\
		<table width="100%" cellpadding="2" cellspacing="2" class="uploadStatsTable">\
			<tr><td class="uploadStatsCapt" width="35%">Progress:</td><td width="65%"><div id="fupProgressBar" style="text-align:center;background-color:blue;color:yellow;font-weight:bold;width:0px;overflow:hidden;">'+data.perc+'%</div></td></tr>\
			<tr><td class="uploadStatsCapt">Transfer Rate:</td><td class="uploadStatsVal">'+(Math.round(data.rate/1024))+' kb/s</td></tr>\
			<tr><td class="uploadStatsCapt">Total:</td><td class="uploadStatsVal">'+(Math.round(data.total/1024))+' kb</td></tr>\
			<tr><td class="uploadStatsCapt">Transferred:</td><td class="uploadStatsVal">'+(Math.round(data.uploaded/1024))+' kb</td></tr>\
			<tr><td class="uploadStatsCapt">Time elapsed:</td><td class="uploadStatsVal">'+eMin+':'+eSec+'</td></tr>\
			<tr><td class="uploadStatsCapt">Time left:</td><td class="uploadStatsVal">'+(FileUploader._stalled >= 2 ? (data.perc >= 99 ? '<div>finalizing ...</div>' : '<div style="color:red;font-weight:bold;">stalled ...</div>') : rMin+':'+rSec)+'</td></tr>\
		</table>';

		if (FileUploader._stalled == 10 && data.perc < 99) {
			FileUploader._stalled = 0;
			alert('Uploading aborted. Please try again.');
			return FileUploader.onFormSubmit();
		}

		var x = document.getElementById('fupProgressBar');
		x.style.width = data.perc+'%';

		if (data.perc == 100) {
			FileUploader.doFormSubmit();
		} else {
			setTimeout(function() {FileUploader.loadStats();}, 1000);
		}
	},

	/* Method called when file trasnsfer is ready */
	doFormSubmit: function() {
		clearInterval(this._keepAliveInterval);
		// if nginx was involved, there will be transfer between nginx and apache
		if (this._proxied || this._cgi) {
			// start querying apache
			this._proxied = 0;
			this._cgi = 0;

			// wait a little to start the file transfer between nginx and apache
			setTimeout(function() {FileUploader.loadStats();}, 3000);

			// return. next time when progress will reach 100% form will submit
			return;
		}

		for (var i=0;i<this.form.elements.length;i++) {
			if (this.form.elements[i].type == 'file') {
				this.form.elements[i].value = '';
				this.form.elements[i].disabled = true;
			}
		}

		this.form.enctype = this.form._savedFormProps.enctype;
		this.form.action = this.form._savedFormProps.action;
		this.form.target = this.form._savedFormProps.target;
		this.form.submit();
	},


	/* Method called when users submits the form */
	onFormSubmit: function() {
		this.prepareGUI();

		for (var i=0;i<this.form.elements.length;i++) {
			if (this.form.elements[i].type == 'submit') {
				this.form.elements[i].disabled = true;
			}
		}

		var _this = this;
		this._keepAliveInterval = setInterval(function () { _this.keepAlive(); }, 60000);

		this.form.submit();
		this.loadStatsCallback({'perc':0,'total':0,'uploaded':0,'elapsed':0,'remains':"0",'rate':"0"});
	},

	onFileFieldChanged: function(form, fid) {
		FileUploader.captureForm(form);
	},


	bodyLoaded: function() {
		this._bodyLoaded = 1;
		if (this.pendingToCaptureForm) this.captureForm(this.pendingToCaptureForm);

	},	

	/* Redirects form submission into the iframe */
	captureForm: function(form) {
		if (!this._bodyLoaded) { this.pendingToCaptureForm = form; return; }
		if (this.form && this.form != form) this.releaseForm();
		this.form = form;

		if (!form._savedFormProps) {
			form._savedFormProps = new Array();
			form._savedFormProps.enctype = form.enctype;
			form._savedFormProps.action = form.action;
			form._savedFormProps.target = form.target;


			form.enctype = "multipart/form-data";


			if (this._cgi) {
				form.action = "/scripts/common.tags/fup/upload.php?sid="+FileUploader.sid+"&"+"X-Progress-ID="+FileUploader.sid;
			} else {
				form.action = "/scripts/common.tags/fup/upload.cgi?sid="+FileUploader.sid+"&"+(FileUploader._proxied?"X-Progress-ID="+FileUploader.sid:"");
			}
			form.target = "_if_fup";

			form.onsubmit = function() { FileUploader.onFormSubmit(); return false; }


			for (var i=0;i<form.elements.length;i++) {
				if (form.elements[i].type == 'submit') {
					var e = form.elements[i];
					if (!e._fup_captured) {
						sysCommon.addListener('click', FileUploader.onSubmitterClick, e);
						e._fup_captured = true;
					}
				}
			}


		}

	},

	onSubmitterClick: function(ev) {
		if (sysCommon.browser.msie) var e = window.event.srcElement; else var e = ev.target;
		if (e.form == FileUploader.form) {
			var f = false;
			for (var i=0;i<FileUploader.form.elements.length;i++) {
				if (FileUploader.form.elements[i].type == 'hidden' && FileUploader.form.elements[i].name == e.name) {
					f = true;
					break;
				}
			}
			if (!f) sysCommon.createInputElement(e.form, 'hidden', e.name).value = e.value;
		}
	},

	/* Restores form into initial state */
	releaseForm: function() {
		if (this.form._savedFormProps) {
			this.form.enctype = this.form._savedFormProps.enctype;
			this.form.action = this.form._savedFormProps.action;
			this.form.target = this.form._savedFormProps.target;
			this.form.onsubmit = null;
			this.form._savedFormProps = null;

			for (var i=0;i<this.form.elements.length;i++) {
				if (this.form.elements[i].type == 'submit') {
					this.form.elements[i].disabled = false;
				}
			}

			this.form = null;
		}
	},


	switchMode: function(fid, mode) {
		var fs = ['upload', 'server', 'url'];
		var e;
		for (var i=0;i<fs.length;i++) {
			e = document.getElementById('_fup_'+fs[i]+'_'+fid);
			if (e) e.style.display = (mode == fs[i] ? 'block' : 'none');
		}
	},





	/* Prepares fake iframe and interface for upload statistics display */
	prepareGUI: function() {
		if (!this.iframe) {
			this.iframe = (sysCommon.browser.msie?document.createElement('<IFRAME name="_if_fup" id="_if_fup">'):document.createElement('iframe'));
			this.iframe.name="_if_fup";
			this.iframe.id="_if_fup";
			this.iframe.style.border = "0px";
			this.iframe.style.height = "0px";
			this.iframe.style.width = "0px";
			this.iframe.style.padding = "0px";
			this.iframe.style.position = "absolute";
			this.iframe.style.visibility = "hidden";
			document.body.appendChild(this.iframe);
		}

		if (!this.statsCont) {
			this.fadeIn();
			var topDiv = document.getElementById('coolfader');
			
			this.statsCont = document.createElement('div');

			this.statsCont.style.position = 'fixed';
			this.statsCont.style.width = '300px';
			this.statsCont.style.height = '120px';
			this.statsCont.className = 'uploadStatsContainer';


			var screenMaxW;
			var screenMaxH;

			if (window.innerWidth) {
				screenMaxW = window.innerWidth;
				screenMaxH = window.innerHeight;
			} else if (document.documentElement && document.documentElement.clientWidth) {
				screenMaxH = document.documentElement.clientHeight;
				screenMaxW = document.documentElement.clientWidth;
			} else if (document.body) {
				screenMaxW = document.body.clientWidth;
				screenMaxH = document.body.clientHeigh;
			}
			
			this.statsCont.style.left = Math.round((screenMaxW - 300) / 2)+'px';
			this.statsCont.style.top = Math.round((screenMaxH - 120) / 2)+'px';
			
			this.isCentered = 0;

			this.statsCont.style.top = '300px';
			this.statsCont.style.backgroundColor = 'white';
			this.statsCont.style.zIndex = 1000;
			document.body.appendChild(this.statsCont);
			return;
		}

	},


	fadeIn: function() {
		var topDiv = document.getElementById('_fup_coolfader');

		if (!topDiv) {
			topDiv = document.createElement('div');
			topDiv.align='center';
			topDiv.setAttribute('id', '_fup_coolfader');
			topDiv.id = '_fup_coolfader';
			topDiv.style.position = 'absolute';
			topDiv.style.top = '0px';
			topDiv.style.left = '0px';

			/*
			if (window.innerHeight) {
				var screenMaxW = window.innerWidth;
				var screenMaxH = window.innerHeight;
			} else if (document.documentElement && document.documentElement.clientWidth) {
				var screenMaxH = document.documentElement.clientHeight;
				var screenMaxW = document.documentElement.clientWidth;
			} else if (document.body) {
				var screenMaxW = document.body.clientWidth;
				var screenMaxH = document.body.clientHeigh;
			}
			*/

			topDiv.style.width = document.body.scrollWidth + 'px';
			topDiv.style.height =document.body.scrollHeight + 'px';
			topDiv.style.backgroundColor = '#000';
			topDiv.style.opacity = '.25';
			topDiv.style.filter = 'alpha(opacity=25)';
			document.body.appendChild(topDiv);
		}

		topDiv.style.display = "";
	},

	fadeOut: function() {
		var topDiv = document.getElementById('_fup_coolfader');

		if (topDiv) {
			topDiv.style.display = "none";
		}

	}


}

//setup onload function
if (typeof window.addEventListener != 'undefined') {
	window.addEventListener('load', function() { FileUploader.bodyLoaded(); }, false);
} else if(typeof document.addEventListener != 'undefined') {
	document.addEventListener('load', function() { FileUploader.bodyLoaded(); }, false);
} else if(typeof window.attachEvent != 'undefined') {
	window.attachEvent('onload', function() { FileUploader.bodyLoaded(); });
} else {
	if (typeof window.onload == 'function') {
		var existing = onload;
		window.onload = function() {
			existing();
			FileUploader.bodyLoaded();
		};
	} else {
		window.onload = generic;
	}
}
