	/**
	 * valid.js
	 * 
	 * Plik zawierający całą warstwę zachowania dla inteligentnego formularza
	 * sprawdzającego wprowadzane dane.
	 *
	 * @author	Marcin Badurowicz <m at badurowicz dot net>
	 * @version	1.23
	 * @licence GNU Lesser General Public Licence v2.1
	 */
	 
	// sprawdzanie czy występują tylko dozwolone znaki w stringu
	function test(acceptChars, str)
	{
		// do acceptChars można wpisać stałe znakowe pewne, żeby było
		// krócej
		var aChars = acceptChars;
		aChars = aChars.replace('a-z', 'abcdefghijklmnopqrstuvwxyz');
		aChars = aChars.replace('A-Z', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
		aChars = aChars.replace('&PLL', 'ąćęóńłżźś');
		aChars = aChars.replace('&PLU', 'ĄĆĘÓŃŁŻŹŚ');
		aChars = aChars.replace('0-9', '1234567890');		
		aChars = aChars.replace('\-', '-');
		
		for (var i = 0; i < str.length; i++)
		{
			if (aChars.indexOf(str.charAt(i)) == -1)
				return false;
		}
		
		return true;
	}
	
	// sprawdzanie czy string pasuje do wyrażenia regularnego
	function testRegex(regexp, str)
	{
		return str.match(regexp);
	}
	
	// pokazywanie błędu
	function showError(field, msg, add)
	{
		var a = document.getElementById(field + "_error");		
		if (a)
		{
			if (!add)
				a.innerHTML = msg;
			else
				a.innerHTML += '<br>' + msg;
			
			if (msg != '')
				a.className = 'error';
			else
				a.className = '';
		}
		
		if (document.getElementById(field))
			document.getElementById(field).className = 'error';
	}
	
	// usuwanie pokazywania błędu
	function clearError(field)
	{
		showError(field, '', false);
		if (document.getElementById(field))
			document.getElementById(field).className = '';
	}
	
	// funkcja, która zamienia niepoprawne formatowanie
	// imienia/nazwiska na poprawne (pierwsza litera wielka,
	// reszta małe, chyba że po myślniku, to wtedy wielka)
	function makeProperCase(s)
	{				
		var p = s.substr(0, 1);
		p = p.toUpperCase();
		p = p.concat(s.substr(1).toLowerCase());
		if (p.indexOf('-') != -1)
		{
			p = p.substr(0, p.indexOf('-') + 1) + makeProperCase(p.substr(p.indexOf('-') + 1));
		}
		
		return p;
	}
			
	// -------------------------------- FUNKCJE SPRAWDZAJCE --------------------------------

	// funkcja sprawdzająca, czy imie jest dobre
	function testImie()
	{					
		var a = document.getElementById('imie').value;
		if (!test("a-zA-Z&PLL&PLU", a) || a.length < 3 || a.length > 15)
		{
			showError('imie', "Imię nie jest poprawne", false);
			return false;
		}
		else
		{					
			document.getElementById('imie').value = makeProperCase(a);
			clearError('imie');
			return true;
		}
	}
	
	function testImieRegex()
	{
		var a = document.getElementById('imie').value;
		if (!testRegex(/^[A-Za-zĄĆĘÓŃŁŻŹŚąćęóńłżźś]{3,15}$/, a))
		{
			showError('imie', "Imię nie jest poprawne", false);
			return false;
		}
		else
		{					
			document.getElementById('imie').value = makeProperCase(a);
			clearError('imie');
			return true;
		}
	}
	
	// funkcja sprawdzająca, czy nazwisko jest dobre
	function testNazwisko()
	{			
		var a = document.getElementById('nazwisko').value;
		if (!test("a-zA-Z&PLL&PLU\-", a) || a.length < 3 || a.length > 20)
		{
			showError('nazwisko', "Nazwisko nie jest poprawne", false);
			return false;
		}
		else
		{					
			document.getElementById('nazwisko').value = makeProperCase(a);
			clearError('nazwisko');
			return true;
		}
	}
	
	function testNazwiskoRegex()
	{
		var a = document.getElementById('nazwisko').value;
		if (!testRegex(/^[A-Za-z\-ĄĆĘÓŃŁŻŹŚąćęóńłżźś]{3,20}$/, a))
		{
			showError('nazwisko', "Nazwisko nie jest poprawne", false);
			return false;
		}
		else
		{					
			document.getElementById('nazwisko').value = makeProperCase(a);
			clearError('nazwisko');
			return true;
		}
	}
	
	// funkcja sprawdzająca poprawność kodu pocztowego
	function testKod()
	{
		var a = document.getElementById('kod_p').value;
		var b = a.indexOf('-');
				
		if ((b != -1) && (a.length == 6) && (a.substr(0, b).length == 2))
		{			
			var c = a.substr(0, b) + a.substr(b + 1);
			if (!test('0-9', c))
			{
				showError('kod_p', 'Kod pocztowy tworzą tylko cyfry i myślnik');				
				return false;
			}
		}
		else
		{
			showError('kod_p', 'Kod pocztowy ma zły format, długość lub nie zawiera myślnika');			
			return false;
		}
		
		clearError('kod_p');
		return true;
	}
	
	function testKodRegex()
	{
		var a = document.getElementById('kod_p').value;		
		if (!testRegex(/^([0-9]){2}\-([0-9]){3}$/, a))
		{
			showError('kod_p', "Kod pocztowy nie jest poprawny", false);			
			return false;
		}
		else
		{								
			clearError('kod_p');
			return true;
		}
	}
	
	// funkcja sprawdzająca poprawność adresu
	function testAdres()
	{		
		clearError('adres');
		clearError('ulica');
		clearError('numer_d');
		
		var err = false;
		var ulica = document.getElementById('ulica').value;
		var numer = document.getElementById('numer_d').value;
				
		if (!test('a-zA-Z0-9&PLL&PLU\- ', ulica) || ulica.length < 3)
		{
			showError("adres", 'Nazwa ulicy nie jest poprawna', false);
			showError('ulica', '');
			err = true;
		}
				
		if (!test('0-9A-Z/', numer) || numer.length < 1)
		{			
			showError('adres', 'Numer domu i/lub mieszkania nie jest poprawny', true);
			showError('numer_d', '');
			err = true;			
		}
		
		if (!err)
		{
			clearError('adres');
			clearError('ulica');
			clearError('numer_d');
		}
		
		return !err;
	}
	
	function testAdresRegex()
	{
		clearError('adres');
		clearError('ulica');
		clearError('numer_d');
		
		var err = false;
		var ulica = document.getElementById('ulica').value;
		var numer = document.getElementById('numer_d').value;
				
		if (!testRegex(/^[a-zA-Z0-9\- ĄĆĘÓŃŁŻŹŚąćęóńłżźś]{3,25}$/, ulica))
		{
			showError("adres", 'Nazwa ulicy nie jest poprawna', false);
			showError('ulica', '');
			err = true;
		}
				
		if (!testRegex(/^[0-9A-Z]{1,5}(\/[0-9A-Z]{1,5})?$/, numer))
		{			
			showError('adres', 'Numer domu i/lub mieszkania nie jest poprawny', true);
			showError('numer_d', '');
			err = true;			
		}
		
		return !err;
	}
	
	// funkcja sprawdzająca miasto
	function testMiasto()
	{					
		var a = document.getElementById('miasto').value;
		if (!test('a-zA-Z&PLL&PLU\- ', a) || a.length < 3 || a.length > 30)
		{
			showError('miasto', "Miasto nie jest poprawne", false);
			return false;
		}
		else
		{					
			document.getElementById('miasto').value = makeProperCase(a);
			clearError('miasto');
			return true;
		}
	}
	
	function testMiastoRegex()
	{
		var a = document.getElementById('miasto').value;
		if (!testRegex(/^[A-Za-z\- ĄĆĘÓŃŁŻŹŚąćęóńłżźś]{3,30}$/, a))
		{
			showError('miasto', "Miasto nie jest poprawne", false);
			return false;
		}
		else
		{					
			document.getElementById('miasto').value = makeProperCase(a);
			clearError('miasto');
			return true;
		}
	}
	
	// sprawdzenie poprawności adresu e-mail
	function testEmail()
	{
		var a = document.getElementById('email').value;
		a = a.toLowerCase();
		
		var b = a.indexOf('@')
		if (b == -1)
		{
			showError('email', 'E-mail nie jest poprawny, powinien zawierać znak "@"');
			return false;
		}
		else
		{
			var c = a.substr(0, b);
			var d = a.substr(b + 1);
			if (!test('a-z0-9+._', c) || c.length == 0)
			{
				showError('email', 'E-mail nie jest poprawny, nieprawidłowe znaki w nazwie użytkownika');
				return false;
			}
			else
			{
				if (!test('a-z0-9._\-', d) || d.length < 4)
				{
					showError('email', 'E-mail nie jest poprawny, nieprawidłowe znaki w domenie');
					return false;
				}
			}
		}
		
		clearError('email');
		document.getElementById('email').value = a;
		return true;
	}
	
	function testEmailRegex()
	{
		var a = document.getElementById('email').value;
		if (
			!testRegex(/^([a-z0-9+_-]+)(\.[a-z0-9+_-]+)*@([a-z0-9-]+\.)+[a-z]{2,6}(\.)?$/, a) &&
			!testRegex(/^([a-z0-9+_-]+)(\.[a-z0-9+_-]+)*@\[([0-9]{1,3}\.){3}([0-9]{1,3})\]$/, a)
		   )
		{
			showError('email', "E-mail nie jest poprawny", false);
			return false;
		}
		else
		{					
			clearError('email');
			return true;
		}
	}
	
	// sprawdzanie poprawności numeru PESEL
	function testPESEL()
	{		
		var err = false;
		var a = document.getElementById('pesel').value;
		
		var plec;
		var wiek;
		
		// długość zła, albo litery w peselu
		if (!test('0-9', a) || a.length != 11)
		{
			showError('pesel', 'PESEL jest nieprawidłowy: nieprawidłowa długość lub zawartość');
			err = true;
		}
		else
		{
			// obliczanie sumy kontrolnej
			var contr = a.charAt(0) * 1 + a.charAt(1) * 3 + a.charAt(2) * 7 + a.charAt(3) * 9 + a.charAt(4) * 1 
						+ a.charAt(5) * 3 + a.charAt(6) * 7 + a.charAt(7) * 9 + a.charAt(8) * 1 + a.charAt(9) * 3;
			
			contr = (10 - contr%10)%10;			
			if (contr != a.charAt(10))
			{
				showError('pesel', 'PESEL jest nieprawidłowy: niepoprawna suma kontrolna');				
				err = true;
			}
			else
			{
				// ustalanie płci (0 == kobieta)
				plec = a.charAt(9) % 2;
				
				// sprawdzanie daty urodzenia
				
				// długość poszczególnych miesięcy w roku
				var monthLengths = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
				var year = a.charAt(0) + a.charAt(1);
				var month = a.charAt(2) + a.charAt(3);
				var day = a.charAt(4) + a.charAt(5);
				
				// "specjalne" miesiące w peselu
				if (month > 80) // lata 1800-1899
				{
					month = month - 80;
					year = '18' + year;					
				}
				else if (month > 60) // lata 2200-2299
				{
					month = month - 60;
					year = '22' + year;
				}
				else if (month > 40) // lata 2100-2199
				{
					month -= 40;
					year = '21' + year;					
				}
				else if (month > 20) // lata 2000-2099
				{
					month -= 20;
					year = '20' + year;
				}
				else
				{
					year = '19' + year;
				}
						
				var year_prze = false;				
				// sprawdzanie roku przestępnego
				if (year % 4 == 0) // jeśli podzielny przez 4 to tak
				{
					year_prze = true; 
					if (year % 100 == 0) // jeśli podzielny przez 100 to nie
						year_prze = false;
						
					if (year % 400 == 0) // chyba, że podzielny jednak przez 400
						year_prze = true;
				}
				
				if (year_prze)
					monthLengths[1] = 29; // jeśli przestępny, to luty ma dodatkowy dzień
				
				// sprawdzenie, czy ten miesiąc ma wystarczająco dużo dni
				if (day <= monthLengths[month -1] && day > 0)
				{
					today = new Date();					
					if (today.getFullYear() <= year)
					{						
						err = true;
						showError('pesel', 'PESEL jest nieprawidłowy: nie mozna wypełniać tego formularza danymi z przyszłości ani danymi noworodków');
					}
					else
					{
						wiek = today.getFullYear() - year;
						err = false;
					}
				}
				else
				{					
					err = true;
					showError('pesel', 'PESEL jest nieprawidłowy: niepoprawna data urodzenia');
				}
			}
		}
		
		if (!err)
		{
			clearError('pesel');
			document.getElementById('wiek').value = wiek;
			
			if (plec == 0)
				document.getElementById('pk').checked = true;
			else
				document.getElementById('pm').checked = true;
		}
		else
		{
			document.getElementById('wiek').value = '';
			document.getElementById('pk').checked = false;
			document.getElementById('pm').checked = false;
		}
		
		return !err;
	}
	
	// obsługa naciskania klawiszy w polu komentarza
	function commentKeyPress(e)
	{	
		// dozwolone klawisze
		var keys = 
		{
		 36:1, // home i end
		 35:1,
         37:1, // 37 - strzalka w lewo
         38:1, // strzalka w gore
         39:1, // w prawo
         40:1, // w dol (chyba nie pomieszalem kolejnosci strzalek ;-P)
         8:1, // backspace
         46:1 // delete         
        };
         		
		var d = document.getElementById('comment');
		
		var keyCodeGood = true;
		
		if (this.event)
			keyCodeGood = event.keyCode in keys;
		else
			keyCodeGood = e.keyCode in keys;
		
		if ((d.value.length >= 250) && (!keyCodeGood))
		{
			return false;
		}
		else
		{			
			return true;
		}
	}
	
	// ustawianie licznika znaków
	function setCharCount()
	{
		var d = document.getElementById('comment');
		var t = document.getElementById('c_count');
		
		t.innerHTML = 250 - d.value.length;
		if (250 - d.value.length < 0 )
		{
			t.style.color = 'red';
		}
		else
			t.style.color = '';
	}
	
	// czyszczenie pola komentarza z nieprawidłowych znaków i testowanie
	// jego poprawności
	function clearComment()
	{
		var d = document.getElementById('comment');
		var n = '';		
		
		// usuwanie nieakceptowanych znaków
		for (var i = 0; i < d.value.length; i++)
		{
			if (test("a-zA-Z0-9%PLL&PLU\-.,;: ", d.value.charAt(i)))
			{				
				n += d.value.charAt(i);
			}			
		}				
		
		// usuwanie wielokrotnych spacji
		while (n.indexOf('  ') != -1)
			n = n.replace('  ', ' ');
		
		d.value = n;
		
		setCharCount();
		// zwraca czy długość zawartości nie jest większy niż limit
		if (document.getElementById('comment').value.length > 250)
		{
			showError('comment', 'Komentarz jest zbyt długi. Maksymalnie 250 znaków.');
			return false;
		}
		else
		{
			clearError('comment');
			return true;
		}
	}
	
	function testBeforeSubmit()
	{
		var err = false;
		
		if (document.getElementById('setNormalToggler').className == 'active')
		{			
			err = testImie() &&
			testNazwisko() &&
			testKod() &&
			testAdres() &&
			testMiasto() &&
			testEmail() &&
			testPESEL() &&
			clearComment();			
		}
		else
		{
			err = testImieRegex() &&
			testNazwiskoRegex() &&
			testKodRegex() &&
			testAdresRegex() &&
			testMiastoRegex() &&
			testEmailRegex() &&
			testPESEL() &&
			clearComment();
		}
				
		if (!err)
		{
			showError('form', "Formularz nie jest poprawnie wypełniony, nie można wysłać.")
			return false;
		}
		else
		{
			clearError('form');
			return true;
		}
	}
	
	// pytanie czy na pewno wykasować dane przyciskiem reset
	function askBeforeReset()
	{
		if (confirm('Czy jesteś pewien, żeby wykasować dane?'))
		{
			clearError('imie');
			clearError('nazwisko');
			clearError('kod_p');
			clearError('adres');
			clearError('miasto');
			clearError('regex');
			clearError('pesel');
			clearError('form');
			return true;
		}
		else
			return false;
	}
	
	// -------------------------- FUNKCJE INICJALIZACYJNE ------------------------------
	// podpinanie zdarzeń
	function init()
	{				
		document.getElementById('setNormalToggler').onclick = function() { setNormal(); return false; };
		
		document.getElementById('setRegexToggler').onclick = function() { setRegex(); return false; };
		setNormal();
		
		// te dwa pola zawsze są tak samo testowane
		document.getElementById('comment').onkeypress = function (e) { return commentKeyPress(e); };
		document.getElementById('comment').onkeyup = setCharCount;
		document.getElementById('comment').onblur = clearComment;
		
		document.getElementById('pesel').onblur = testPESEL;		
		document.getElementById('f').onsubmit = testBeforeSubmit;
		document.getElementById('reset').onclick = askBeforeReset;		
		setCharCount(); // aktualizacja licznika zdarzeń, żeby po F5 było widać dobrą informację
	}
	
	// podpinanie funkcji testujących normalnie
	function setNormal()
	{
		document.getElementById('imie').onblur = testImie;
		document.getElementById('nazwisko').onblur = testNazwisko;
		document.getElementById('ulica').onblur = testAdres;
		document.getElementById('numer_d').onblur = testAdres;
		document.getElementById('kod_p').onblur = testKod;
		document.getElementById('miasto').onblur = testMiasto;
		document.getElementById('email').onblur = testEmail;
		
		document.getElementById('setNormalToggler').className = 'active';
		document.getElementById('setRegexToggler').className = '';
		return false;
	}
	
	// podpianie funkcji testujących przez wyrażenia regularne
	function setRegex()
	{
		document.getElementById('imie').onblur = testImieRegex;
		document.getElementById('nazwisko').onblur = testNazwiskoRegex;
		document.getElementById('ulica').onblur = testAdresRegex;
		document.getElementById('numer_d').onblur = testAdresRegex;
		document.getElementById('kod_p').onblur = testKodRegex;
		document.getElementById('miasto').onblur = testMiastoRegex;
		document.getElementById('email').onblur = testEmailRegex;	
		
		document.getElementById('setNormalToggler').className = '';
		document.getElementById('setRegexToggler').className = 'active';
		return false;
	}
	
	// podpięcie zdarzenia do window.onload
	window.onload = init;
	//alert('b');
