/**
*
* JavaScript knihovna s metodami pro validaci textových údajů
*
* @package		sllibs3
* @subpackage	jslibs
* @version		$Id: sl.validator.js 7378 2009-02-06 16:58:38Z michal $
* @encoding		utf-8
* @author		Michal Kouďa <michal.kouda@e4you.cz>
* @copyright	(c) e4you spol. s r.o. 2002-2008, <design@e4you.cz>
*
* Obsah tohoto souboru je majetkem e4you spol. s r.o. Jeho kopírování,
* pozměňování, šíření a jakékoli další využití je možné výhradně
* se souhlasem e4you spol. s r.o.
*
* @todo dopsat jednotkove testy
*
*/

/// pokud neexistuje jmenny prostor sl vytvorime ho
if(!sl) { var sl = {} };

/// definujeme modul a jeho metody
sl.validator = {

	/// požadovaná minimální délka přihlašovacího jména
	LOGIN_MIN_LENGTH: 5,

	/// požadovaná minimální délka přihlašovacího jména
	LOGIN_MAX_LENGTH: 48,

	/// požadovaná délka hesla
	PASSWORD_MIN_LENGTH: 8,

	/// jména top level domén pro metodu validDomainName
	TOP_LEVEL_DOMAINS: 'ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zr|zw|com|edu|gov|int|mil|net|org|info|biz|aero|cat|coop|jobs|mobi|museum|pro|travel|name|co.cz|co.uk|me.uk|org.uk|co.jp|com.cn|org.cn|net.cn|com.tw|org.tw|idv.tw|co.nz|org.nz|net.nz|com.tr|gen.tr|org.tr|biz.tr|info.tr|av.tr|dr.tr|pol.tr|bel.tr|mil.tr|bbs.tr|k12.tr|edu.tr|name.tr|net.tr|gov.tr|web.tr|tel.tr',


	/**
	* Kontroluje jestli je parametr integer nebo řetězec ve formátu celého čísla
	*
	* @param mixed hodnota o níž chceme zjistit, jestli je ve formátu celého čísla
	* @return boolean
	*/
	validInteger: function(_integer) {
		/// buď jde o integer
		if(typeof _integer == 'number' && _integer == Math.round(_integer)) return true;
		/// nebo ověříme jestli jde o řetězec ve tvaru integer
		return /^[+-]?[0-9]+$/.test(_integer);
	},


	/**
	* Pokud je parametr neprázdný, zkontroluje jestli je parametr řetězec ve formátu celého čísla
	*
	* @param mixed hodnota o níž chceme zjistit, jestli je ve formátu celého čísla
	* @return boolean
	*/
	validIntegerOrEmpty: function(_integer) {
		if(_integer) {
			return sl.validator.validInteger(_integer);
		} else {
			return true;
		}
	},


	/**
	* Kontroluje jestli je parametr řetězec ve formátu čísla v plovoucí řádové čárce
	*
	* @param mixed hodnota o níž chceme zjistit, jestli je ve formátu čísla v plovoucí řádové čárce
	* @return boolean
	*/
	validFloat: function(_float) {
		/// buď jde o float
		if(typeof _float == 'number' && _float != Math.round(_float)) return true;
		/// nebo ověříme jestli jde o řetězec ve tvaru float
		return /^[+-]?[0-9]*\.[0-9]+$/.test(_float);
	},


	/**
	* Kontroluje jestli je parametr řetězec ve formátu čísla
	*
	* @param mixed hodnota o níž chceme zjistit, jestli je ve formátu čísla
	* @return boolean
	*/
	validNumber: function(number) {
		return sl.validator.validInteger(number) || sl.validator.validFloat(number);
	},


	/**
	* Pokud je parametr neprázdný, zkontroluje jestli je parametr řetězec ve formátu čísla
	*
	* @param mixed hodnota o níž chceme zjistit, jestli je ve formátu čísla
	* @return boolean
	*/
	validNumberOrEmpty: function(number) {
		if(number) {
			return sl.validator.validNumber(number);
		} else {
			return true;
		}
	},


	/**
	* Kontroluje jestli je parametr telefonní číslo ve správném formátu
	*
	* @param mixed hodnota o níž chceme zjistit, jestli je telefonní číslo
	* @return boolean
	*/
	validPhone: function(phone) {
		return /^[+]?[0-9 ]{9,}$/.test(phone);
	},


	/**
	* Pokud je parametr neprázdný, zkontroluje jestli je parametr telefonní číslo ve správném formátu
	*
	* @param mixed hodnota o níž chceme zjistit, jestli je telefonní číslo
	* @return boolean
	*/
	validPhoneOrEmpty: function(phone) {
		if(phone) {
			return sl.validator.validPhone(phone);
		} else {
			return true;
		}
	},


	/**
	* Kontroluje jestli je parametr e-mailová adresa ve správném formátu
	*
	* @param mixed hodnota o níž chceme zjistit, jestli je ve formátu e-mailové adresy
	* @return boolean
	*/
	validEmail: function(email) {
		return /^[a-z0-9._+-]+@[a-z0-9._-]+\.[a-z]{2,7}$/i.test(email);
	},


	/**
	* Pokud je parametr neprázdný, zkontroluje jestli je parametr e-mailová adresa ve správném formátu
	*
	* @param mixed hodnota o níž chceme zjistit, jestli je ve formátu e-mailové adresy
	* @return boolean
	*/
	validEmailOrEmpty: function(email) {
		if(email) {
			return sl.validator.validEmail(email);
		} else {
			return true;
		}
	},


	/**
	* Kontroluje jestli je parametr čas ve správném formátu
	*
	* @param mixed hodnota o níž chceme zjistit, jestli je ve formátu času
	* @return boolean
	*/
	validTime: function(time) {
		return /^[0-2][0-9]:[0-5][0-9](:[0-5][0-9])?$/i.test(time);
	},


	/**
	* Kontroluje jestli je parametr PSČ ve správném formátu
	*
	* @param mixed hodnota o níž chceme zjistit, jestli je ve formátu PSČ
	* @return boolean
	*/
	validPSC: function(psc) {
		return typeof psc == 'string' && /^[0-9]{5}$/.test(psc.replace(/ /gi,''));
	},


	/**
	* Kontroluje jestli je parametr IČ ve správném formátu
	*
	* @param mixed hodnota o níž chceme zjistit, jestli je ve formátu IČ
	* @return boolean
	*/
	validIC: function(ic) {
		if(! /^[0-9]{8}$/.test(ic)) {
			return false;
		}

		/// spočítáme kontrolní součet
		var check_sum = 0;
		for(var i=0; i<7; i++) {
			check_sum += (8 - i) * ic.charAt(i) ;
		}
		check_sum %= 11;

		/// vypočteme správnou poslední číslici
		if (check_sum === 0 || check_sum === 10) {
			var last_digit = 1;
		} else if (check_sum === 1) {
			var last_digit = 0;
		} else {
			var last_digit = 11 - check_sum;
		}

		return (last_digit === parseInt(ic.charAt(7)));
	},


	/**
	* Pokud je parametr neprázdný, zkontroluje jestli je parametr parametr IČ ve správném formátu
	*
	* @param mixed hodnota o níž chceme zjistit, jestli je ve formátu IČ
	* @return boolean
	*/
	validICOrEmpty: function(ic) {
		if(ic) {
			return sl.validator.validIC(ic);
		} else {
			return true;
		}
	},


	/**
	* Kontroluje jestli je parametr DIČ ve správném formátu
	*
	* @param mixed hodnota o níž chceme zjistit, jestli je ve formátu IČ
	* @return boolean
	* @todo upravit kontrolu tak, aby pokud jde o DIC slozene z CZ + IC se zkontrolovala validita IC
	* @todo upravit kontrolu tak, aby pokud jde o DIC slozene z CZ + rodne cislo se zkontrolovala validita rodneho cisla
	*/
	validTaxNo: function(tax_no) {
		return /^([a-z]{2}|[0-9]{3}-)[0-9]{8,10}$/i.test(tax_no);
	},


	/**
	* Kontroluje jestli je parametr IP adresa (ip verze 4)
	*
	* @param mixed hodnota o níž chceme zjistit, jestli je IP adresa
	* @return boolean
	*/
	validIp: function(ip) {
		if(/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/.test(ip)) {
			var octets = ip.split('.');
			return	(octets[0]>=0) && (octets[0]<256)
					&& (octets[1]>=0) && (octets[1]<256)
					&& (octets[2]>=0) && (octets[2]<256)
					&& (octets[3]>=0) && (octets[3]<256);
		}
		return false;
	},


	/**
	* Kontroluje jestli je parametr seznam IP adres (ip verze 4)
	*
	* @param mixed hodnota o níž chceme zjistit, jestli jde o seznam IP adres
	* @return boolean
	* @todo dodělat kontrolu jestli všechny oktety jsou 0-255
	*/
	validIpList: function(ip_list) {
		return /^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(\/[0-9]{1,2})?(, ?)?)+$/.test(ip_list);
	},


	/**
	* Kontroluje jestli je parametr doménové jméno
	*
	* @param mixed hodnota o níž chceme zjistit, jestli jde o doménové jméno
	* @return boolean
	*/
	validDomainName: function(domain_name) {
		if(/^[a-z0-9_-]+\.[a-z0-9_-]+\.name$/i.test(domain_name)) {
			return true;
		}
		var domain_re = new RegExp('^[a-z0-9_-]+\\\.(' + sl.validator.TOP_LEVEL_DOMAINS.replace(/\./g,'\\\.') + ')$','ig');
		return domain_re.test(domain_name);
	},


	/**
	* Kontroluje jestli je parametr login ve správném formátu
	*
	* @param mixed hodnota o níž chceme zjistit, jestli jde o login ve správném formátu
	* @return boolean
	*/
	validLogin: function(login) {
		if(login.length < sl.validator.LOGIN_MIN_LENGTH) return false;
		if(login.length > sl.validator.LOGIN_MAX_LENGTH) return false;
		return /^[a-z0-9_.-]+$/i.test(login);
	},


	/**
	* Kontroluje jestli je parametr heslo ve správném formátu
	*
	* Následující funkce (asi jen ve Firefoxu?) nepracovala správně, pokud nebyly regulární
	* výrazy explicitně vytvořeny konstruktorem RegExp()
	*
	* Zkrácená forma regulárního výrazu ( /[a-z]+/ig.test(passwd) ) zřejmě náhodně vracela
	* true a false - bylo by dobré to ověřit pomocí jednotkových testů
	*
	* @param mixed hodnota o níž chceme zjistit, jestli jde o heslo ve správném formátu
	* @return boolean
	*/
	validPasswd: function(_passwd) {
		if(_passwd.length < sl.validator.PASSWORD_MIN_LENGTH) return false;
		var check_number = new RegExp('[0-9]+');
		if(!check_number.test(_passwd)) return false;
		var check_letter = new RegExp('[a-z]+','ig');
		if(!check_letter.test(_passwd)) return false;
		return true;
	},


	/**
	* Kontroluje jest-li předaná hodnota formulářového pole správná reprezenatace hesla
	*
	* @param mixed hodnota o níž chceme zjistit, jestli jde o správnou reprezenataci hesla
	* @return boolean
	*/
	validPasswdField: function(_passwd) {
		if(_passwd === '******') return true;
		return sl.validator.validPasswd(_passwd);
	},

	/**
	* Kontroluje jestli je parametr EAN ve správném formátu
	*
	* @param mixed hodnota o níž chceme zjistit, jestli je ve formátu EAN
	* @return boolean
	*/
	validEAN: function(ean) {

		if(typeof ean != 'string') {
			return false;
		}

		/// odstraníme z ean kódu znaky ' ', '-' a '.'
		var code = ean.replace(/[ .-]/g,'');

		/// pokud nejde o číslo dlouhé 13 nebo 8 zaků není to EAN
		if(! /^([0-9]{13}|[0-9]{8})$/.test(code)) {
			return false;
		}

		/// spočteme kontrolní součet
		var check_sum = 0;
		/// projdeme kod a sečteme jednotlivé číslice
		for(var i=0; i<code.length; i++) {
			/// pokud jde o omsimístný kod, každou lichou číslici vynásobíme 3
			/// pokud jde o třináctimístný kod, každou sudou číslici vynásobíme 3
			/// přitom znaky počítáme od 0
			if(	(code.length == 8 && i%2==0)
				||	(code.length == 13 && i%2==1)
			   )  {
				check_sum +=  parseInt(code.charAt(i)) * 3;
			} else {
				check_sum +=  parseInt(code.charAt(i));
			}
		}

		/// pokud je kontrolní součet dělitený 10 jde o EAN
		return (check_sum % 10 == 0);
	},


	/**
	* Pokud je parametr neprázdný, zkontroluje jestli je parametr EAN ve správném formátu
	*
	* @param mixed hodnota o níž chceme zjistit, jestli je ve formátu EAN
	* @return boolean
	*/
	validEANOrEmpty: function(ean) {
		if(ean) {
			return sl.validator.validEAN(ean);
		} else {
			return true;
		}
	}

}

