//
// CORE/PROTO ADDONS
//

Array.prototype.indexPush = function ( pItem ) {
	this.push( pItem );
	return(this.length-1);
}

Array.prototype.has = function ( pItem ) {
	if (this.indexOf(pItem)!=-1) { return(true); }
	return(false);
}

String.prototype.has = function ( pSubStr ) {
	if (this.indexOf(pSubStr)!=-1) { return(true); }
	return(false);
}

Element.reveal = function( obj, pClassName ) {
	if (obj) obj.style.visibility = 'visible';
}

Element.cloak = function( obj, pClassName ) {
	if (obj) obj.style.visibility = 'hidden';
}

Element.glueClass = function( obj, pClassName ) {
	if (!obj.className) 
	{ 
		obj.className = pClassName;
	} else {
		if (!obj.className.has(pClassName)) obj.className += ' '+ pClassName;
	}
}

Element.unGlueClass = function( obj, pClassName ) {
	if (obj.className.has(pClassName)) obj.className = obj.className.replace(' '+ pClassName,'');
}

Element.simpleFlip = function( obj ) { //not the same as proto's flip!!!
	if (obj.style.display != '')
	{
		if (obj.style.display == 'none') {
			 obj.style.display = 'block'
		} else {
			obj.style.display = 'none';
			var allInObj = obj.getElementsByTagName('*');
			for (var a = 0; a < allInObj.length; a++) {
				if ((allInObj[a].nodeName == "INPUT")) {
					if ((allInObj[a].name.indexOf("srjs") != -1)) allInObj[a].value = "";
				}
			}
		}
	}
}

document.getAll = function() {
	return(document.getElementsByTagName('*'));
}


function dateString() {
	var currentTime = new Date();
	var month = currentTime.getMonth() + 1; if (month<10) month = '0' + month;
	var day = currentTime.getDate(); if (day<10) day = '0' + day;
	var year = currentTime.getFullYear();
	return (year + "." + month + "." + day + ".");
}


//
// CORE VALIDATOR OBJECT (BACKEND)
//

