if (typeof(asc)!='function')
{
	function asc(str){str = String(str);return str.charCodeAt(0);}
}
if (typeof(chr)!='function')	
{
	function chr(AsciiNum){return String.fromCharCode(AsciiNum);} 
}
if (typeof(isset)!='function')//so we havent declared the function isset
{
	function isset(obj)
	{
		if (typeof(obj)=='undefined')
			return false;
		if (obj==null)
			return false;
		return true;
	}
}
if (typeof(String.prototype.trim)!='function')
{
	String.prototype.trim = function()
	{
		return this.replace(/^\s+|\s+$/g,"");
	}
}

if (typeof(styled_alert)!='function')
{
	function styled_alert(message, callback)
	{
		alert(message);
		if (isset(callback) && typeof(callback)=='function')
			callback();
	}
}

function morph_cnp(k)
{
	var cnp = new Array();
	for (i = 0; i <=12; i++)
	{
	 cnp[i] = k[i];
	}
	suma = cnp[0] * 2 + cnp[1] * 7 + cnp[2] * 9 + cnp[3] * 1 + cnp[4] * 4 + cnp[5] * 6 + cnp[6] * 3 + cnp[7] * 5 + cnp[8] * 8 + cnp[9] * 2 + cnp[10] * 7 + cnp[11] * 9; 
	rest = suma % 11;  
	if ((rest < 10 && rest == cnp[12]) || (rest == 10 && cnp[12]==1)) 
	 validare = true;
	else
	 validare = false;
	return validare;
}
function morph_cui(cui)
{
	//return true;//fuck that,we'll edit this out later
	var nr = cui.length, total = 0
	if (nr < 2 || nr > 10) {return false}
	pondere = "7532175321".substr(10-nr,nr)
	for (x=0; x < nr -1 ; ++x) {total += cui.charAt(x) * pondere.charAt(x)}
	return (cui.substr(nr-1,1) == ((total * 10) % 11 ) % 10 )	
}
function morph_mysql_date(date)
{
	var matches = date.match(/^[0-9]{4}\-[0-9]{1,2}\-[0-9]{1,2}$/);
	if (!isset(matches))
		return false;
	return (matches.length==1);
}
function morph_email(email)
{
	var matches = email.match(/^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/i);	
	if (!isset(matches))
		return false;
	return (matches.length==1);
}

function morph_url(url)
{
	var matches = url.match(/^(https?:\/\/)?(www\.)?((?!www)[a-z0-9][a-z0-9.-]*\.[a-z]{2,4})$/i);
	if (!isset(matches))
		return false;
	return (matches.length>=1);
}

