﻿/*** changelog ***
	
2010.01.04
* dodana ogsluga : window.scrollbarWidth / window.scrollbarHeight
* przeniesienie objcectsAreSame jako wewnętrzną metodę f

2009.12.*
* aktualizacje metod dla Array.

*/
// 	ROZSZERZENIA  //

//	[window]
// 	scrollbar width / height
$(function(){
	var i = document.createElement('p');
	i.style.width = '100%'; i.style.height = '200px';

	var o = document.createElement('div');
	o.style.position = 'absolute'; o.style.top = '0px';  o.style.left = '0px';
	o.style.visibility ='hidden'; o.style.width = '200px';
	o.style.height = '150px'; o.style.overflow = 'hidden'; o.appendChild(i);

	document.body.appendChild(o);
	var w1 = i.offsetWidth; var	h1 = i.offsetHeight;
	o.style.overflow = 'scroll';
	var w2 = i.offsetWidth; var h2 = i.offsetHeight;
	if (w1 == w2) w2 = o.clientWidth; if (h1 == h2) h2 = o.clientWidth;
	document.body.removeChild(o);

	window.scrollbarWidth = w1-w2; window.scrollbarHeight = h1-h2;
});

//	[Array]
//	http://www.hunlock.com/blogs/Mastering_Javascript_Arrays#forEach
/*  stara wersja metody Array.contains 
Array.prototype.contains = function() {
	/**
	 *	Sprawdza czy dany element jest w tablicy. Można przekazać listę elementów - wtedy są sprawdzane wszystkie.
	 *	Nie modyfikuje obiektu, na ktorym zostala wywolana.
	 *	@param 		item 		 	- element, który chcemy sprawdzić czy jest obecny w tablicy
	 *							 	- lista elementów, które sprawdzamy (jako kolejne argumenty)
	 *	@return 	true/false 		w zaleznosci od tego czy w tablicy zostal znaleziony element 'item'
	 *	
	 *	@jquery 	nie	
	* /
	//	zwracamy false, jesli nie przekazano zadnych argumentow.
	if ( arguments.length == 0 ) {
		return false;
	}
	var _contains = [];
	//	sprawdzamy wszystkie przekazane parametry
	for ( var i=0; i<arguments.length; i++ ) {
		var item = arguments[i];
		_contains[i] = false;
		//	sprawdzamy element 'i'
		for ( var index in this ) {
			if ( this.hasOwnProperty(index) ) {
				//	porownujemy dwa obiekty (obsluga również typów innych niż proste)
				if ( f.objectsAreSame( this[index] , item )  ) {
					//	znaleziono element 'i'
					_contains[i] = true;
				}
			}
		}
		//	jesli nie znaleziono elementu 'i', zwroc false. (musza byc wszystkie obecne)
		if ( !_contains[i] ) {
			return false;
		}
	}
	//	wszystkie elementy znalezione, zwracamy true.
	return true;
}; */
Array.prototype.contains = function(item) {
	/**
	 *	Sprawdza czy dany element jest w tablicy. Można przekazać listę elementów - wtedy są sprawdzane wszystkie.
	 *	Nie modyfikuje obiektu, na ktorym zostala wywolana.
	 *	@param 		item 		 	- element, który chcemy sprawdzić czy jest obecny w tablicy
	 *							 	- lista elementów, które sprawdzamy (jako kolejne argumenty)
	 *	@return 	true/false 		w zaleznosci od tego czy w tablicy zostal znaleziony element 'item'
	 *	
	 *	@jquery 	nie	
	 */
	//	zwracamy false, jesli nie przekazano zadnych argumentow.
	if ( arguments.length == 0 ) {
		return false;
	}
	//	sprawdzamy wszystkie przekazane parametry
	for ( var i=0; i<arguments.length; i++ ) {
		var item = arguments[i];
		//	jesli element 'i' nie zostal znaleziony, zwroc false
		if ( !  (( ( x = this.find(item) ) === 0 ) ? true : !!x) ) {
			return false;
		}
	}
	//	wszystkie elementy zostaly znalezione
	return true;
	
	
	
	
	
	var x = null;
	return ( ( x = this.find(item) ) === 0 ) ? true : !!x;
};
Array.prototype.find =	function(item) {
	/**
	 *	Sprawdza index elementu w tablicy
	 *	Nie modyfikuje obiektu, na ktorym zostala wywolana.
	 *	@param 		item	element, który chcemy znaleźć w tablicy (pojedynczy element)
	 *	@return 	indeks elementu 'item' w tablicy lub false jesli takiego elementu nie ma, 
	 */
	for ( var index in this ) {
		if ( this.hasOwnProperty(index) ) {
			//	porownujemy dwa obiekty (obsluga również typów innych niż proste)
			if ( f.objectsAreSame( this[index] , item )  ) {
				//	znaleziono element , zwracamy index
				return index;
			}
		}
	}
	return false;
};
Array.prototype.sortBy = function(column, type, reverse) {
	/** 
	 *	Sortowanie tablicy.
	 *	Sortuje tablicę po wartościach kolumny 'column', według typu 'type', reverse - od końca; Modyfikuje obiekt, na ktorym została wywołana.
	 *	@param 	column	nazwa kolumny, po której ma się odbyć sortowanie
	 *	@param 	type		typ danych - w jaki sposób ma porównywać dane z kolumny 'column'
	 *					jest to nazwa funkcji do porównywania. (z obiektu arraySorting)
	 *	@param	reverse	true/false - czy odwrócić kolejność sortowania (od 'tyłu'...)
	 *	@return	nic nie zwraca :)
	 */
	arraySorting.setColumn(column);
	if ( typeof arraySorting[type] != 'function' ) {
		return false;
	}
	this.sort( arraySorting[type] );
	if ( reverse ) {
		this.reverse();
	}
	arraySorting.unsetColumn();
};
Array.prototype.shuffle = function() {
	/**
	 *	Ustawia elementy w tablicy w kolejności losowej. 
	 *	Modyfikuje obiekt, na którym została wywołana.
	 *	@return 	true	- jesli wszystko poszlo dobrze, to zwraca true.
	 *	@example :
	 *	funkcja losowo rozrzuca elementy po tablicy... nie bierze pod uwage elementow z innymi indeksami niz liczbowymi, np : 
	 * 		var a2 = new Array( 'a', 53 , 'b' );
	 *		a2['a'] = 55;
	 *		a2[3] = 88;
	 *		a2[10] = 99;
	 * 	element 55 nie zmieni swojego miejsca, zazwyczaj wyswietlony bedzie na koncu
	 *	elementy 88, 99 zmienia jako ze sa indeksowane liczbowo
	 */
	for ( var randomIndex, tmp, i=this.length; i; ) { 
		if ( this[i-1] ) {
			randomIndex = parseInt(Math.random()*i);
			if ( this[randomIndex] ) {
				tmp=this[i-1];
				this[i-1]=this[randomIndex];
				this[randomIndex]=tmp;
			}
		}
		i--;
	}
	return true;
};
Array.prototype.switchIndexes = function() {
	/**
	 *	Zamienia indeksy z wartościami.
	 *	Nie modyfikuje obiektu, na którym została wywołana.
	 *	@return	obiekt Array
	 *	@example 
	 *	jesli dwa elementu maja taka sama wartosc - wartoscia tego indeksu bedzie element wystepujacy 'pozniej' w tablicy, np : 
	 *		var a = new Array( 'a', 53 , 'b' );
	 *		a[10] = 99;
	 *		a['c'] = 99;
	 *		var aw = a.switchIndexes();
	 *		aw[99] = 'c';
	 */
	var w = [];
	for (var i in this) {
		if ( this.hasOwnProperty(i) && typeof this[i] != 'funcion') {
			w[this[i]]=i;
		}
	}
	return w;
};
if ( !Array.prototype.forEach ) {
	//	zmiana nazwy each.... forEach jest w FF zdefiniowana.
	Array.prototype.forEach = function( fn ) {
		/**
		 *	Leci po wszystkich elementach.
		 *	Nie modyfikuje obiektu tablicy.
		 *	@param	fn	funkcja do wywolania, na każdym elemencie
		 *	@return 	ta sama tablice
		 *	@example : 
		 *		var s = 'to jest string';
		 *		s.split('').each(function(item){
		 *			alert(this);		//  	tablica, na której wywołana została metoda each
		 *			alert(item);		//	pojedynczy element tablicy
		 *		});
		 */
		if ( typeof fn != 'function' ) {
			return false;
		}
		for (var i in this ) {
			if ( this.hasOwnProperty(i) ) {
				fn.call(this, this[i], i, this);
				//	w funkcji : 
				//	arguments[0] = this[i]  	- item.
				//	arguments[1] = i 			- index.
				//	arguments[2] = this			- whole array
				//	this 						- whole array
			};
		};
		return this;
	};
};
//	each - alias dla forEach
Array.prototype.each = function( fn ) {
	return this.forEach(fn);
};
var arraySorting = function() {
	/*private*/
	var sortCharsPL = " !\"#$%&'()*+,-./0123456789:;<=>?@AaĄąBbCcĆćDdEeĘęFfGgHhIiJjKkLlŁłMmNnŃńOoÓóPpQqRrSsŚśTtUuVvWwXxYyZzŹźŻż[\\]^_`{|}~"
		.split('').switchIndexes();
	var sortByColumn = false;

	
	/*public*/
	return { 
		setColumn: function(name) {
			if ( !name ) {
				return false;
			}
			sortByColumn = name;
		},
		unsetColumn: function(name) {
			sortByColumn = false;
		},
		comparePL: function(a,b) {
			if ( sortByColumn ) {
				a = a[sortByColumn] || a;
				b = b[sortByColumn] || b;					
			}
			a=new String(a);
			b=new String(b);
			var aTab = a.split('');
			var bTab = b.split('');
			for (var i=0, aIle=aTab.length; i<aIle; i++) {
				if ( typeof sortCharsPL[bTab[i]] == "undefined" ) 
					return -1;
				if (sortCharsPL[aTab[i]] > sortCharsPL[bTab[i]]) {
					return 1;
				} else if (sortCharsPL[aTab[i]] < sortCharsPL[bTab[i]]) {
					return -1;
				}
			};
			//	jesli aTab jest pusta, to sprawdzamy czy w bTab sa jakies elementy...
			if ( bTab.length > 0 ) {
				//	bTab zawiera elementy, aTab pusta.
				return 1;
			} else {
				//	obie puste, czyli takie same.
				return 0;
			}
			//	inny przypadek, ktory nie powinien wystapic ;)
			return 0;
		},
		compareInt: function(a,b) {
			if ( sortByColumn ) {
				a = a[sortByColumn] || a;
				b = b[sortByColumn] || b;					
			}
			return a-b;
		},
		compareAmount: function(a,b) {
			//	porównywanie kwot, np : 192,004.57
			if ( sortByColumn ) {
				a = a[sortByColumn] || a;
				b = b[sortByColumn] || b;					
			}
			var val1 = Number.MAX_VALUE, val2 = Number.MAX_VALUE;
			if ( a ) {
				val1 = a.replace('\.','').replace('\,','.');
			}
			if ( b ) {
				val2 = b.replace('\.','').replace('\,','.');
			}
			if ( parseFloat(val1) == parseFloat(val2) ) {
				return 0;
			} else if ( parseFloat(val1) > parseFloat(val2) ) {
				return 1;
			} else {
				return -1;
			}
		}		
	};
}();

