
// JavaScript Document

// tworzenie animowanego paska
function animate_bar( 
	container_id, // id kontenera w którym zostanie osadzony pasek
	all_cnt,      // ilość wszystkich animowanych elementów
	size_elem,    // rozmiar elementu
	size_padd,    // rozmiar odstępu
	offs_top,     // domyślne położenie animowanych elementów względem wysokości
	get_element,  // metoda zwrotna podajaca kod w htmlu animowanych elementów
	data,         // dowolne pomocnicze dane użytkownika
	zero_elems    // komunikat gdy jest zero elementów
) {
	this.cont   = document.getElementById(container_id); // kontener
	this.elems  = Array();                               // lista animowanych elementów
	this.resets( all_cnt, size_elem, size_padd, offs_top, get_element, data , zero_elems );
}


// restart ustawień animowanego paska
animate_bar.prototype.resets = function(
	all_cnt,      // ilość wszystkich animowanych elementów, jeśli -1 to pozostanie to pozostanie niezmieniona
	size_elem,    // rozmiar elementu, jeśli -1 to pozostanie to pozostanie niezmieniona
	size_padd,    // rozmiar odstępu, jeśli -1 to pozostanie to pozostanie niezmieniona
	offs_top,     // domyślne położenie animowanych elementów względem wysokości, jeśli -1 to pozostanie to pozostanie niezmieniona
	get_element,  // metoda zwrotna podajaca kod w htmlu animowanych elementów, może być null
	data,         // dowolne pomocnicze dane użytkownika, może być null
	zero_elems    // komunikat gdy jest zero elementów
) {
	if( all_cnt     >= 0    ) this.all_cnt     = all_cnt;
	if( size_elem   >= 0    ) this.size_elem   = size_elem;
	if( size_padd   >= 0    ) this.size_padd   = size_padd;
	if( offs_top    >= 0    ) this.offs_top    = offs_top;	
	if( get_element != null ) this.get_element = get_element;
	if( data        != null ) this.data        = data;
	if( zero_elems  != null ) this.zero_elems  = zero_elems;
	for( var e in this.elems ) {
		if( this.elems[e] != null ) {
			this.elems[e].parentNode.removeChild( this.elems[e] );
			this.elems[e] = null;
		}
//		this.elems.splice(e,1);
	}
//	while( this.cont.childNodes.length > 0 )
//		this.cont.removeChild( this.cont.childNodes[0] );
	this.cont.innerHTML = "";
	this.first    = 0;
	this.curr_cnt = 0;
	this.resizes();
	this.locker = false;
	if( this.all_cnt <= 0 && zero_elems != null )
		this.cont.innerHTML = zero_elems;
}

// Obliczanie bieżącej ilości elementów w kontenerze
//  - szerokosć kontenera this.cont_size musi być poprawna
//  - rozmiary odstępów i elementów muszą być poprawne
animate_bar.prototype.comp_cnt = function() {
	this.curr_cnt  = this.cont_size;                      // odejmujemy od szerokości kontenera szerokość marginesu 
	this.curr_cnt  /= (this.size_elem + this.size_padd + 1);  // ilość miniaturek w kontenerze
	this.curr_cnt  = Math.floor( this.curr_cnt );         // zaokrąglamy w dół, aby nie wyświetlało się pół miniaturki
	if( this.curr_cnt < 2 )                               // co najmniej 2 elementy
		this.curr_cnt = 2;
	if( this.curr_cnt > this.all_cnt )
		this.curr_cnt = this.all_cnt;
}


// obliczanie bieżącego odstępu, może być większy niż podany
//  - szerokosć kontenera this.cont_size musi być poprawna
//  - rozmiary odstępów i elementów muszą być poprawne
//  - bieżąca ilość elementów musi być poprawna
animate_bar.prototype.comp_padd = function() {
	this.curr_padd  = this.cont_size - this.curr_cnt * (this.size_elem+1);
	this.curr_padd /= this.curr_cnt;
	if( this.curr_padd < 1 )
		this.curr_padd = 1;
}


animate_bar.prototype.show_element = function( i ) {
	var set_top = false;
	if( this.elems[i] == null ) {
		this.elems[i]                = document.createElement("div");
		this.elems[i].id             = "animated_element_" + (i+1);
		this.elems[i].innerHTML      = this.get_element( this.data , i );
		this.cont.appendChild( this.elems[i] );
		this.elems[i].style.position = "relative";
		this.elems[i].style.display  = "block";
		this.elems[i].style.width    = this.size_elem + "px";
		this.elems[i].style.height   = this.size_elem + "px";
		this.elems[i].style.top      = (- i * this.size_elem + this.offs_top ) + "px";
		this.elems[i].an_obj         = this;
	}
	this.elems[i].style.left     = parseInt( ( this.curr_padd + this.size_elem ) * (i-this.first) + this.curr_padd/2 ) + "px";
}
/*
animate_bar.prototype.hide_elements = function( start , end ) {
	for( var x in this.showed ) {
		if( x < start || x >= end ) {
			this.cont.removeChild( this.showed[x] );
			this.showed.splice( x , 1 );
		}
	}
}
*/

