//-------------------------------------------------------------
// © Michal Michna - 22.4.2009 - 1.0
//-------------------------------------------------------------

var prog;

function ProgressBar(div_element){
	// promena odkazujici na DOM objekt realizujici progressbar
	this.element = div_element;	
	//.........................................................
	this.visibility = true;				// viditelnost
	this.units = "px";
	this.width = "400"+this.units;		// sirka
	this.height = "30"+this.units;		// vyska
	//.........................................................
	this.limiter_size = "5px";			// osazeni jednotlivych bloku
	this.status = "Wait";				// status "Loading/Wait/Done..."
	this.info = "";						// co se nahrava
	this.animation = "&nbsp;.....";		// pole animace
	this.animation_interval = 500;		// interval rychlosti animace
	//.........................................................
	this.position_mark = 0;				// aktualni pozice progress baru
	this.set_mark = 0;					// nastavena pozice progressbaru
	this.old_set_mark = 0;				// puvodni nastavena pozice progressbaru
	this.speed_mark = 0;				// rychlost pohybu progressbaru
	this.akceleration_mark = 1;			// zrychleni pohybu progressbaru
	this.mark_reflesh_time = 40;		// aktualizace pozice kazdych xx ms
	this.change_interval = true;		// nastavi se na tru v pripade ze
										// se zmenil rozsah
	this.middle_interval = 0;			// stred intervalu 
	this.tasks = new Array();			// pole zpracovavanych uloh
	this.switch_task_limit = 0;			// limit kdy ma byt zobrazena dalsi uloha
	//.........................................................
	this.done_wait = 100;
	
	div_element.innerHTML = "<strong>" +
		"<span>"+this.status+"</span>" +
		"<span>"+this.info+"</span>" +
		"<span>"+this.animation+"</span>" +
		"<span>"+(this.position_mark*100)+"</span>%</strong>";
	
	var parts = this.element.getElementsByTagName("span");
	
	this.status_element = parts.item(0); 
	this.info_element = parts.item(1);
	this.animation_element = parts.item(2);
	this.progress_status = parts.item(3);
	
	for(var part = 0; part<parts.length; part++){
		parts.item(part).style.padding = this.limiter_size;
	}
	
	this.element.style.width = this.width;
	this.element.style.height = this.height;
	this.element.style.lineHeight = this.height;
	this.element.style.position = "relative";
	this.element.style.top = "250px";
	this.element.style.margin = "auto";
	this.element.style.textAlign = "center";
	this.element.style.border = "1px gray solid";
	this.element.style.background = "url('http://jitom.com/core/img/progress_bar.jpg') no-repeat white "+"-"+this.width+" 0";	
	this.animateProgress();
}
// vrati sirku progressbaru
ProgressBar.prototype.getWidth = function () {
	return this.element.style.width;
};
// nastavi sirku progressbaru
ProgressBar.prototype.setWidth = function (value){
	this.element.style.width = value+this.units;
};
// zmeni obsah pole status
ProgressBar.prototype.changeStatus = function (status){
	this.status_element.innerHTML = status;
};
// nastavi ukazatel progressbaru na zvolenou hodnotu
ProgressBar.prototype.progressBarValue = function (value) {
	var val = parseFloat(value);
	// v rozsahu 0 az 1 vcetne
	if(val > 1) val = 1;
	else if(val < 0) val = 0;
	
	// posunuti pozadi s ukazatelem prubehu
	var patt = new RegExp(/(-?\d*)..\s-?\d*..$/);
	res = patt.exec(this.element.style.background);
	width = this.width.match(/(\d*)../,"m");
	var shift = parseInt(-width[1]+val*parseInt(width[1]));
	this.element.style.background = this.element.style.background.replace(/(-?\d*)(..\s-?\d*..$)/,shift+"$2");
	this.progress_status.innerHTML = Math.round(val * 100);

};
// nastavi soucasnou poyici progressbaru
ProgressBar.prototype.currentMarkValue = function (value){
	var val = parseFloat(value);
	
	// v rozsahu 0 az 1 vcetne
	if(val > 1) val = 1;
	else if(val < 0) val = 0;

	this.position_mark = val;
	this.progressBarValue(val);

};
ProgressBar.prototype.addTask = function (name,value){
	var task = new Array(name, value);
	this.tasks.push(task);
	this.stopMarkValue(this.set_mark+value);
};

