/*********
* Javascript for file upload demo
* Copyright (C) Tomas Larsson 2006
* http://tomas.epineer.se/

* Licence:
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under this License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*/
function PeriodicalAjax(url, parameters, frequency, decay, onSuccess, onFailure, upload_progress_fails_limit, upload_no_progress_limit, upload_progress_timeout) {
	function createRequestObject() {
		var xhr;
		try {
			xhr = new XMLHttpRequest();
		}
		catch (e) {
			xhr = new ActiveXObject("Microsoft.XMLHTTP");
		}
		return xhr;
	}

	function send() {
		if(!stopped) {
			try{
				xhr.open('post', url, true);
				xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
				xhr.onreadystatechange = function() { self.onComplete(); };
				xhr.send(parameters);

				timeout_timer = setTimeout(function(){ xhr.abort();}, upload_progress_timeout);
			} catch (ex) {
				if (typeof log_error == 'function') log_error(ex);
			}
		}
	}

	this.stop = function() {
		stopped = true;
		clearTimeout(this.timer);
	}

	this.start = function() {
		upload_progress_fails_count = 0;
		upload_no_progress_count = 0;
		stopped = false;
		this.onTimerEvent();
	}

	this.onComplete = function() {
		if(this.stopped) return false;
		if ( xhr.readyState == 4) {

			clearTimeout(timeout_timer);

			if(xhr.status == 200) {
				upload_progress_fails_count = 0;
				if(xhr.responseText == lastResponse) {
					decay = decay * originalDecay;
				} else {
					decay = 1;
				}
				lastResponse = xhr.responseText;
				if(onSuccess instanceof Function) {
					onSuccess(xhr);
				}
				this.timer = setTimeout(function() { self.onTimerEvent(); }, decay * frequency * 1000);
			} else {
				upload_progress_fails_count++;
				if (xhr.status == 500 || upload_progress_fails_count >= upload_progress_fails_limit){
					if(onFailure instanceof Function) {
						onFailure(xhr);
					}
				} else {
					this.timer = setTimeout(function() { self.onTimerEvent(); }, decay * frequency * 1000);
				}
			}
		}
	}

	this.getResponse = function() {
		if(xhr.responseText) {
			return xhr.responseText;
		}
	}

	this.onTimerEvent = function() {
		send();
	}

	var timeout_timer;
	var fails_progress_count;
	var self = this;
	var stopped = false;
	var originalDecay = decay || 1.2;
	decay = originalDecay;
	var xhr = createRequestObject();
	var lastResponse = "";
	this.start();
}

function ProgressTracker(sid, options) {

	this.onSuccess = function(xhr) {
		try {
			if(parseInt(xhr.responseText) >= 100) {
				periodicalAjax.stop();
				if(options.progressBar && options.progressBar.style) {
					options.progressBar.style.width = "100%";
				}
				if(options.onComplete instanceof Function) {
					if (options.scope) {
						options.onComplete.call(options.scope);
					} else {
						options.onComplete();
					}
				}
			} else if(xhr.responseText && xhr.responseText == lastResponse) {
				upload_no_progress_count++;
				if (upload_no_progress_count >= upload_no_progress_limit){
					this.onFailure(xhr);
				}
			} else if(xhr.responseText && xhr.responseText != lastResponse) {
				if(options.onProgressChange instanceof Function) {
					if (options.scope) {
						options.onProgressChange.call(options.scope, xhr.responseText);
					} else {
						options.onProgressChange(xhr.responseText);
					}
				}
				if(options.progressBar && options.progressBar.style) {
					options.progressBar.style.width = parseInt(xhr.responseText) + "%";
				}
				lastResponse = xhr.responseText;
				upload_no_progress_count = 0;
			}

		} catch(e) {
			log_error('ProgressTracker: ' + e, '', '');
			options.onFailure(xhr.responseText);
		}
	}

	this.onFailure = function(xhr) {

		if(options.onFailure instanceof Function) {
			if (options.scope) {
				options.onFailure.call(options.scope, xhr.responseText, xhr.status);
			} else {
				options.onFailure(xhr.responseText, xhr.status);
			}
		} else {
			alert(xhr.responseText);
		}
		periodicalAjax.stop();
	}

	this.stop = function() {
		periodicalAjax.stop();
	}

	var upload_progress_fails_count = 0;
	var upload_no_progress_count = 0;
	var self = this;
	var lastResponse = -1;
	options = options || {};
	var url = '/upload/progress';
	var frequency = options.frequency || 0.5;
	var decay = options.decay || 2;
	var upload_progress_fails_limit = options.upload_progress_fails_limit || 5;
	var upload_no_progress_limit = options.upload_no_progress_limit || 5;
	var upload_progress_timeout = options.upload_progress_timeout || 10000;
	var periodicalAjax = new PeriodicalAjax(url, 'sid=' + sid, frequency, decay, function(request){self.onSuccess(request);},function(request){self.onFailure(request);}, upload_progress_fails_limit, upload_no_progress_limit, upload_progress_timeout);

	return periodicalAjax;
}