Number.prototype.isFloat = function() {
	/**
	 *	@see 	f.number.isFloat
	 */
	return f.number.isFloat(this);
};
Number.prototype.isInteger = function() {
	/**
	 *	@see	f.number.isInteger
	 */
	return f.number.isInteger(this);
};



if ( typeof String.trim == 'undefined' && typeof String.prototype.trim == 'undefined' ) {
	//	Firefox 3.5 ma już wbudowaną tą funkcję, więc nie będziemy jej podmieniać ;) 
	String.prototype.trim = function() 		{
		/**
		 *	Usuwa białe znaki z początku i końca napisu.
		 *	Nie modyfikuje obiektu, na którym jest wywołana.
		 *	@return	obiekt String z usuniętymi białymi znakami na początku i końcu
		 */
		return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
	};
}
String.prototype.test = function( str, where ) {
	/**
	 *	Metoda sprawdza czy w napisie, na którym jest wywołana występuje podciąg 'str'.
	 *	Nie modyfikuje obiektu, na którym jest wywołana.
	 *	Metoda rozróżnia wielkie i małe litery.
	 *	@param 	str		szukany podciąg
	 *	@param	where	parametr opcjonalny, wksazuje na miejsce poszukiwania podciągu 'str', możliwe wartości: 
	 *					first	- szuka tylko na początku ciągu
	 *					last	- szuka tylko na końcu ciągu
	 *	@return	true/false	w zależności czy dany podciąg został znaleziony czy nie.
	 */
	str = 	str.replace(/\?/g, '\\?').replace(/\./g, '\\.').replace(/\^/g,'\\^').replace(/\$/g,'\\$').replace(/\+/g,'\\+')
			.replace(/\*/g,'\\*').replace(/\(/g,'\\(').replace(/\)/g,'\\)').replace(/\|/g,'\\|').replace(/\{/g,'\\{').replace(/\[/g,'\\[');
	var G = new RegExp('^.*'+str+'.*$','g');
	if ( where && where == 'first' ) {
		G = new RegExp('^'+str+'.*$','g');
	} else if ( where && where == 'last' ) {
		G = new RegExp('^.*'+str+'$','g');
	}
	return G.test(this);
};

Date.prototype.getWeek = function() {
	/**
	 *	Metoda zwraca numer bieżącego (dla danego obiektu daty) tygodnia.
	 *	@return		numer tygodnia w roku
	 *	@example
	 *		var date = new Date();
	 *		var numerTygodnia = d.getWeek();
	 */
	var firstJan = new Date(this.getFullYear(),0,1);
	return Math.ceil((((this - firstJan) / 86400000) + firstJan.getDay()+1)/7); 
}

$.fn.showHide = function(options) { 
	/**
	 *	Pokazuje / ukrywa dany obiekt.
	 *	@param	options  	- możliwe opcje: 
	 *				el 			- element, na którym zachodzi zdażenie (link) - eventObject
	 *				effect		- efekt animacji ('slide');
	 *							domyślnie : fadeOut / fadeIn
	 *				speed		- jak szybko ? ('fast', 'normal', 'slow', 100, 200 itp)
	 *	 						domyślnie 'normal'
	 *				txt			- zmiana tekstu linku po pokazaniu / schowaniu obiektu. wymaga przekazania el (eventObject)
	 *							['tekst jak ukryte', 'tekst jak pokazane']						
	 *	@return	obiekt jQuery 
	 * 	@example 	
	 *		$('#idObiektu').showHide();
	 *		a.click(function(){
	 *			$(this).next('code').showHide({ effect: 'slide', speed: 500, txt:[ 'Pokaż kod', 'Schowaj kod'], el:this });
	 *			return false;
	 *		});
	 */
	return this.each(function(options) {
		return function(){
			var _animationSpeed = 'normal';
			if ( options && options.speed ) {
				//	sprawdzanie wartosci, liczba lub fast, normal, slow.
				if ( ! ( options.speed == 'fast' || options.speed == 'normal' || options.speed == 'slow' || 
						( parseInt(options.speed) > 0 && parseInt(options.speed) < 10000 ) ) ) {
					_animationSpeed = options.speed;
				}
			}
			var obj = $(this);
			if ( obj.is(':visible') ) {
				//	chowamy i pokazujemy 
				if ( options && options.effect ) {
					if ( options.effect == 'slide' ) {
						obj.slideUp(_animationSpeed);
					} else {
						//	domyślny efekt
						obj.fadeOut(_animationSpeed);
					}
				} else {
					obj.fadeOut(_animationSpeed);
				}
				//	zmieniamy tekst, jesli potrzeba :)
				if ( options && options.txt && options.txt.length == 2 && options.el ) {
					$(options.el).text(options.txt[0]);
				}
			} else {
				//	chowamy i pokazujemy 
				if ( options && options.effect ) {
					if ( options.effect == 'slide' ) {
						obj.slideDown(_animationSpeed);
					} else {
						//	domyślny efekt
						obj.fadeIn(_animationSpeed);
					}	
				} else {
					//TODO usunąć powtórzenie
					obj.fadeIn(_animationSpeed);
				}
				//	zmieniamy tekst, jesli potrzeba :)
				if ( options && options.txt && options.txt.length == 2 && options.el ) {
					$(options.el).text(options.txt[1]);
				}
			}
		}
	}(options));
};

var f = function() {
	/* private */
	var months = ['Styczeń','Luty','Marzec','Kwiecień','Maj','Czerwiec','Lipiec','Sierpień','Wrzesień','Październik','Listopad','Grudzień'];
	var monthsDop = ['stycznia','lutego','marca','kwietnia','maja','czerwca','lipca','sierpnia','września','października','listopada','grudnia'];
	
	/* public */
	return { 
		hideObjects: 	false,
		sortByColumn: 	false,
		
		objectsAreSame: 	function(x, y) {
			/** 
			 *	Funkcja porównuje dwa obiekty: x i y.
			 *	@return	true/false 	w zależności od tego, czy obiekty sa takie same czy nie.
			 *
			 */
			for(var propertyName in x) {
				if(x[propertyName] !== y[propertyName]) {
					return false;
				}
			}
			for(var propertyName in y) {
				if(y[propertyName] !== x[propertyName]) {
					return false;
				}
			}
			return true;
		},
		getMonth: 		function(n, przypadek) {
			/**
			 *	Zwraca nazwę miesiąca (pl).
			 *	@param 	n 	numer miesiaca (1-12)
			 * 	@param 	przypadek	w jakim przypadku ma być zwrócona nazwa, możliwe wartości : 
			 *					mianownik, dopełniacz
			 *					domyślna wartośc: mianownik
			 * 	@return	nazwę miesiąca lub false, jeśli np przekazalismy zly numer miesiaca.
			 */
			przypadek = przypadek || 'mianownik';
			if ( --n<12 ) {
				if ( przypadek == 'mianownik' && months[n] ) {
					return months[n];
				} else if ( ( przypadek == 'dopelniacz' || przypadek == 'dop' ) && monthsDop[n] ) {
					return monthsDop[n];
				}
			} 
			return false;
		},
		number: {
		/**
		 *	Pierwsze dwie sprawdzaja czy dany obiekt jest liczbą zmiennoprzecinkową lub całkowitą. 
		 *	Pozostałe dwie zwracają liczbę z podanego przedziału - całkowitą lub zmiennoprzecinkową.
		 *	@param 	number	obiekt, do sprawdzenia czy jest liczbą
		 *	@param	a,b		dwie liczby, określające zakres, z którego ma być wylosowana liczba
		 *	@return		true / false		czy dany obiekt to liczba
		 *	@return		Number		wylosowana liczba.
		 */
			isFloat: 		function(number) {
				return /^[\d]+\.[\d]*$/.test(number.toString().trim());
			},
			isInteger: 		function(number) {
				return /^[\d]+$/.test(number.toString().trim());
			},
			randomInt: 		function(a,b) {
				return Math.floor((b-(a-1))*Math.random()) +a;
			},
			randomFloat: 	function(a,b){
				return Math.random()+this.randomInt(a,b-1);
			}
		},
		url: {
			get: function(param, options) {
			/**
			 *	Funkcja pobiera parametr (zgodnie z zasadami przekazywania parametrów do URL).
			 *	@param	param	nazwa parametru do wczytania.
			 *	@param	options	obiekt z dodatkowymi opcjami (opcjonalny)
			 *					możliwe opcje : 
			 *				searchFrom : string 		przekazany ciąg znaków, w którym mamy szukać parametru 'param' zamiast domyślnie z URL
			 *				caseSensitive : boolean 	czy brać pod uwagę wielkość znaków w wyszukiwaniu parametur i 
			 *											zwracaniu wartości ?  domyślnie false;
			 *	@return	wartość parametru 'param' .
			 *			false	jeśli nie ma takiego parametru.
			 */
				var qstr = window.location.search;
				if ( options && options.searchFrom && options.searchFrom != '' ) {
					qstr = options.searchFrom;
				}
				if ( !options || !options.caseSensitive ) {
					// dotyczy zarowno wartosci zwracanej jak i nazwy zmiennej
					param = param.toLowerCase();
					qstr = qstr.toLowerCase();
				}
				if ( qstr.test('=') && qstr.test(param) ) {
					var tmp = new RegExp(".*[\\?\\&]+"+param+"=([\\w\\d]+).*").exec(qstr);
					if (tmp) {
						return tmp[1];
					} else {
						return null;
					}
				} else { 
					return false;
				}
			}
		},
		getParam: 		function(param, options) {
			//	alias do f.url.get();
			return f.url.get(param,options);
		},
		objects: {
		/**
		 *	Funkcje do pokazywania / ukrywania obiektów typu <object> i <select>, które prześwitują przez overlay.
		 *	@return	nic
		 */
			hide: 		function() {
				$('object:visible, select:visible').each(function() {
					$(this).css('visibility', 'hidden').data('hiddenByHideFunction',true);
				});
				this.hideObjects = true;
			},
			show: 		function() {
				if ( !this.hideObjects ) {
					return false;
				}
				$('object, select').each(function() {
					if ( $(this).data('hiddenByHideFunction') ) {
						$(this).css('visibility', 'visible').data('hiddenByHideFunction',false);
					}
				});
			}
		},
		cookie : {
			set: 		function(name, value, days) {
			/**
			 *	Ustawia cookie o nazwie 'name', wartością 'value'.
			 *	@param	name		nazwa ciasteczka
			 *	@param	value		wartość ciasteczka
			 *	@param	days		ile dni ma być ważne ciasteczko? (opcjonalnie, domyślnie do czasu zamknięcia sesji)
			 *	@return	true	jeśli wszystko poszło dobrze, 
			 *			false	jeśli np nie przekazaliśmy name lub value
			 */
				if ( !name || !value ) {
					return false;
				}
				if (days && f.number.isInteger(days)) {
					var date = new Date();
					date.setTime(date.getTime()+( days * 24 * 60 * 60 * 1000 ));
					var e = "; expires="+date.toGMTString();
				} else {
					var e = "";
				}
				document.cookie = escape(name)+"="+escape(value)+e+"; path=/";
				return true;
			},
			get:		function(name){
			/**
			 *	Zwraca wartość ciasteczka o nazwie 'name'.
			 *	@param	name		nazwa ciasteczka, którego wartość będzie zwrócona.
			 *	@return	wartość ciasteczka, jeśli zostało znalezione.
			 *			false	jeśli ciasteczka o takiej nazwie nie ma, lub nie przekazalismy nazwy ciasteczka.
			 */
				if ( !name ) {
					return false;
				}
				name = escape(name);
				name += "=";
				if (document.cookie && document.cookie != '') {
					var cookieStr = document.cookie.split(';');
					var cookieSubStr;
					for(var i=0;i < cookieStr.length;i++) {
						cookieSubStr = cookieStr[i].trim();
						if (cookieSubStr.test(name) ) {
							var cookieVal = unescape(cookieSubStr.substring(name.length,cookieSubStr.length));
							if (cookieVal == 'fdeleted') {
								return false;
							}
							return cookieVal ;
						}
					}
				}
				return false;
			},
			del:		function(name){
			/**
			 *	Usuwa ciasteczko o podanej nazwie.
			 *	@param 	name		nazwa ciasteczka.
			 *	@return   @see   cookie.set 
			 *	@important 
			 *	usuwa cookie, (przynajmniej teoretycznie, bo get zwraca 0 zamiast false);
			 *	pamietac, aby sprawdzac wartosc cookiesa
			 */
				this.set(name, 'fdeleted',-1);
			}
		},
		insert: {
			css: function(href, antyCache) {
			/**
			 *	Dodaje arkusz styli do dokumentu.
			 *	@param	href		adres arkusza styli
			 *	@param	antyCache	true/false  - true zapobiega cacheowaniu pliku przez przeglądarke poprzez dorzucenie dodatkowego parametru
			 *	@return	nic
			 *	@important 
			 *		pamiętać, aby wywoływać na początku strony, a nie na końcu, z uwagi na efekt 'skosku' elementu po dodaniu nowego stylu
			 */
				if ( !href ) {
					return false;
				}
				//TODO :
				//	dodac 'obsługę' hrefa w postaci ?get=c.css  lub np ?get=css&file=jquery 
				if ( antyCache ) {
					href = href +'?antyCache='+new Date().getTime();
				}
				$.ajax({
					type: "GET",
					url: href,
					dataType: 'html',
					async: false,
					success: function(data) { 
						var cssNode = document.createElement('link');
						cssNode.type = 'text/css';
						cssNode.href = href;
						cssNode.rel = 'stylesheet';
						cssNode.media = 'screen';
						cssNode.title = 'dynamicStyleSheet';
						document.getElementsByTagName("head")[0].appendChild(cssNode);				
					}
				});
			},
			js: function(href, antyCache) {
			/**
			 *	Dodaje plik skryptów JS do strony.
			 *	Cały skrypt jest wykonywany w chwili dodania do dokumentu.
			 *	@param		href		adres pliku ze skryptami JS
			 * 	@param		antyCache	true/false - true zapobiega cacheowaniu pliku przez przeglądarke poprzez dorzucenie dodatkowego parametru
			 *	@return		nic
			 *	@important
			 *		nie wiem jak to jest z $(function() { } ): w takim jsie - czy jest wykonywany po załadowaniu pliku .js (czyli siebie) 
			 *		czy dopiero po załadowaniu całego dokumentu DOM.
			 */
				if ( !href ) {
					return false;
				}
				//TODO :
				//	dodac 'obsługę' hrefa w postaci ?get=js.js  lub np ?get=js&file=jquery 
				if ( antyCache ) {
					href = href +'?antyCache='+new Date().getTime();
				}
				var newScript = document.createElement('script');
				newScript.type = 'text/javascript';
				newScript.src = href;
				document.getElementsByTagName("head")[0].appendChild(newScript);
			}
		},
		preload : function(hrefs) {
		/** 
		 *	Metoda do ładowania obrazków przed ich wyświetleniem, aby ładowały się jak już będą potrzebne :)
		 *	@param 	hrefs	tablica z odnośnikami do obrazków do załadowania
		 *	@return	false	jeśli nie przekazano tablicy lub jest ona pusta
		 *			true	jeśli wszystko poszło ok
		 *	@example 
		 *		f.preload(['https://cos.com/karta.gif', 'https://cos.com/karta_.gif']);		// => true
		 *		f.preload([]);				// 	=> false
		 *		f.preload(''); 				//	=> false;
		 *		f.preload({cos:'cos'});		//	=> false;
		 */
			if ( typeof hrefs == 'undefined' || !hrefs || hrefs.length==0 || !hrefs.each ) {
				return false;
			};
			if ( hrefs.length > 0 && typeof f.preloadedImages == 'undefined' ) {
				f.preloadedImages = new Array();
			};
			hrefs.each(function(item) {
				if ( !f.preloadedImages.contains(item) ) {
					var img = new Image();
					img.src = item;
					f.preloadedImages.push(item);
				}
			});
			return true;
		},
		wups: function(href, options) {
			/**
			 *	Otwiera nowe okno, ładuje stronę o adresie 'href' lub kod html przekazany w opcjach.
			 *	@return 	zwraca true jesli wszystko poszlo ok
			 *	@param 	href		adres URL strony do otworzenia
			 *	@param	options	obiekt z dodatkowymi opcjami
			 *				width, height	szerokość, wysokość otwieranego okna (liczbowo, bez px, nie string)
			 *				name			nazwa otwieranego okna
			 *				html			kod HTML, ktory zostanie załadowany do okna. strona z hrefa nie będzie wtedy otwierana.
			 */			
			
			/*
			 *	domyslne wartosci 
			 */
			var width = 800;			//default value
			var height = 600;			//default value
			var name = 'wupsWindow';
			if ( options && options.width && this.number.isInteger(options.width) ) {
				width = options.width;
			} 
			if ( options && options.height && this.number.isInteger(options.height) ) {
				height = options.height;
			}
			//	sprawdzamy czy mamy wystarczajaco miejsca, aby wyswietlic okno o podanych wymiarach :
			if ( width > screen.availWidth ) {
				width = Math.floor(screen.availWidth*0.9);
			}	
			if ( height > screen.availHeight ) {
				height = Math.floor(screen.availHeight*0.9);
			}
			//alert('* f.wups : width: '+width+' , height: '+height);
			if ( options && options.name ) {
				name = options.name;
			}
			if ( name.length>10 ) {
				name = name.slice(0,10);
			}
			var parameters = 'menubar=no, toolbar=no, location=yes, width='+width+', height='+height+', left=30, top=30, scrollbars=yes, status=yes, resizable=yes';
			//	otwieramy okienko z HTML
			if ( options && options.html ) {
				//TEST sprawdzic czy html zawiera wszystkie potrzebne tagi i tylko wtedy wyswietlic zawartosc, ewentualnie olac ;)
				var newWin = window.open('', name, parameters);
				if ( newWin ) {
					with ( newWin.document ) {
						open('text/html', 'replace');
						write(options.html);
						close();
					};
				}
			} else {
				//	otwieramy normalne okienko z jakas strona
				//	sprawdzamy czy obecna strona ma jakies prID , jesli tak i w hrefie nie ma innego, to dodaj...
				var prid = f.getParam('prid');
				var pridHref = f.getParam('prid', { searchFrom: href} );
				if ( typeof prid != 'undefined' && prid && !pridHref ) {
					if ( href.test('?') ) {
						href += '&prid='+prid;
					} else {
						href += '?prid='+prid;
					}
				}
				var newWin = window.open(href, name, parameters);
				if ( newWin ) {
					newWin.focus();
				}
			}
			return true;
		}
		
	}
}();