// nastavi koncovou hodnotu pro ukazetel progressbaru
ProgressBar.prototype.stopMarkValue = function (value){
	var val = parseFloat(value);
	// v rozsahu 0 az 1 vcetne
	if(val >= 0 && val <= 1){
		this.old_set_mark = this.set_mark;
		this.set_mark = val;
		this.change_interval = true;
	}
};
// skryje progressbar
ProgressBar.prototype.hide = function (){
	this.element.style.display = "none";
	this.visibility = false;
};
// ukaze progressbar
ProgressBar.prototype.show = function (){
	this.element.style.display = "block";
	this.visibility = true;
};
// animace pohybu progressbaru
ProgressBar.prototype.reflesh = function (){
	var thisProgBar = this;
	// pokud je pozice progresbaru <1 - akce neni dokoncena
	if(this.position_mark<1 && this.set_mark+0.01<1){
		// aktualni pozice progressbaru je mensi nez koncova nastavena
		if(this.position_mark < this.set_mark){
			// pokud se menil interval, je nutne prepocitat nove stredy pro zrychleni, zpomaleni prubehu
			if(this.change_interval){
				// pokud je ukazatel prubehu pred puvodnim stredem
				if(this.middle_interval > this.position_mark){
					// stred intervalu(puvodni] se pouze posune na stred noveho intervalu
					this.middle_interval = this.set_mark/2;
				}
				// pokud je ukazatel za puvodnim stredem
				else {
					// spocita se rozdil aktualni polohy a polohy zastaveni
					var shift = this.old_set_mark - this.position_mark;
					// novy stred se pak spocita tak, ze od aktualni pozice se odecte rozdil do zastaveni
					// z minule pozice, pak se spocita stred (noveho useku) a pricte se k aktualni pozici
					this.middle_interval = this.position_mark + (this.set_mark - (this.position_mark - shift)) / 2;
				}
				// indikator zmeny intervalu se nastavi na false
				this.change_interval = false;
			}
			// pokud je ukazatel pred stredem intervalu a nebo je nastaveny koncovy bod roven 1
			if(this.middle_interval > this.position_mark || this.set_mark == 1){
				// pocitej s rovnomerne zrychlenym pohybem ukazatele
				s = this.speed_mark*0.01 + (0.5 * this.akceleration_mark * 0.01);
				// aktualni rychlost je puvodni aktualni rychlost + nova rychlost
				this.speed_mark = this.speed_mark + (s / 0.1);
			}
			// ukazatel za koncem stredu
			else {
				// rovnomerne zpomaleny pohyb
				s = this.speed_mark*0.01 - (0.5 * this.akceleration_mark * 0.01);
				this.speed_mark = this.speed_mark - (s / 0.1);
			}
			// dodatecna podminka proto, aby nezacal ukazatel "couvat" ;), prirustek musi byt kladny vzdy
			if(this.position_mark+(this.speed_mark*0.1)>=this.position_mark)
				this.position_mark = this.position_mark+(this.speed_mark*0.1);
		}
		// pokud je dosazeno koncoveho bodu
		else {
			// nastav rychlost na nulu (pro jistotu :)
			this.speed_mark = 0;
		}
		// nastav novou hodnotu progressbaru
		this.progressBarValue((Math.round(this.position_mark*1000))/1000);
		// prepinani uloh
		if(this.switch_task_limit < this.position_mark){
			var task = this.tasks.shift();
			if(task != null){
				this.info_element.innerHTML = task[0];
				this.switch_task_limit = this.switch_task_limit + task[1];				
			}
		}
	}
	// kdyz je akce dokoncena
	else {
		this.position_mark = 1;
		this.progressBarValue(1);
		//alert("a");
		// zastav animaci prubehu
		this.animation_element.innerHTML = "......";
		//
		this.info_element.innerHTML = "";
		// zobraz info o dokonceni
		this.changeStatus("Done");
		//setTimeout(function() { thisProgBar.reflesh(); } ,this.mark_reflesh_time);
		// chvilku "podrz" progressbar a pak ho skryj
		setTimeout(function() { thisProgBar.hide(); } ,this.done_wait);
	}
	if(this.visibility){
		// spust dalsi reflesh..
		setTimeout(function() { thisProgBar.reflesh(); } ,this.mark_reflesh_time);
	}
};
//------------------------------------------------------
ProgressBar.prototype.startProgress = function (){
	this.changeStatus("Loading");
	this.reflesh();
	//this.inc();
};

ProgressBar.prototype.animateProgress = function() {
	var thisProgBar = this;
	if(this.position_mark!=1){
		this.animation_element.innerHTML = runDots(this.animation_element.innerHTML);
		setTimeout(function() { thisProgBar.animateProgress(); } ,this.animation_interval);
	}
};
//------------------------------------------------------

function runDots(string)
{
	var result;
	if(string.match(/^(\.*)(\&nbsp;)$/)){
		result = string.replace(/^(\.)(\.*)(\&nbsp;)$/, "$3"+"$2"+"$1");
	}
	else {
		result = string.replace(/^(\.*?)(\&nbsp;)(\.)(\.*?)$/, "$1"+"$3"+"$2"+"$4");
	}
	return result;
};