var validators = new Hash();
var help = new function(){
    var obj = new Object();
    var i = 0;
    
	obj.bgcolor_error = '#FFBFBF';
	obj.bgcolor_ok = '#FFFFFF';
	
	obj.ok = function(obj,vg,msg){
		//raport o wywolaniu
		obj = $(obj);
		if(!obj){
			return false;
		}
		d('help.OK('+ obj.id +','+ vg + ','+msg + ')');
		//odszukuje w rejestrze
		g = validators.get(obj.id);
		var isFinded = false;
		var im = $(obj.id + '_i');
		var en = $(obj.id + '_en');
		if(!g){
			//nie ma nic w rejestrze - blad, cos powinno byc, zeruje
			//d('Dla helpera, obiektu: ' + obj.id + ' Powinno byc cos zarejestrowane'); 
			obj.style.background = 'transparent';
			obj.title = '';
			if(im){
				im.setStyle({visibility : 'hidden'});
				im.alt = null;
				im.title = null;
			}
			if(en){
				//sprawdzam czy takie pole rzeczywiscie istnieje, na wszelki wypadek
				en.innerHTML = '';	
			}
			return false;
		}
		var before = g.length;
		isFinded = g.find(function(e){
				if(e == vg){
					//wyjecie z tablicy
					g = g.without(vg);
					validators.set(obj.id,g)
					return true;
				};
				return false;
		});
		//sprawdz czy tablica jest pusta jesli tak wywolaj efekt OFF.
		//d('Tablica obiektu id:' + obj.id + ', ma ' + g.length + ' elementow');
		
		if(g.length == 0){
			if(before > 0){
				new Effect.Highlight(obj, {startcolor: this.bgcolor_error, endcolor: this.bgcolor_ok, restorecolor: this.bgcolor_ok});
			}
			obj.style.background = this.bgcolor_ok;
			obj.title = msg;
			if(im){
				im.setStyle({visibility : 'hidden'});
				im.alt = null;
				im.title = null;
			}
			if(en){
				//sprawdzam czy takie pole rzeczywiscie istnieje, na wszelki wypadek
				en.innerHTML = '';
			}
		}	
	};
	obj.msg = function (obj,vg,msg){
		obj = $(obj);
		//raport o wywolaniu
		
		d('MSG ' + obj.id + ' : ' + msg);	
		g = validators.get(obj.id);
		var isFinded = false;
		
		if(!g){
			//dodaje do listy globalnej validators identyfikator validatora w grupie pola 
			validators.set(obj.id,[vg]);
			g = validators.get(obj.id);
			
		}else{
			//mamy obiekt, sprawdzam czy posiada juz wiezy zeby nie nadpisywac
			//upewniam sie ze element taki juz istnieje w rejestrze
			isFinded = g.find(function(e){
				if(e == vg){
					//d('[[Odszukalem obiekt');
					return true;
				};
				return false;
			});
			if(!isFinded){
				//wprowadzam na stos element
				g.push(vg);				
			}
		}
		var im = $(obj.id + '_i');
		var en = $(obj.id + '_en');
		if(!isFinded){
			new Effect.Highlight(obj, {endcolor: this.bgcolor_error,restorecolor: this.bgcolor_error});
			//obj.style.background = this.bgcolor_error;
		}
//		if(!im){
//			notify = new Element('span');
//			notify.id = obj.id + '_hint';
//			
//			notify.innerHTML = '!'
//			var parent = obj.parentNode.appendChild(notify);
//		}
		if(im){
			im.setStyle({visibility : 'visible'});
			im.title = msg;
			im.alt = msg;
		}
		if(en){
			en.innerHTML = msg;
			en.show();
		}
		obj.title = msg;
	};
	return obj;

};
var vc = new Class.create({
	ele : null,//to jest wskaznik do aktualnie analizowanego obiektu.
	a : {},//lista parametrow w postaci obiektu.
	ok : function(msg){
		help.ok(this.e,this.type,msg);
	},	
	msg : function(msg){
		help.msg(this.e,this.type,msg);
	},
	initialize: function(obj,p) {
		
		obj = $(obj);
		this.e = obj;
		this.p = p;
		this.valid();
	}
});