// do wywołania po zmianie rozmiaru animowanych elementów
// lub zmianie rozmiaru kontenera
animate_bar.prototype.resizes = function() {
	if( this.locker ) 
		return;
	this.locker = true;

	this.cont_size = this.cont.offsetWidth;               // szerokość kontenera
	var cpy_curr_cnt = this.curr_cnt;                     // kopia ilości elementów
	this.comp_cnt();                                      // oblicz ile elementów zmieści się w kontenerze
	this.comp_padd();                                     // oblicz odstęp pomiędzy elementami
	
	// obliczamy zakres widocznych miniaturek
	var i = this.first;                                   // zaczynamy od pierwszego widocznego
	var e = this.first;                                   // zakładamy ze zakres jest jednostkowy
	while( e-i < this.curr_cnt && e < this.all_cnt ) e++; // poszerzamy w prawo
	while( e-i < this.curr_cnt && i > 0 )            i--; // jak się nie starczyło w prawo to jeszcze w lewo
	this.first = i;                                       // aktualizujemy pierwszy widoczny

	while( i < e ) this.show_element( i++ );              // pokazujemy miniaturki
	e += cpy_curr_cnt - this.curr_cnt;
	while( i < e )
		this.elems[i++].style.left = (-10 - this.size_elem) + "px"; // ukrywamy po lewej stronie
	this.locker = false;
}


animate_bar.prototype.end_next = function() {
	this.an_count -- ;
	if( this.an_count == 0 ) {
		var new_first = this.add_last - this.curr_cnt;
		while( this.first < new_first ) {
			this.elems[this.first].style.left = (-10 - this.size_elem) + "px";
			this.first++;
		}
		this.locker = false;
	}
}


animate_bar.prototype.next = function() {
	var i;
	if( this.locker ) 
		return;
	this.locker = true;
	this.add_first = this.first     + this.curr_cnt;       // zaczynamy od pierwszego niewidocznego
	this.add_last  = this.add_first + this.curr_cnt;       // przesuwamy o curr_cnt
	if( this.add_last > this.all_cnt )                     // test przekroczenia zakresów
		this.add_last = this.all_cnt;
	if( this.add_last <= this.add_first ) {
		this.locker = false;
		return false;		
	}
	for( i=this.add_first ; i<this.add_last ; i++ )
		this.show_element( i );
	this.an_count = this.add_last - this.first;
	var an_offset = ( this.add_last - this.add_first ) * ( this.size_elem + this.curr_padd );
	
	for( i=this.first ; i<this.add_last ; i++ ) {
		var start = this.elems[i].offsetLeft;
		var end   = start - an_offset;
		$( "#" + this.elems[i].id ).animate( {left: end} , 1000 , function() { this.an_obj.end_next(); } );
	}
	
	return true;
}

animate_bar.prototype.end_prev = function() {
	this.an_count -- ;
	if( this.an_count == 0 ) {
		this.first = this.add_first;
		for( var i=this.first + this.curr_cnt ; i<this.first + this.curr_cnt*2 && i<this.all_cnt ; i++ )
			this.elems[i].style.left = (-10 - this.size_elem) + "px";
		this.locker = false;
	}
}


animate_bar.prototype.prev = function() {
	var i;	
	if( this.first == 0 ) 
		return false;                                      // nie można przewinąć w lewo
	if( this.locker ) 
		return;
	this.locker = true;
	this.add_first = this.first - this.curr_cnt;           // zaczynamy od ostatniego niewidocznego
	if( this.add_first < 0 )                               // test zakresu
		this.add_first = 0;
	this.add_last = this.first;
	for( i=this.add_first ; i<this.add_last ; i++ )
		this.show_element( i );
	this.an_count = this.first + this.curr_cnt - this.add_first;
	var an_offset = ( this.add_last - this.add_first ) * ( this.size_elem + this.curr_padd );
	
	for( i=this.add_first ; i<this.first + this.curr_cnt ; i++ ) {
		var start = this.elems[i].offsetLeft;
		var end   = start + an_offset;
		$( "#" + this.elems[i].id ).animate( {left: end} , 1000 , function() { this.an_obj.end_prev(); } );
	}
	
	return true;
}