var tSimpleValidator = Class.create();
Object.extend(tSimpleValidator.prototype, {

	initialize: function( pTarget, pProfile ) {
	
		//INITIAL PARAMETERS
		this.target = pTarget;
		this.profile = pProfile; //can be date, numeric, array, custom etc.
		
		//PUBLIC
		this.errorClass = 'svError'; //attach this css class on error event
		this.focusClass = 'svFocus'; //attach this class on focus event
		this.errorTarget = null; //defaults to htmlSelf
		this.allowEmpty = false; //if false, then will not remove error class from empty field
		
		this.baseRExp = null; //force these characters only
		this.rExpression = null; //validate according to this criteria
		
		this.jumpTo = null; //if set, set focus to specified object
		this.glueOnFocus = true; //should we apply the error style upon focus?
		this.cleanFirstFocus = null; //if set, will clean value on first focus
		this.allowedItems; //can be set for array profile
		this.maxLength; //can also be set explicitly, otherwise uses maxlength from htmlSelf
		this.minLength = 0; //use minLength = maxLength for strict size checking
		this.dateNotLowerThan = null; //range check for date
		this.forceUpperCase = true; //conevrt to uppercase on blur
		
		//PRIVATE
		this.touched = false;
		this.htmlSelf;
		this.forceJump = false;
		// --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  -- 
		
		this.htmlSelf = this.getFirstInput(this.target);
		this.errorTarget = this.htmlSelf;
		
		this.htmlSelf.onkeyup = this.keyupEvent.bindAsEventListener(this);
		this.htmlSelf.onkeydown = this.keydownEvent.bindAsEventListener(this);
		this.htmlSelf.onfocus = this.focusEvent.bindAsEventListener(this);
		this.htmlSelf.onblur = this.blurEvent.bindAsEventListener(this);
		
		if (this.htmlSelf.maxLength) { this.maxLength = this.htmlSelf.maxLength; }
	},

	getFirstInput: function(pfTarget)
	{
		if ((pfTarget != null) && (pfTarget != 'auto'))
		{
			if (!document.getElementById(pfTarget)) alert('ERROR! Bad target: ' + pfTarget + "; Can't continue, sorry."); //debug?
			var htmlElements = $(pfTarget).getElementsByTagName('*');
			var subSelf = null;
			for(var m=0; m<htmlElements.length; m++) //sorry, no loops
			{
				var htmlElement = htmlElements[m];
				if ((htmlElement.type == '') || (htmlElement.type == 'text')) //filter out hidden fields
				{
					return htmlElement;
				}
			}
			return null;
		}
	},
	
	focusEvent: function(evt)
	{
		if ((this.glueOnFocus) && (!this.isBroken)) { Element.glueClass(this.htmlSelf,this.focusClass); }
		if ((this.cleanFirstFocus) && (!this.touched)) { this.touched = true; this.htmlSelf.value = ''; }
	},

	blurEvent: function(evt)
	{
		if (this.glueOnFocus) this.htmlSelf.className = this.htmlSelf.className.replace(this.focusClass,'');
		if (this.forceUpperCase) { this.htmlSelf.value = this.htmlSelf.value.toUpperCase(); }
	},
	
	//two special functions; it would be better to inject into descendant though...
	
	scanAccountCode: function(pCode) {
		var valnum = 0;
		var scanner = "97319731";
		if (pCode.length != 8) return false;
		for (var i = 0; i < 7; i++) { valnum += Number(pCode.substr(i,1))*Number(scanner.substr(i,1)); }
		return ( pCode%10 == ((10 - valnum%10)%10) );
	},
	
	scanContractCode: function(pCode) {
		var valnum = 0;
		var buffer = 0;
		if (pCode.length < 8) return false; //excel-ben nem teljesen egyertelmu, ra kell kerdezni; nulla persze SOHA nem lehet
		
		for (var i = pCode.length-2; i > 0; i=i-2) {
			buffer = Number(pCode.substr(i,1))*2;
			if (buffer > 9) buffer = 1 + buffer%10;
			valnum += buffer + Number(pCode.substr(i-1,1));
		}
		return (Number(pCode)%10 == Math.ceil(valnum/10)*10 - valnum);
	},
	
	//external check, calls keyup
	validateSelf: function(evt)
	{
		return !this.keyupEvent(null);
	},
	
	keydownEvent: function(evt,r)
	{
		if (evt.keyCode == 13)
		{
			this.validateSelf();
			return false;
        }
	},
	
	keyupEvent: function(evt)
	{
		isBroken = false;
		if (!this.htmlSelf.disabled) 
		{
			if (this.profile == 'date') 
			{ 
				//always scan for this regexp
				//this.baseRExp = new RegExp ("^[0-9- .]*$","g");  /* engedi a kotojelet */
				this.baseRExp = new RegExp ("^[0-9 .]*$","g");
				//upon reaching maxLength, run the normal regexp
				if (!this.maxLength) this.maxLength = 11;
				this.rExpression = 
					
					//olyan regexp, amit a js nem szeret
					//new RegExp ("(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])","g"); - will not work in javascript
					
					//rugalmas datum:
					//new RegExp ("^(19|20|21)[0-9][0-9][- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[.]?$");
					
					//rideg datum, csak pontot fogad el
					new RegExp ("^(19|20|21)[0-9][0-9][.](0[1-9]|1[012])[.](0[1-9]|[12][0-9]|3[01])[.]?$");
	
	
			}
			
			if (this.profile == 'shortdate') 
			{ 
				this.baseRExp = new RegExp ("^[0-9- .]*$","g");
				if (!this.maxLength) this.maxLength = 8;
				this.rExpression = 
					new RegExp ("^(19|20|21)[0-9][0-9][- /.](0[1-9]|1[012])[- /.]?$");
			}
			
			if (this.profile == 'custom') 
			{
				//nothing special, set things manually
			}
			
			if (this.profile == 'creditnum') 
			{
				this.baseRExp = new RegExp ("^[0-9]*$","g");
				if (!this.maxLength) this.maxLength = 8;
				this.rExpression = this.baseRExp;
			}
			
			if (this.profile == 'taxnum') 
			{
				this.baseRExp = new RegExp ("^[0-9]*$","g");
				if (!this.maxLength) this.maxLength = 10;
				this.rExpression = this.baseRExp;
			}
			
			if (this.profile == 'numeric') 
			{
				this.baseRExp = new RegExp ("^[0-9]*$","g");
				this.rExpression = this.baseRExp;
			}
			
			if (this.profile == 'zipcode') 
			{
				this.baseRExp = new RegExp ("^[0-9]*$","g");
				this.rExpression = new RegExp ("^[1-9][0-9]{3}$","g");
			}
			
			if (this.profile == 'contractcode') 
			{
				this.baseRExp = new RegExp ("^[0-9]*$","g");
				if (!this.maxLength) this.maxLength = 8;
				this.rExpression = null;
			}
			
			if (this.profile == 'accountcode') 
			{
				this.baseRExp = new RegExp ("^[0-9]*$","g");
				if (!this.maxLength) this.maxLength = 8;
				this.rExpression = null;
			}
			
			if (this.profile == 'standard') //numeric+name
			{
				/*this.baseRExp = new RegExp ("^[0-9A-Za-zíöüóőúáäëéűÍÖÜÓŐÚÉËÁÄŰ./ \-]*$","g"); */
				this.baseRExp = new RegExp ("^[0-9A-Za-zíöüóőúáäëéűÍÖÜÓŐÚÉËÁÄŰ/ \-]*$","g");/*kiszedtem a pont karaktert*/
				this.rExpression = this.baseRExp;
			}
			
			if (this.profile == 'array')
			{
				rexString = '';
				for (var i=0; i<this.allowedItems.length; i++)
				{
					rexString += '(' + this.allowedItems[i] + ')';
					if (i != this.allowedItems.length-1) rexString += '|';
				}
				this.rExpression = new RegExp ("^" + rexString + "$");
				this.baseRExp = new RegExp (".*","g");
			}
				
			if (this.profile == 'name') 
			{
				/*this.baseRExp = new RegExp ("^[A-Za-zíöüóőúáäëéűÍÖÜÓŐÚÉËÁÄŰ. \-]*$","g");*/
				this.baseRExp = new RegExp ("^[A-Za-zíöüóőúáäëéűÍÖÜÓŐÚÉËÁÄŰ \-]*$","g");
				this.rExpression = this.baseRExp;
			}
			
			if (this.profile == 'email') 
			{
				if (!this.maxLength) this.maxLength = 255;
				this.baseRExp = null;
				this.rExpression = null;
			}
			
			//truncate if needed
			if (this.htmlSelf.value.length > this.maxLength)
			{
				this.htmlSelf.value = this.htmlSelf.value.substr(0,this.maxLength);
			}
				
			//clean letters if needed
			if (this.baseRExp != null)
			{
				var correctedValue = this.filterString(this.htmlSelf.value,this.baseRExp);
				if (this.htmlSelf.value != correctedValue) this.htmlSelf.value = correctedValue;
			}
			
			//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
			
			//get ready for scan
			myValue = this.htmlSelf.value;
			
			//scan
			if (this.rExpression != null)
			{
				if (myValue.match(this.rExpression)==null) { isBroken = true; }
			} else {
				if (this.profile == 'email') { if (!this.mailCheck(myValue)) isBroken = true; }
				if (this.profile == 'contractcode') { if (!this.scanContractCode(myValue)) isBroken = true; }
				if (this.profile == 'accountcode') { if (!this.scanAccountCode(myValue)) isBroken = true; }
			}
			
			if ((myValue.length == 0) && (this.allowEmpty == true)) { isBroken = false; } //revert if needed
			if ((myValue.length == 0) && (this.allowEmpty == false)) { isBroken = true; }
			if (myValue.length < this.minLength) { isBroken = true; } //check min size
			
			if ((this.dateNotLowerThan != null) && (this.profile == 'date')) //date limit check (extra)
				{
					var cleanActDate = this.htmlSelf.value.replace(/[^0-9]/gi,''); 
					var cleanNewDate = this.dateNotLowerThan.replace(/[^0-9]/gi,''); 
					if ((cleanNewDate.length == 8) && (cleanActDate.length == 8))
					{
						if (cleanActDate<cleanNewDate) isBroken = true;
					}
				}
			
			//mark finally
			if (isBroken == true) { Element.glueClass(this.errorTarget,this.errorClass); }
				else { Element.unGlueClass(this.errorTarget,this.errorClass); }
				
			//and jump if needed
			if ((this.htmlSelf.value.length == this.maxLength) && (this.maxLength) && (!isBroken))
			{
				if (this.jumpTo != null) { this.getFirstInput(this.jumpTo).focus(); }
			}

		} else { //the control has been disabled
			isBroken = false;
			Element.unGlueClass(this.errorTarget,this.errorClass);
		}
		
		return isBroken;
	},
	
	setHtmlSelfValue: function( pString ) {
		this.htmlSelf.value = pString;
		this.htmlSelf.protectedValue = pString;
		this.keyupEvent();
	},
		
	filterString: function(pString,pRegexp) {
	    validChars = pRegexp;
	    failed = 0;
	    for (var i = 0; i < pString.length; i++)
	    {
	        selChar = pString.substr(i,1);
	        if (selChar.match(validChars)==null)
	            {
	            failed = 1;
	            pString = pString.replace(selChar,'?');
	            }
	    }
	    if (failed == 1) { pString = pString.replace(/\?/gi,''); }
	    return(pString);
	},
	
	mailCheck: function(pString) {
		//based on "The JavaScript Source"'s mail validator
		emailPat		= /^(.+)@(.+)$/
		specialChars	= "\\(\\)<>@,;:\\\\\\\"\\.\\[\\]"
		validChars		= "\[^\\s" + specialChars + "\]"
		quotedUser		= "(\"[^\"]*\")"
		ipDomainPat		= /^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/
		atom			= validChars + '+'
		word			= "(" + atom + "|" + quotedUser + ")"
		userPat			= new RegExp("^" + word + "(\\." + word + ")*$")
		domainPat		= new RegExp("^" + atom + "(\\." + atom +")*$")
		matchArray = pString.match(emailPat);
		if (matchArray==null) {	return false; }
		
		user = matchArray[1];
		domain = matchArray[2];
		if (user.match(userPat)==null) { return false; }
		
		IPArray = domain.match(ipDomainPat);
		if ( IPArray != null ) {
			for (var i=1; i<=4; i++)
			{
				if (IPArray[i]>255) { return false; }
			}
			return true;
		}
		domainArray = domain.match(domainPat);
		if (domainArray == null) { return false; }
		
		var atomPat=new RegExp(atom,"g")
		var domArr=domain.match(atomPat)
		var len=domArr.length
		ending = domArr[domArr.length-1];
		if ((ending != 'nato') && (ending != 'arpa') && (ending != 'store') && (ending != 'firm')) {
			if (domArr[domArr.length-1].length<2 || domArr[domArr.length-1].length>3) 
			{
			   return false;
			}
		}
		if (len<2) { return false; }
		return true;
	}
});


