/**
 *	@todo 		- po wpisaniu _MIN_ZNAKOW pokazujemy listę, a następnie przy wpisywania kolejnych liter tylko sprawdzamy które <li> usunąć.
 *				- przy usuwaniu znaków ładujemy od nowa (jak teraz) lub przechowuje gdzieś listę wartości dla _MIN_ZNAKOW 
 *
 */
 
var podpowiadacz = function(){
	/**
	 *	@require input musi być w jakims divie najlepiej, 
	 *	do którego jest 'wsadzany' spreparowany ul z podpowiedziami
	 */
	 
	/* configuration */
	var _MIN_ZNAKOW			= 2;			//	po wpisaniu ilu znakow pojawia sie podpowiedz
	var _CASE_SENSITIVE		= true;			//	czy ma brać pod uwagę wielkość liter ?
	
	/* private */
	
	var _aktywny 		= false;			//	czy aktualnie cos podpowiadamy ?
	var _pTimer 		= false;			//	timer podpowiadacz.
	var _slownik 		= false;			//	tablica z wartościami do podpowiadania
	var _input 			= false;			//	obiekt $() wskazujący na element input, do którego użytkownik coś wpisuje
	var _pID			= false;			//	id elementu ul, który zawiera listę podpowiedzi
	var _value			= '';				//	wartosc inputa po ostatniej zmianie ( służy do tego, aby sprawdzić czy wartośćj 
											//	została zmienione, jeśli nie, np przy keydown to nie pokażemy podpowiedzi)
	var _fn 			= false;			//	funkcja do uruchomienia, po wybraniu jakiejs opcji, jako parametr przekazywana jest
											//	wybrana wartość z podpowiadanych lub wpisana przez użytkownika1
	
	/* obsluga klawiatura */
	var _selected		= false;			//	true / false
	var _activeElement	= false;			//	aktywny element na liscie podpowiadacza ( $(li) )
	
	
	function podpowiadaj() {
		//	resetujemy obsluge strzalek...
		_selected = false
		_activeElement = false;
		var znalezionoPodpowiedz = false;
		var value = _input.val();
		/* jest wpisana zostala jakas wartosci ma odpowiednia ilosc znakow (minimum _MIN_ZNAKOW znakow) 
			i jest ona rozna od poprzednio wpisanej, aby wykluczyc ponowne ladowanie listy przy wcisnieciu np strzalek */
		if ( value && value.length >= _MIN_ZNAKOW && value != _value ) {
			_value = value;
			//	usuwanie zawrrtosci istniejacego ula, tworzenie ula podpowiadacza, jesli nie istnieje
			$(_pID).empty();
			var ul = $(_pID);
			if ( !ul.length ) {
				//	jesli nie utworzylismy jeszcze ula, utworzmy go
				ul = $('<ul></ul>').attr('id', _pID.slice(1) ).addClass('podpowiadacz').hide();
				ul.appendTo( _input.parent() );
			}
			if ( _CASE_SENSITIVE ) {
				var V = new RegExp(value, 'g');
			} else {
				var V = new RegExp(value,'ig'); 
			} 
			//	sprawdzamy wartości słownikowe
			for ( var i=0, ile=_slownik.length; i<ile; i++ ) {
				if ( _slownik[i] && V.test( _slownik[i] ) ) {
					znalezionoPodpowiedz = true;
					var li = $('<li></li>');
					var a = $('<a></a>');
					li.append(a);
					if ( value.indexOf(' ') >= 0 ) {
						var sIndex = value.indexOf(' ');
						if ( sIndex+2 >= value.length ) {
							sIndexEnd = value.length;
						} else {
							sIndexEnd = sIndex+2;
						}
						var valU = value.charAt(0).toUpperCase() + value.slice(1, sIndex) +' ' + value.charAt(sIndex+1).toUpperCase() + value.slice(sIndexEnd);
					} else {
						var valU = value.charAt(0).toUpperCase() + value.slice(1);
					}
					echo('valU : '+valU);
					// if ( _CASE_SENSITIVE ) {
						 var V_u = new RegExp(".*"+valU+".*", 'g');
						 var V_ = new RegExp(".*"+value+".*", 'g');
					// } else {
						// var V_u = new RegExp(".*"+valU+".*", 'ig');
						// var V_ = new RegExp(".*"+value+".*", 'ig');
					// }
					if ( V_.test( _slownik[i] ) ) {
						a.html( _slownik[i].replace(value, '<strong>'+value+'</strong>') );
					}
					else if ( V_u.test( _slownik[i] ) ) {
						a.html( _slownik[i].replace(valU, '<strong>'+valU+'</strong>') ) ;
					} else {
						a.html( _slownik[i] );
					}
					
					a.click( function() {
						_input.val( $(this).text() );
						ul.hide(10);
						if ( _fn && typeof _fn == 'function' ) {
							setTimeout( function() { _fn.call(_input, _input.val() ); }, 30);
						}
					}).hover( function() {
							if ( _selected ) {
								_activeElement.removeClass('active');
								_selected = false;
								_activeElement = false;
							}
							$(this).parent().addClass('active');
						}, function() {
							$(this).parent().removeClass('active');
					});
					ul.append(li);
				};
			};
			if (znalezionoPodpowiedz) {
				//	_input.css() ?
				ul.slideDown();
			} else {
				//	_input.css() ?
				ul.slideUp().remove();
			}
		};
		
	};
	
	/* public */
	return {
		init:	function( input, slownik, fn, caseSensitive ){
		/**
		 *	@param input w ktorym bedzie cos wpisywane
		 *	@param slownik - tablica z wartosciami do podpowiedzi
		 *	@param fn 	- funkcja do wykonania po wybraniu opcji - przekazana do niej zostanie wybrana wartosc
		 *	@param caseSensitive - jesil false, to nie bedzie brane pod uwage wielkosci liter
		 *
		 **/
			if ( !input || !slownik || !slownik.length ) {
				return false;
			}
			if ( caseSensitive === false ) { _CASE_SENSITIVE = false; }
			if ( typeof fn == 'function' ) {
				_fn = fn;
			}
			_input = $(input);
			_slownik = slownik;
			_pID = '#'+_input.attr('name')+'_podpowiadacz';		//	podpowiadacz ID na bazie input@name.
			_input.keydown( function(e) {
				if ( e.keyCode == 13 ) {		//	sprawdzic czy cos jeste selected
					$(_pID).fadeOut(10);
					if ( _selected && _activeElement ) {		//	jesli mamy cos zaznaczone, to zmienmy wartosc inputa..
						_input.val( _activeElement.text() );
						_value = _activeElement.text();
					}
					if ( _fn ) {
						setTimeout( function() { _fn.call(_input, _input.val() ); }, 30);
					}
					return false;
				} 
				else if ( e.keyCode == '40' || e.keyCode == '38' ) {			//	obsluga strzalek
					//	czy pokazany podpowiadacz?
					//alert(_pID);
					if ( !_aktywny ) {
						//return false;
					}
					var ul = $(_pID);
					if ( ul.length == 0 ) {
						throw new Error('Nie znalazłem ula');
					}
					if ( !_selected ) {			// czy cos juz zaznaczylismy?
						_selected = true;
					}
					if ( _activeElement) {		//	jesli mamy jakis zaznaczony, to odznaczmy
						_activeElement.removeClass('active');
					}
					if ( e.keyCode == '40' ) {
						//	strzalka w dol
						//	jesli nie ma zadnego zaznacz pierwszy
						//	jesli aktywny to jest ostatni element, to zaznacz pierwszy :)
						if ( !_activeElement || !_activeElement.next().length ) {
							//echoN('40 -> first');
							_activeElement = ul.find('li:first');
						} else {
							//echo('40 -> next()');
							_activeElement = _activeElement.next();
						}
					} else if ( e.keyCode == '38' ) {
						//	strzalka w górę
						//	jesli nie ma aktywnego, to zaznacz ostatni
						//	jesli aktywny jest pierwszy (nie znaleziono prev), zaznacz ostatni
						if ( !_activeElement || !_activeElement.prev().length ) {
							//echoN('38 -> last');
							_activeElement = ul.find('li:last');
						} else {
							//echo('38 -> prev()');
							_activeElement = _activeElement.prev();
						}
					}
					if ( _activeElement.length ) {
						//echo('activeElement found');
						_activeElement.addClass('active');
					} else {
						//echo('active empty');
						_selected = false;
					}
					return false;
				}
				if ( _aktywny && _pTimer ) {
					clearTimeout(_pTimer);
				}
				_pTimer = setTimeout(function() { podpowiadaj(); }, 300);
				_aktywny = true;
			}).blur( function() {
				_pTimer = setTimeout( function() { $(_pID).fadeOut().remove() }, 100); 
			});

		
		}
	};
	
}();

$(function(){

	/**
		@example 
		
		podpowiadacz.init( '#partner', partners, function(){
			echo('przekazano '+arguments.length+' argumentow do funkcji');
			echo('wartosc pierwszego : '+arguments[0]);
		});
		
	*/

});