var vc_int = new Class.create(vc,{
	type : 'int',
	valid : function (){
		d('[[new VC_int]]');
		this.e.value = this.e.value.replace(',','.');
		if(isNaN(Math.floor(this.e.value))){
			this.e.value = 0;
		}
		this.e.value = Math.floor(this.e.value);
		if(this.e.value < this.p.min){
			this.msg('Zbyt mała wartosc, dopuszczalne: '+this.p.min+'..'+this.p.max);
		}else if(this.e.value > this.p.max){
			this.msg('Zbyt duża wartosc, dopuszczalne: '+this.p.min+'..'+this.p.max);
		}else{
			this.ok();
		}
	}	
});
var vc_float = new Class.create(vc,{
	type : 'float',
	valid : function (){
		d('[[new VC_float]]');
		this.e.value = this.e.value.replace(',','.');
		if(isNaN(this.e.value)){
			this.e.value = 0;
		}
		if(this.p.after_dot){
			var n = new Number(this.e.value);
			this.e.value = n.toFixed(this.p.after_dot);
		}
		if(this.e.value < this.p.min){
			this.msg('Zbyt mała wartosc, dopuszczalne: '+this.p.min+'..'+this.p.max);
		}else if(this.e.value > this.p.max){
			this.msg('Zbyt duża wartosc, dopuszczalne: '+this.p.min+'..'+this.p.max);
		}else{
			this.ok();
		}	
	}	
});
var vc_email = new Class.create(vc,{
	type : 'email',
	valid : function (){
		d('[[new VC_email]]');
		var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
		if(reg.test(this.e.value)==false){
			this.msg('Nieprawidłowy adres.');
		}else{
			this.ok();
		}	
	}	
});
var vc_time = new Class.create(vc,{
	type : 'time',
	valid : function (){
		d('[[new VC_time]]');
		this.e.value = this.e.value.replace(/\,|\.|;/,':');
		if(this.p.allow_null && this.e.value == ''){
			this.ok();
		}else{
			if(this.p.over24){
				//more than 24 hours allowed
				ss = /^[0-9]+:([0-5]?[0-9])$/;
			}else
			if(this.p.use24){
				//24 hours mode
				ss = /^(0?[0-9]|1[0-9]|2[0-3]):([0-5]?[0-9])$/;
			}else{
				//12 hours mode
				ss = /(0?[0-9]|1[0-2]):([0-5]?[0-9])\s?(pm|am)/;
			}
			if(this.e.value.search(ss) == -1){
				this.msg('Nie moge odszukać poprawnego czasu');
			}else{
				this.ok();
			}
		}
	}	
});
var vcs_std = new Class.create(vc,{
	type : 'vcs_std',
	valid: function(){
		d('[[new VCS_std]]');

		this.e.value = this.e.value.replace(String.fromCharCode(8211),String.fromCharCode(45));
		var c1 = String.fromCharCode(64,33,35,36,37,94,38,42,243,261,260,263,262,281,280,322,321,324,323,211,347,346,380,379,378,377,126);
		var c2 = String.fromCharCode(9,10,13,32,96,8222,8221,44,60,62,46,47,63,92,124,8364);	//tab,Enter,return,spaca, „”,<>./?\|€ 
		var c3 = String.fromCharCode(59,58,39,34,123,125,91,61,43,95,96,8211);					//;:'"=_+`
		var pattern = new RegExp(new String("[^a-zA-Z0-9\(\)\\\"\\\[\\\]\\\-\\\{\\\}" + c1 + c2 + c3 + "]"),"gi");
		var before = this.e.value;
		var after = this.e.value.replace(pattern,this.p.new_char);
		
		if(before != after){
			this.msg('Nie dozwolone znaki');
		}else{
			this.ok();
		}	
		this.e.value = after;
	}
});
var vcs_simple = new Class.create(vc,{
	type : 'vcs_simple',
	valid: function() {
		d('[[new VCS_simple]]');
		var pattern = new RegExp(new String("[^a-zA-Z0-9_\-]"),"gi");
		var before = this.e.value;
		var after = this.e.value.replace(pattern,this.p.new_char);
		if(before != after){
			this.msg('Bledne znaki');
		}else{
			this.ok();
		}	
		this.e.value = after;
	}
});
/** 
 * Kliencki walidator dlugosci kodu.
 * parametry:
 * min - minimalna dlugosc lancucha
 * max - maksymalna akceptowalna dlugosc lancucha
 */