//
// SIMPLE PREPOST VALIDATION (FRONTEND)
//

var domCache = new Array;
var useDomCache = false
var forceJumps = false;
var verboseDebug = false;

function fullValidation( pValObjects ) {
	var IBroke = false;
	
	if (!forceJumps)
	{
		for (var l=0; l<pValObjects.length-1; l++ )
		{
			if (!pValObjects[l])
			{
				alert('ERROR! Array discontinuity at index ' + l + '.');
				return false;
			}
		}
	}
	
	pValObjects.each( function(valObject){
		if ((valObject != null) && (valObject))
		{
			if (!valObject.validateSelf()) 
			{
				if (verboseDebug) alert('Validation error at html container "' + valObject.target + '".');
				IBroke = true; 
			}
		}
	});
	
	if (IBroke) 
	{
		Element.show($('prePostErrorMsg'));
		return false; 
	} else { 
		return true;
	}
}

// GROUP-SWITCHERS AND EXTRAS


function groupSwitch(pDisableList, pEnableList) {

	var diLst = pDisableList.split(',');
	var enLst = pEnableList.split(',');

	diLst.each( function(htmlElementName){
		if ($(htmlElementName))
		{
			htmlElement = $(htmlElementName);
			htmlElement.disabled = true;
			htmlElement.value = '';
			htmlElement.onkeyup();
			Element.glueClass(htmlElement,'disabled');
		}
	});

	enLst.each( function(htmlElementName){
		if ($(htmlElementName))
		{
			htmlElement = $(htmlElementName);
			htmlElement.disabled = false;
			Element.unGlueClass(htmlElement,'disabled');
		}
	});
}