function validateElement(element)
{
	var value_type;
	var value;
	if (!element.length || !isset(element))
		return 5;
	var tag_name = element.attr('tagName');
	
	if (isset(tag_name))
		tag_name = tag_name.toLowerCase();
	else
	{
		return 0;//depending element doesn't exist, but we don't care
	}	
	//first, we need to check if the refered element is an input, or a div
	if (tag_name=='div' || tag_name=='fieldset')//so we have a div/fieldset, we need to scan it for the value
	{//thanks to nice naming, we can get to the input elements pretty easy			
		if (element.hasClass('ui-buttonset') || tag_name=='fieldset' || element.hasClass('radiofield') || element.hasClass('checkboxfield'))//it's a buttonset/fieldset full of inputs
		{
			value = 0;//init the var
			value = $('#'+element.attr('id')+' input:checked').filter(':first').val();			
		}
		else//it's Radu's plugin
		{
			value='';
			var block=false;
			element.find('ul').find('li').each(function()
											{
												var val = this.lastChild.nodeValue;
												if (!val.length)
												{
													block=true;
													value='';
												}
												if (!block)
													value=val;
											}
											);
		}
		
	}
	else//or else, it's simple stuff
	{
		value = element.val();
		if (tag_name=='input')
		{
			if ((element.attr('type')=='checkbox' || element.attr('type')=='radio') && !element.is(':checked'))//if we don't have the checked attribute on it, don't acknowledge
				value=null;//the result as being valid
		}
	}
	if (!isset(value))
		return 1;
	if (element.attr('xsd-type'))			
		value_type = element.attr('xsd-type');
	else
		value_type = 'string';			
	value_type = value_type.toLowerCase();	
	
	switch(value_type)
	{
		case 'number':
			value = parseInt(value);
			if (!isset(value) || isNaN(value) || value<=0)
				return 1;
		break;
		case 'float':					
			value = Number(value);
			if (!isset(value) || value<=0 || isNaN(value))
				return 1;
			//element.attr('xsd-allow','digits|.');//we force the xsd-allow attribute to digits|., since digits are the only thing we should be interested in
		break;
		
		case 'string':
		default:				
			value = String(value);		
			if (!isset(value) || !value.length)
				return 1;	
		break;
	}//ok, that was validation against value type
			
	if (element.attr('xsd-length'))//this is validation against length
	{
		if (String(value).length!=parseInt(element.attr('xsd-length')))
		{
			return 2;
			
		}
	}	
	if (element.attr('xsd-allow'))//watch this, it should be pretty good | validation against allowed/disallowed characters
	{
		var allowed_array = Array();//holds the allowed elements
		var v = element.attr('xsd-allow').split('|');//split against an unfamiliar character, like vertical bar, so we can allow spaces and other stuff in
		
		for (i=0;i<v.length;i++)
		{
			switch(v[i].toLowerCase())//in case somebody tries to validate against retarded stuff like DiGIts
			{
				case 'digits':
					for (j=0;j<10;j++)
						allowed_array.push(j);
				break;
				
				case 'alphanumeric':
					for (j=0;j<10;j++)
						allowed_array.push(j);
				case 'letters':
					for (j=asc('a');j<=asc('z');j++)
						allowed_array.push(chr(j));
					for (j=asc('A');j<=asc('Z');j++)
						allowed_array.push(chr(j));
				break;
				
				default:
					allowed_array.push(v[i]);
				break;
			}
		}			
		value = String(value);//cast value to string, we don't need it anymore anyway
		for (i=0;i<value.length;i++)
		{
			var ch = value.charAt(i);
			found=false;
			for (j=0;j<allowed_array.length;j++)
			{
				if ( String(ch)==String(allowed_array[j]) )//found it
				{
					found=true;
				}
			}
			if (!found)
				return 3;
		}
		
	}
	if (element.attr('xsd-morph'))//this is validation against a certain shape(or morph); 
	{//it calls the function morph_{xsd-morph}(value) which must return true(for valid shape) or false otherwise; more morphs can be added by adding more functions
	
		eval( 'var morph_ok = morph_'+element.attr('xsd-morph')+"('"+element.val()+"');" );
		if (!morph_ok)
			return 4;
	}
	return 0;//unix-style return code for OK, we're good

}

function validateForm(containerId)//containerId is the id of the container which holds the elements, can be anything, from a form to a div
{		
	var validated = true;
	$('#'+containerId+' label.required').each(function()
	{			
		if (!isset($(this).attr('for')) || !$(this).attr('for').length)
			return true;
		var element = $('#'+$(this).attr('for')).filter('select.styled-select, :visible');//we get the element refered in the for attribute of the label, and we make sure the element is visible,
		//we also select "select"s, which is a trick bypassing styled select's display none on the selects themselves
		//makes no sense trying to validate a hidden element. If the user couldn't see it to fill it with data, why would we validate it?
		
		if (!element.length)//so if the element doesn't exist, ignore it
			return true;

		var skip_validation=false;
		if (isset($(this).attr('xsd-skip')))
			skip_validation = true;
		
		if (!skip_validation && $(this).attr('xsd-depends'))
		{			
			var depends = $(this).attr('xsd-depends');
			var negated = false;
			if (depends.trim().indexOf('!')==0)
			{
				negated= true;
				depends = depends.substr(1);
			}
			
			if ( !validateElement($('#'+ depends)) )			
				skip_validation = negated;
			else
				skip_validation = !negated;			
		}
		
		
		
		if (!skip_validation)
		{
			code = validateElement(element);//0 means success, others mean like following:
			if (code>0)
			{
				var str = $('label[for="'+element.attr('id')+'"]').html();
				if (str.indexOf('<')!=-1)//get the text from char 0 until we find the first opening tag brace
					str = str.substr(0,str.indexOf('<'));//so we trim the string to the textnode only(cutting out the span)
					
				str = str.replace(':','').replace('_',' ').toLowerCase();
				switch(code)
				{
					case 1://form field empty
						styled_alert('Campul "'+str+'" nu este completat');
					break;
					
					case 2://form field doesn't have the required length(for fixed-length values)
						styled_alert('Campul "'+str+'" nu are lungimea corespunzatoare');
					break;
					
					case 3://form field has disallowed characters
						styled_alert('Campul "'+str+'" contine caractere invalide');
					break;
					
					case 4://form field doesn't have the shape we wanted it to have
						styled_alert('Campul "'+str+'" nu este completat corect');
					break;
				}				
				validated=false;
				return false;	
			}
		}
		return true;
	});	
	return validated;//prevents the submit
}