var vcs_length = new Class.create(vc,{
	type : 'string_length',
	valid : function (){
		d('[[new VCS_length]]');
		if(this.e.value.length < this.p.min){
			this.msg('Za mało znaków od '+this.p.min+' od ' +this.p.max+ ' obecnie: ' + this.e.value.length);
		}else if(this.e.value.length > this.p.max){
			this.msg('Za dużo znaków do '+this.p.min+' do ' +this.p.max + ' obecnie: ' + this.e.value.length);
		}else{
			this.ok('Pole tekstowe od '+this.p.min+' do ' +this.p.max+ ' znaków');
		}
	}
});
var vcs_exactlength = new Class.create(vc,{
	type : 'string_length',
	valid : function (){
		d('[[new VCS_excatlength]]');
		if(this.p.req || this.e.value.length > 0){
			if(this.e.value.length > this.p.len){
				this.msg('Za dużo znaków, wymagane dokładnie '+this.p.len+', obecnie: ' + this.e.value.length);
			}else if(this.e.value.length < this.p.len){
				this.msg('Za mało znaków, wymagane dokładnie '+this.p.len+', obecnie: ' + this.e.value.length);
			}else{
				this.ok('Pole tekstowe od '+this.p.min+' do ' +this.p.max+ ' znaków');
			}
		}else{
			this.ok('Pole tekstowe, wymaga '+this.p.len+' znaków');
		}
	}
});


/**
 * Walidator loginu zastepujacy znaki domyslne
 * parametry wywolania:
 * new_char - znak zastepujacy. 
 */