function setGroupVisibility(pGroupPrefix) { //do *NOT* use, IE will slow down even with caching!
	if (domCache.length > 0) domTree = domCache
		else domTree = $A(document.getAll());
	for (var i = 0; i < domTree.length-1; i++) //loops are SLOW and IE sucks
	{
		if (domTree[i].id)
		{
			if (domTree[i].id.has(pGroupPrefix + '_'))
			{
				Element.simpleFlip(domTree[i]);
			}
		}
	}
	/*domTree.each( function(htmlElement) {
		if (htmlElement.id.has(pGroupPrefix + '_')) Element.simpleFlip(htmlElement);
	});*/
}

function switchMultiValidation( pValArray, pValObjectArrayIndexes, pState ) {
	var pvLst = pValObjectArrayIndexes.split(',');
	pvLst.each( function(valObjIndex){
		pValArray[valObjIndex].allowEmpty = !pState;
	});
}
function switchMultiValidationExt( pValArray, pValObjectArrayIndexes, pState, pValue ) {
	pValue = pValue.toLowerCase();
	if (pValue == "igen") {
		var pvLst = pValObjectArrayIndexes.split(',');
		pvLst.each( function(valObjIndex){
			pValArray[valObjIndex].allowEmpty = !pState;
			alert(pValArray[valObjIndex].allowEmpty);
		});
	} else {
	return false;
	}
}

function niceReset( pTargetForm ) {
	$(pTargetForm).reset();
	$A($(pTargetForm).getElementsByTagName('INPUT')).each( function(htmlElement){ 
		if (htmlElement.protectedValue) htmlElement.value = htmlElement.protectedValue; 
	});
	if (useDomCache) domCache = $A(document.getAll());
}

function forwardFelsKod ( pTarget1, pTarget2, pTarget3, pSzamKod ) {
	if ( pSzamKod == '' ) 
	{
		$(pTarget1).value = '';
		$(pTarget2).value = '';
		$(pTarget3).innerHTML = '';
		return false;
	}
	loc = felsoOktArr.indexOf(pSzamKod);
	$(pTarget1).value = felsoOktArr[loc];
	$(pTarget2).value = felsoOktArr[loc+1];
	$(pTarget3).innerHTML = felsoOktArr[loc+2];
}