var vcs_login = new Class.create(vc,{
	type : 'string_length',
	valid : function (){
		d('[[new VCS_login]]');
		var pattern = new RegExp(new String("[^a-zA-Z0-9_\-\.\@]"),"gi");
		var before = this.e.value;
		var after = this.e.value.replace(pattern,this.p.new_char);
		if(before != after){
			this.msg('Błędne znaki');
		}else{
			this.ok();
		}	
		this.e.value = after;
	}
});
var vcs_equal = new Class.create(vc,{
	type : 'vcs_equal',
	valid : function (){
		d('[[VCS_Equal]]');
		if(this.e.value != $(this.p.e1).value){
			this.msg('Pola różnią się');
		}else{
			this.ok();
		}
	}
});
var vcs_pass_mem = new Hash();
var vcs_passwdstrength = new Class.create(vc,{
	type : 'passwdstrength',
	valid : function (){
		d('[[new VCS_passwdstrength]]');
		if(!vcs_pass_mem.get(this.e.id)){
			vcs_pass_mem.set(this.e.id,$(this.e.id+'strength').getStyle('background-image'));
			d('Kolor zapisany ' + vcs_pass_mem.get(this.e.id));
		}
		if(this.e.value.length > 0){
			var s = passwdGetStrength(this.e.value);
		}else{
			var s = 0;
		}
		var w = parseInt($(this.e.id+'stg_main').getStyle('width'));
		var w = (w/32)*s;
		new Effect.Morph(this.e.id+'strength', {style:'width:'+w+'px', duration:'0.5'});
		if(s <= this.p.min){
			this.msg('Zbyt łatwe hasło [obecnie '+ (100 *s/32)+'%] '+ s);
			if(vcs_pass_mem.get(this.e.id) && this.p.color){
				$(this.e.id+'strength').style.background = vcs_pass_mem.get(this.e.id);
			}
		}else{
			if(this.p.color && vcs_pass_mem.get(this.e.id)){
				$(this.e.id+'strength').style.background = this.p.color;
			}
			this.ok('Aktualna siła hasła: '+(100 *s/32)+'%');
		}	
	}	
});
var passwdGetStrength = function(passwd){
	var o = 0 ;
	if (passwd.match(/[a-z]/)) // [verified] at least one lower case letter
	{
	o = (o+1)
	} if (passwd.match(/[A-Z]/)) // [verified] at least one upper case letter
	{
	o = (o+5)
	} // NUMBERS
	if (passwd.match(/\d+/)) // [verified] at least one number
	{
	o = (o+5)
	} if (passwd.match(/(\d.*\d.*\d)/)) // [verified] at least three numbers
	{
	o = (o+5)
	} // SPECIAL CHAR
	if (passwd.match(/[!,@#$%^&*?_~]/)) // [verified] at least one special character
	{
	o = (o+5)
	} if (passwd.match(/([!,@#$%^&*?_~].*[!,@#$%^&*?_~])/)) // [verified] at least two special characters
	{
	o = (o+5)
	} // COMBOS
	if (passwd.match(/[a-z]/) && passwd.match(/[A-Z]/)) // [verified] both upper and lower case
	{
	o = (o+2)
	} if (passwd.match(/\d/) && passwd.match(/\D/)) // [verified] both letters and numbers
	{
	o = (o+2)
	} // [Verified] Upper Letters, Lower Letters, numbers and special characters
	if (passwd.match(/[a-z]/) && passwd.match(/[A-Z]/) && passwd.match(/\d/) && passwd.match(/[!,@#$%^&*?_~]/))
	{
	o = (o+2)
	}
	return o;
}
var vco_pesel = new Class.create(vc,{
	type : 'vco_pesel',
	valid : function (){
		alert('nie uzywalne');
		return true; 
		
        if (this.e.value=='') return true;
        if (this.e.value.length != 11 || parseInt(this.e.value).toString()!=this.e.value) return false;
        var ws = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3]; 
        var s = 0;
        for (var x=0; x<10; x++) s = s + ws[x] * parseInt(this.e.value.substr(x,1));
        s = 10 - (s % 10);
        if (s == 10) s = 0;
        if (s == parseInt(this.e.value.substr(10,1))) {
        	this.ok();
        	return true;
        }
        this.msg('Błędny numer pesel');
        return false;
	}
});
var vco_nip = new Class.create(vc,{
	type : 'vco_nip',
	valid : function (){
		d('[[new VCO_nip]]');
		this.e.value = this.e.value.replace(',','.');
        if (this.e.value=='' && this.p.allow_null) return true;
        var ws = [6, 5, 7, 2, 3, 4, 5, 6, 7];
        nip=this.e.value.replace(/[ -]/g, ''); 
        if (nip.substring(0,2).toUpperCase() == 'PL') nip = nip.substring(2,nip.length);
        if (nip.length != 10){
        	this.msg('Błędna długość, spodziewam się 10 znaków');
        } 
        var s = 0; 
        for (var x=0; x<9; x++) {
        	s = s + ws[x] * parseInt(nip.substr(x,1)); 
        }
        s = s % 11; 
        if (s == parseInt(nip.substr(9,1))){
        	this.ok();
        	return true;
        }
        this.msg('Nieprawidłowy numer NIP');
        return false;
	}	
});
 		
 
