/*! (C) 2008 PRIME Computer Kft. www.prime.hu */
// Global PSIntra java namespace
var PSIntra = PSIntra || { globaldebug: false };

//---------- Start localization ---------------
// Error messages / other strings
PSIntra.prt_pfe = 
{
	e_req1: '<li>A(z) %1 értéke nem lehet üres.',							
	e_req2: '<li>Kérem jelölje be a(z) %1 jelölőnégyzetet.',								
	e_req3: '<li>Kérem válassza ki a(z) %1 értékét.',													
	e_minl: '<li>A(z) %1 hossza legalább %2 karakter kell hogy legyen.',
	e_mail: '<li>A(z) %1 nem érvényes e-mail cím.',														
	e_date: '<li>A(z) %1 nem érvényes dátum formátumú.<br />(a várt formátum: éééé.hh.nn - például: <b>2008.06.01</b>)',
	e_dati: '<li>A(z) %1 nem érvényes dátum+idő formátumú.<br />(a várt formátum: éééé.hh.nn óó:pp - például: <b>2008.06.01 11:23</b>)',
	e_minv: '<li>A(z) %1 értéke nem lehet kisebb mint %2.', 									
	e_maxv: '<li>A(z) %1 értéke nem lehet nagyobb mint %2.',									
	e_real: '<li>A(z) %1 értéke nem szám.',																		
	e_int:  '<li>A(z) %1 értéke nem egész szám.', 												
	e_phon: '<li>A(z) %1 nem megfelelő telefonszám (%2. karakter rossz).',
	e_maxl: '<li>A(z) %1 hossza nem lehet több mint %2 karakter.',
	e_maxe: '<li>Az ellenőrzés megszakítva, vannak még fel nem sorolt hibák az oldalon...',
	e_bbad: '<li>A(z) %1 nem érvényes vagy nem létező bankszámlaszám.<br />(létező kell, a várt formátum pl.: <b>12345678-12345678-12345678</b>)',
	e_bzip: '<li>A(z) %1 nem érvényes irányítószám.',
	e_mlac: '<li>A(z) %1 nem tartalmazhat ékezetes betűket.',
	
	// Other strings
	errorcap:	    'Hibás Adatmegadás',
	ajaxprog:	    'Adatok Továbbítása Folyamatban&nbsp;&nbsp;<img src="java/images/wait.gif">',
	ajaxerr:      '<b>Ajax Hiba</b>',																																
	plswait:      'Türelmét kérem...<br />',				
	ajaxcanabort: 'Az adattovábbítást megszakíthatja a <b>"Megszakít"</b> gomb megnyomásával.<br />',
	postaborted:	'Az adattovábbítás megszakítva',
	ajaxunknown:  '<b>Ismeretlen AJAX eljárás</b>',
	ajaxnotarget: '<b>Nincs AJAX célobjektum megadva</b>',
	
	// jquery.psintra other strings
	informations: 'Információk',
	inforwaitfor: 'Az információk töltődnek...',
	closecaption: 'Bezárás'
};

// Form controll type indices
PSIntra.ftype =
{
	Unknown:    0,   // Unknown, rendered as red rectangle                    
	EditBox:    1,   // Editbox (input-edit)                                  
	Memo: 	    2,   // Memo (textarea)                                       
	ComboBox:   3,   // Combobox (select)                                     
	CheckBox:   4,   // Checkbox (div+ input-checkbox + label)                
	PSButton:   5,   // Button (input - button/submit/reset, or skin rendered)
	HiddenCtrl: 6,   // Hidden (input-hidden)                                 
	RadioGroup: 7,	 // Radiogroup (fieldset-legend+input-radios)             
	Panel: 			8,	 // Panel (div)                                           
	GroupBox:		9,   // GroupBox (div+div)                                    
	Label: 			10,  // Label (label)                                         
	URLLink: 		11,  // Link (a)                                              
	AsIs: 			12,  // Rendered as div+HTML content 	                       
	Captcha:		13,  // Captha code image                                     
	FileSelect: 14,  // File upload                                           
	DBGrid: 		15   // DBGrid                                                
};
	
// Form controll names
PSIntra.prt_pfcn = [	
	'beviteli mező',	// FRT_UNKNOWN  	0	 Unknown, rendered as red rectangle
	'szövegdoboz', 	  // FRT_EDITBOX    1	 Editbox (input-edit)
	'szövegdoboz', 		// FRT_MEMO       2	 Memo (textarea)
	'lenyíló lista',	// FRT_COMBO      3	 Combobox (select)
	'jelölő négyzet',	// FRT_CHECKBOX   4	 Checkbox (div+ input-checkbox + label)
	'gomb',						// FRT_BUTTON     5	 Button (input - button/submit/reset, or skin rendered)
	'-', 							// FRT_HIDDEN     6	 Hidden (input-hidden)
	'gombsor',				// FRT_RADIOGROUP 7	 Radiogroup (fieldset-legend+input-radios)
	'panel',					// FRT_PANEL      8	 Panel (div)
	'paneldoboz',     // FRT_GROUPBOX   9  GroupBox (div+div)
	'felirat',				// FRT_LABEL			10 Label (label)
	'link',						// FRT_LINK 			11 Link (a)
	'-',		 					// FRT_ASIS 			12 Rendered as div+HTML content 	
	'-',     					// FRT_CAPTCHA		13 Captha code image
	'fájlválasztó',		// FRT_FILE   		14 File upload
	'adattábla' ]; 		// FRT_DBGRID     15 DBGrid
//---------- End localization -----------------

// Pending ajax XML-HTTP-REQ object
PSIntra.prt_pajax = null; 
// Last error string
PSIntra.prt_plasterr="";  
// Last ajax result
PSIntra.prt_last_get="";  


// Non DOM object dependent 'utility' functions
// call by $.functionname(params)
jQuery.extend({
	
	// Format divid for '#divid' format
	formid: function(d)
	{
		if( d !=='' && d.substr(0,1)!='#' ) return '#'+d; else return d;		
	},	

	// Get divid from '#divid' text
	divnam: function(d)
	{
		if( d !=='' && d.substr(0,1)=='#' ) return d.substr(1); else return d;
	},

	// Fájlnév átalakítása skin specifikusra
	// '/valami/akarmi.gif' => '/valami/akarmi_skinname.gif'
	skinspecific : function(fn)
	{
		var dp = fn.lastIndexOf('.');
		if(dp<0) return fn;
		
		return fn.substr(0,dp) + '_' + PSIntra.skin_name + fn.substr(dp);
	},
	
	// Check if file exists
	checkfileexists: function(f)
	{
		var res=true;
		try	
		{
			var fso = new ActiveXObject("Scripting.FileSystemObject");
			res = fso.FileExists(f);			
		}
				
		catch(e) 
		{
			res = true;
		}
		return res;
	},

	// Elapsed days between two date object
	date_daydiff: function( d1,d2 )
	{	
		var one_day=1000*60*60*24,
			d1u=Date.UTC(d1.getFullYear(),d1.getMonth(),d1.getDate(),0,0,0,0),
			d2u=Date.UTC(d2.getFullYear(),d2.getMonth(),d2.getDate(),0,0,0,0);

		return Math.abs(Math.ceil((d1u-d2u)/(one_day)))+1;		
	},

	// Format a number
	// s:  Float number as string
	// d:  decimals
	// ds: decimal separator
	// ts: thousand separator
	// er: string which is returned at formatting error
	number_format: function(s,d,ds,ts,er)
	{
		var fl=parseFloat(s);
		if( er===undefined ) er = '*';
		if( isNaN(fl) ) return er;
		
		if( d===undefined )  d  = 0;
		if( ds===undefined ) ds = '.';
		if( ts===undefined ) ts = ' ';
		
		var fs=fl.toString(), dp=fs.indexOf('.'), ret="", dcs=0;
		
		if( d > 0 )
		{
			ret = ds;			
			if( dp>=0 )
			{
				var i=dp+1;
				while(i<fs.length && dcs < d )
				{
					ret	+= fs.substr(i,1);
					dcs++; i++;
				}	
			}
		
			if( dcs != d ) 
			{
				ret += '00000000000000000000000'.substr(0,d-dcs);
			}
		}
		
		if( dp==0 )
		{
			ret = '0' + ret;	
		}		
		else
		{
			if( dp < 0 ) dp = fs.length;
			for( var i=dp-1; i>=0; i-- )
			{
				if( ts != '' && i<(dp-1) && ( (i-dp+1) % 3 ) == 0 ) ret = ts + ret;
				ret = fs.substr(i,1) + ret;	
			}
		}
		return ret;
	},

	//----------------------------------------------------------------------------------------
	// Set/get a skin button's caption
	//----------------------------------------------------------------------------------------	
	buttoncaption : function(btn, acap)
	{
		// Find caption span
		var btno = ( typeof btn != 'object' ) ? $($.formid(btn)) : btn,
				capspan = $('span[id^="xicon_"]', btno );
		
		// If caption not found, return false
		if( capspan.length < 1 ) return false;
		
		// Set or get caption
		return ( acap === undefined ) ? capspan.html() : capspan.html(acap);
	},

	//----------------------------------------------------------------------------------------
	// Redraw background stripes from top to down alternate
	//----------------------------------------------------------------------------------------
	// Inputs:
	// container - konténer elem, amin belül a stripe-okat keressük
	// classbase - CSS class kezdete, amire stripe-nak tekintünk egy container-child elemet
	// c1				 - classbase+c1 lesz a CSS classa a felülről számolva PÁRATLAN (első, harmadik...) csíkoknak
	// c2				 - classbase+c2 lesz a CSS classa a felülről számolva PÁROS (második, negyedik...) csíkoknak	
	// start1    - Ha true, akkor a fentiek szerint csíkoz. Ha false, akkor fordítva.
	// Returns:
	// - True:  Ha c2 classú volt a legalsó színezett elem
	// - False: Ha c1 classú volt a legalsó színezett elem
	//----------------------------------------------------------------------------------------
	restripes : function( container, classbase, c1, c2, start1 )
	{
		// Stripes on form
		var stripes = $('div[class^="'+classbase+'"]', container);
		if( stripes.length == 0 ) return true;
		
		// Save stripe data
		var stdat = [];
		for( var i=0; i < stripes.length; i++ )
		{			
			if( $(stripes[i]).myvisible() )
			{
				var atop = parseInt( $(stripes[i]).css('top'), 10 );
				stdat.push( {idx: i, top: atop} );
			}
		}
		
		// Sort stripe data
		stdat.sort( function(a,b)	{	if( a.top == b.top ) return a.idx - b.idx; else return a.top - b.top; } );
		
		// Re-classify by sort order
		var cends = start1 ? [c1,c2] : [c2,c1], last1;
		for( var i=0; i < stdat.length; i++ )
		{
			var ac1 = cends[i%2], ac2 = cends[1-(i%2)];
			$(stripes[stdat[i].idx]).removeClass(''+classbase+ac2).addClass(''+classbase+ac1);
			last1 = ac1 == c1;
		}			
		return !last1;
	},
	
	// Abort current ajax call
	// Pending ajax in 'prt_pajax' global var
	abort_ajax: function(b)
	{	
		jQuery.dlgbtnclick(b);
		if ( PSIntra.prt_pajax !== null ) 
		{
			PSIntra.prt_pajax.abort(); 
			PSIntra.prt_pajax = null;
			alert( $.striptags( PSIntra.prt_pfe.postaborted ) );
		}
	},

	// Encode a string in UTF8
	UTF8encode : function (string) 
	{
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";
 
		for (var n = 0; n < string.length; n++) 
		{ 
			var c = string.charCodeAt(n);
 
			if (c < 128) 
			{
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) 
			{
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else 
			{
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			} 
		}
 
		return utftext;
	},

	// Decode a string from UTF8
	UTF8decode : function (utftext) 
	{
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;
 
		while ( i < utftext.length ) 
		{ 
			c = utftext.charCodeAt(i);
 
			if (c < 128) 
			{
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) 
			{
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else 
			{
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			} 
		} 
		return string;
	},

	// Drop error message to 'd' div, or if d = '' or d = '-' use alert
	drop_error: function(d,er)
	{
		if ( d !== '' && d !== '-' ) 
		{ $($.formid(d)).html('<div class="skn_messE">'+er+ '</div>' ); }
		else 											
		{ alert($.striptags(er)); }
		return er;
	},

	// Get window central top/left position for element
	centerpos: function(a)
	{
		if( !(a.length) ) return {left: '0px', top: '0px'};
		var w=a.width(), h=a.height();
		if(w==0) { w=parseInt(a.css('width'),10);  if( isNaN(w) || w===undefined ) w=0; }
		if(h==0) { h=parseInt(a.css('height'),10); if( isNaN(h) || h===undefined ) h=0; }
		return { left: Math.max(Math.round(($(window).width()-w)/2),0)+'px',
  	  top: Math.max(Math.round(($(window).height()-h)/2),0)+'px' };
	},

	// Simple check filename validity
	checkfilename: function(s)
	{
		if( s==='' || s===null || s===undefined || s.length < 4 ) return false;
		var fp=s.indexOf(':'), lp=s.lastIndexOf(':');
		
		//if( fp<0 || fp != lp ) return false;
		// FIREFOX miatt 
		if(  fp != lp ) return false;
		// TODO: more check
		return $.checkfileexists(s);		
	},
	
	// Change date separator at input
	// ev - keypress event
	chdatesep: function(ev)
	{
		if ( ev.which == 44 ) ev.which = 46;
		return true;
	},

	// Show document in popup window. Doc get by AJAX.
	show_indoc: function(opt,event)
	{	
		var opts = $.extend(
		{
			idpre: 	 'infowin',
			durl: 	 '',
			caption: PSIntra.prt_pfe.informations,
			waittxt: PSIntra.prt_pfe.inforwaitfor,
			width:   600,
			height:  450,
			pdta: 	 {}
		}, opt || {});	

		if( opts.durl == '' )
		{
			if(event !== undefined ) event.returnValue = false;
			return false;			
		}
		
		var cdiv=opts.idpre+'_cont', hdiv=opts.idpre+'_head', tdiv=opts.idpre+'_txtarget', bcls=opts.idpre+'_bclosewin',
			bgcol=PSIntra.prt_blindmode ? 'black' : '#FFFFD0', bgcolin=PSIntra.prt_blindmode ? 'navy' : '#F3F8FE';
		
		if( !( $('#'+cdiv).length ) )
		{
			var ih='<div id="'+cdiv+'" class="p_groupbox hidden" style="position:relative;width:'+opts.width+'px;height:'+opts.height+'px;background-color: '+bgcol+';">'+
		  '<div id="'+hdiv+'" class="p_gbcaption" style="height:21px"><b>'+opts.caption+'</b></div>'+
			'<div class="p_cbwrapper" style="position:absolute;width:165px;height:28px;left:'+(opts.width-173)+'px;top:'+(opts.height-35)+'px;overflow:hidden;">'+
			'<a href="" class="xbtn" style="width:157px;" target="_self" id="'+bcls+'" onclick="$.unblockUI(); event.returnValue=false; return false;">'+
			'<span class="xbtn_pre"></span><span class="xbtn_post"></span><span id="xicon_cancel" class="xbtn_icon">'+PSIntra.prt_pfe.closecaption+'</span></a></div>'+
			'<div id="'+tdiv+'" class="p_panel" style="padding:2px;background-color:'+bgcolin+';position:absolute;width:'+(opts.width-18)+'px;height:'+(opts.height-74)+'px;left:8px;top:32px;border: 1px solid navy; overflow: auto;"></div></div>';
			$('body').append(ih);
		}
		
    $('#'+tdiv).html('<br /><br /><center><b>'+opts.waittxt+'</b></center>');
	  $.blockUI({ message: $('#'+cdiv), css: $.centerpos($('#'+cdiv)) });
	  $('#'+tdiv).myload(opts.durl,opts.pdta);	  	
  	if(event !== undefined ) event.returnValue = false;
	  return false;
	},

	// Cancel a JavaScript event
	cancel_event: function(e)
	{
	  if(!e) e = window.event;
	  
	  if( e===undefined || e===null ) return false;
	  
	  if(e.stopPropagation) e.stopPropagation();
	  if(e.preventDefault)  e.preventDefault();
	  e.cancelBubble = true;
	  e.cancel = true;
	  e.returnValue = false;
	  return false;
	},

	// Strip (closed) tags '<' .. '>' from text
	striptags: function(txt)
	{
		var ot=0,ct=0;
		while( ot>=0 && ct>=0 )
		{
			ot = txt.indexOf('<'); ct = txt.indexOf('>',ot);
			if( ct>=0 && ot>=0 ) txt = txt.substr(0,ot) + txt.substr(ct+1);
		}		
		return txt;
	},

	// Check hungarian bank account number
	checkhunba: function(ba)
	{
		var chk_tags = [ 9,7,3,1 ], bac = '', cs;

	  // Strip it / check digit groups
	  for( var i=0;i < ba.length;i++)
	  {
	  	if( ba.charCodeAt(i) >= 48 && ba.charCodeAt(i) <= 57 ) bac += ba.charAt(i);	
	  }
		if( bac.length != 16 && bac.length != 24 ) { return false; }

	  // Cut final 00000000
		if( bac.length == 24 && bac.substr( 16, 8 ) == '00000000' ) { bac = bac.substr( 0, 16 ); }	

	  // Checksum for first group
	  cs = 0;
	  for( var i=0; i < 8; i++ ) { cs += ( bac.charCodeAt(i) - 48 ) * chk_tags[i % 4]; }
	  
	  // If first group OK, the check the rest at once
	  if( ( cs % 10 ) == 0 )
	  {
	    cs = 0;
	    for( var i=8; i < bac.length; i++ ) { cs += ( bac.charCodeAt(i) - 48 ) * chk_tags[i % 4]; }
	  }
	  return ( cs % 10 ) == 0;
	},

	// Add an URL to browser's bookmarks
	addbookmark: function(ur,cap)
	{
		if (window.sidebar) 
		{ 
			window.sidebar.addPanel(cap,ur,'');	
		} 
		else if( window.external ) 
		{ 
			window.external.AddFavorite( ur, cap);
	  }	
	  else if(window.opera && window.print) 
	  { 
	  	return true; 
	  }  
	}, 

	// Enable / disable a PSIntra button
	endisbutton: function(sel,con,sta)
	{
		var itm; sel += "[class^='xbtn']";
		if( con === undefined || con === '' )	itm = $(sel); else itm = $(sel,con);
					
		for( var i=0; i<itm.length; i++ )
		{			
			var ao=$(itm[i]), acls=ao.attr('class'), isdis=acls.indexOf('Dis') < 0, 
					newcls = isdis ? acls.substr(4) : acls.substr(7), xdis=ao.attr('xdisabled') == '1';
					
			// Toggle
			if( sta === undefined )
				newcls = 'xbtn' + ( isdis ? 'Dis' : '' ) + newcls;
			// Enabled
			else if( sta )
				newcls = 'xbtn' + newcls;
			// Disabled
			else
				newcls = 'xbtnDis' + newcls;

			// Change class				
			if( acls != newcls && !xdis ) 
			{
				ao.attr('class',newcls);				
				
				// Enabled -> Disabled
				if( isdis  )
				{
					var ahr=ao.attr('href');
					ao.attr('xhref',ahr === undefined ? '***' : ahr).attr('href','#');

					ao[0].xonclick = ( ao[0].onclick ) ? ao[0].onclick : null;
					ao[0].onclick  = function(event) { event.returnValue=false; return false; };
				}
				// Disabled -> Enabled
				else
				{				
					var ahr=ao.attr('xhref');
					if( ahr == '***' ) ao.removeAttr( 'href' ); else ao.attr('href',ahr);					
					ao.removeAttr('xhref');

					ao[0].onclick  = ( ao[0].xonclick ) ? ao[0].xonclick : null;
					ao[0].xonclick = null;
				}
			}
		}		
	},
	
  // Format message: use index 'm' in global prt_pfe, or 'sm'
  // P1, p2 replacement parameters (%1, %2)
	formatmess: function(m,p1,p2,sm)
	{
		var fh=function(am,i,p)
			{
				if ( am.indexOf('(z) %'+i)>= 0 )
				{
					if ( 'euioaöüóőúéáű15'.indexOf(p.substr(0,1).toLowerCase())>=0 )
					{
						am=am.replace('(z) %'+i,'z %'+i); 
					}
					else 
					{
						am=am.replace('(z) %'+i,' %'+i);
					}
				}
				return am.replace('%'+i,'<b>'+p+'</b>');		
			};
		
		if (sm===undefined) { sm=PSIntra.prt_pfe[m]; } if (p1==='') { return sm+'<br />';	}
		var r=fh(sm,'1',p1);  if (p2==='') { return r+'<br />'; }
		return fh(r,'2',p2)+'<br />';		
	},

	// Execute mail-to link
	mlc: function(p,c,d)
	{
		var a3="mail", a6=p+String.fromCharCode(64)+d+'.'+c, a5="to", a7=a3+a5+':'+a6;
		document.location.href=a7;		
	},
	
	// Add session ID to link 'l'
	adsidlink: function(l)
	{
		if (PSIntra.prt_phpsess!==undefined) 
		{ 
			var sidn=PSIntra.prt_phpsess.split('=');			
			l += ( l.indexOf('?') < 0 ? '?' : '&' ) + sidn[0] + '=' + sidn[1];
		}				
		return l;
	},
	
	// Add session ID to post vars
	addsid: function(o)
	{
		if (PSIntra.prt_phpsess!==undefined&&PSIntra.prt_phpsess!==null) 
		{ 
			var sidn=PSIntra.prt_phpsess.split('=');
			o[sidn[0]] = sidn[1]; 
		}		
	},
	
	// Get date object from 'YYYY.MM.DD' date string 
	getdateYMD: function(v)
	{
		var ok=false, ad=null;
	  if ( v!=="" )
	  {
	  	ok = /^\d{4}[\.]\d{2}[\.]\d{2}$/.test(v);
	  	if (ok)
	  	{				  		
	  		var er, ymd=v.split('.'); for( var j=0;j<3;j++) { ymd[j]=ymd[j]*1; } ad=new Date();
	  		try { ad.setFullYear(ymd[0],ymd[1]-1,ymd[2]); ad.setHours(0,0,0,0); } catch(er) { ok=false; }
	  		if (ok) { ok=ad.getFullYear()==ymd[0]&&(ad.getMonth()+1)==ymd[1]&&ad.getDate()==ymd[2]; }
	  	}				  	
	  	if (!ok) { ad=null; }
	  }
	  return ad;
	},	

	// Set time part in a date string
	settimepart: function(d,t)
	{
		if( t.length != 5 || t.substr( 2,1 ) != ':' ) return null;
		var ah=parseInt(t.substr(0,2),10), am=parseInt(t.substr(3,2),10);
		if( ah >= 0 && ah <=23 && am >= 0 && am <= 59 )
		{
			d.setHours(ah,am,0,0);
			return d;
		}
		return null;		
	},

	// Get date-time object from 'YYYY.MM.DD hh:mm' date-time string 
	getdatetimeYMDhm: function(v,deft)
	{
		// Empty or bad length
	  if ( v==="" || v===undefined || v===null || ( v.length != 10 && v.length != 16 ) ) return null;
		// Default time part
		deft=deft===undefined?'00:00':deft;
		// Date part, with 00:00 time
  	var ad=$.getdateYMD(v.substr(0,10)); if( ad === null ) return null;
  	// No time specified
  	if( v.length==10 ) return deft=='00:00' ? ad : $.settimepart(ad, deft);
  	// Check internal space
  	if( v.substr(10,1) != ' ' ) return null;
		// Set time, return it
		return $.settimepart(ad, v.substr(11,5) );
	},

	// Get date object for check value
	// s:    The date check expression
	// ut:   Use time part?
	// deft: Default time value
	// 's' can be: 
	// - 't' 					: Current date
	// - '2010.01.01' : (constant date)
	// - 't.t+1.t-2'  : date expression, where 't' replaced by current date part (year/month/day)
	//                  and corrected by the expression	
	getdatecheckval: function(s,ut,deft)
	{
		// ---- If just current date/time
		if( s=='t' )
 		{ 
 			return new Date(); 
 		} 
 		
 		// ---- If expression not contains 't'
 		// Just convert as date/time constant
 		if( s.indexOf('t') < 0 )
 		{
 			if( ut ) 
 			{
 				return $.getdatetimeYMDhm(s,deft);
 			}
 			else
 			{
 				return $.getdateYMD(s);
 			}
 		}
 		
 		// ---- Evaluate 't' expressions
 		var ad=new Date(); 		
 		
 		// ---- Not Y/M/D part defined, just 't+constant'
 		// evaluate as current date + add days
 		if( s.indexOf('.')<0 )
 		{
 			var 
 				// operator (+/-) + constant
 				md = s.substr(s.indexOf('t')+1), 
 				// One day as millisecond
 				one_day = 1000*60*60*24,
 				// given date mean time (12:00) as timestamp
 				at=Date.UTC(ad.getFullYear(),ad.getMonth(),ad.getDate(),12,0,0,0),
 				// Setup expression: timestamp + operator (+/-) + '*' + one_day
				ev=at+md+'*'+one_day;
 			
 			try
 			{
 				// Evaluate expression (get the new timestamp)
 				var nt=eval(ev);
 				// Set timestamp to datetime object
 				ad.setTime(nt);
 				// Clear h:m:s:ms
 				ad.setHours(0,0,0,0);
 			}
 			catch(er)
 			{
 				return null; 				
 			}
 		}
 		// ---- Y+t/M+t/D+t fdefined date
 		else
 		{ 		
	 		var 
	 			// Date object
	 			ad=new Date(), 
	 			// Split to YMD parts
	 			ymd=s.split('.'),
	 			// Current YMD
	 			aymd=[ad.getFullYear(), ad.getMonth()+1, ad.getDate()], 
	 			// Other internal vars
	 			rd=[],t,er;
	 		
	 		// See through YMD parts
	 		for( var i=0; i<3; i++ )
	 		{
	 			// If current part not contains 't'
	 			if( ymd[i].indexOf('t') < 0 )
	 			{
	 				// Use the constant as current part
	 				rd[i] = parseInt( ymd[i], 10 );
	 			}
	 			else
	 			{
	 				// Set curent timepart to 't'
	 				// evaluate as expression
	 				t = aymd[i];
	 				try	{	rd[i] = eval(ymd[i]);	} catch(er)	{	return null; }
	 			} 			
	 		}		
	
			// Try to set-up new date
	 		try 
	 		{ 
	 			ad.setFullYear(rd[0],rd[1]-1,rd[2]); 
	 			ad.setHours(0,0,0,0); 
	 		} 
	 		catch(er) 
	 		{ 
	 			return null;
	 		}		 		
	  }
  	
  	// Set time part if need
 		if( !ut || deft===undefined || deft=='00:00' )
 		{
 			return ad;	
 		}
 		return $.settimepart( ad, deft ); 		
	},

	// Captitalize Words in text
	mycapital: function(v)
	{
		if (v==='') return '';
		var d=' .,;:-+!/?"\'', rs='', mx=v.length, i=0;
		while( i<mx )
		{
			var j=i; while( i<mx && d.indexOf(v.charAt(i))>=0 ) { i++; }
			rs += v.substr(j,i-j);
			if( i<mx ) { rs += v.charAt(i++).toUpperCase(); }
			j=i; while( i<mx && d.indexOf(v.charAt(i))<0 ) { i++; }
			rs += v.substr(j,i-j).toLowerCase();
		}
		return rs;
	},

	// Get checked checkbox indices (idx) and values (key) in a container
	// CB ids must be: CONTAINERn where n is the idx of CB, CONTAINER is ID of container
	gettabcheck: function(s)
	{
		var c=$("input[@type='checkbox']:checked",$.formid(s)), r=[], l=s.length;
		for(var i=0;i<c.length;i++)
		{
			var o=$(c[i]), n=o.attr('id').substr(l), v=o.attr('value');			
			r.push( {idx: n, key: v} );		
		}
		return r;
	},	
	
	// Get checked checkboxes as string od '0' / '1'
	// indices parsed from name, value after final '_'
	// mx is string Lengt (maxindex)
	gettabcheck_str: function(s,mx)
	{
		var c=$("input[@type='checkbox']:checked",$.formid(s)), r=[], res='', mxid=0;
		if( mx===undefined ) mx=0;
		for(var i=0;i<c.length;i++)
		{
			var cid=$(c[i]).attr('id'), idl=cid.lastIndexOf('_'), idx=parseInt((idl>0)?cid.substr(idl+1):'NAN',10);
			if( !isNaN(idx) ) { r[idx]=1; if(idx>mxid) mxid=idx };
		}	
		if( mx==0 ) mx=mxid+1;
		for(var i=0;i<mx;i++) if( r[i] === 1 ) res +='1'; else res +='0';				
		return res;
	},
	
	// Change CB states in a container
	// x = 0 - uncheck all, x = 1  - check all, x = other - invert checks
	chgtabcheck: function(s,x)
	{
		var st="input[@type='checkbox']"; s=$.formid(s);
		switch(x)
		{
			case 0:  return $(st,s).attr("checked","");
			case 1:  return $(st,s).attr("checked","checked");
			default: return $(st,s).each( function(i) { this.checked = !this.checked; } ); 
		}		
	},	

	// Reformat date for yyyy.mm.dd format
	reformatdate: function( dv, a )
	{
		if( dv.length != 8 ) return dv;
		var y=parseInt( dv.substr(0,4),10 ),m=parseInt( dv.substr(4,2),10 ),	
			d=parseInt( dv.substr(6,2),10 );
			
		if( y>1900 && y<2100 && m >= 1 && m <= 12 && d >= 1 && d <= 31 )
		{
			dv = y + '.' + ( m < 10 ? '0' : '' ) + m + '.' + ( d < 10 ? '0' : '' ) + d;
			a.myval(dv);						
		}	
		return dv;		
	},
		
	// Fill a numeric value with leading zeros to length l
	fillnull: function(v,l)
	{
		var r=v.toString(); if( r.length<l ) r='00000000000000000000000'.substr(0,l-r.length)+r;
		return r;
	},

	// Set height of a container (mdiv) to the most-bottom 
	// contained visible element (except bdiv)
	autoheight: function( mdiv, bdiv )
	{
		var ab=null, mh=0, mw=0, ad=$($.formid(mdiv));
		if(ad===null||ad===undefined) return null;
		if(bdiv!==undefined&&bdiv!=='') ab=$($.formid(bdiv));
		var childs=$($.formid(mdiv)+' > *');
		jQuery.each( childs, function(eidx,o)
		{
			var ao=jQuery(o);
			if( ao.attr('id')!=$.divnam(bdiv)&&ao.myvisible() )
			{
				var ah=ao.height()+parseInt( ao.css('top'), 10 ), ar=ao.width()+parseInt( ao.css('left'), 10);
				if( ah>mh ) mh = ah; if ( ar > mw ) mw = ar;
			}
		});
		if( ab!==null&&ab!==undefined ) 
		{
			mh += 2; ab.css('top',mh+'px'); mh += ab.height();
		}
		ad.css('height',mh+'px');
		return ad;
	},

	// Reload a container 
	ajxreload: function(s,pars)
	{
	  var pdta={}; pdta[PSIntra.prt_ajaxfunc]='reload'; $.addsid(pdta);
		var sdta=$.extend(pdta, pars || {});	
		if( !$($.formid(s)).length ) return null;
  	return $($.formid(s)).myload('ajaxgate.php', sdta);
	},
		
	// Get date / time string from date object (d)
	// if d not given, use current date
	// t: need time? ds - date separator, ts - time separator
	getdateSTR: function(d,t,ds,ts)
	{
		if( d===undefined || d===null || typeof d!='object' || d.constructor != Date ) d = new Date();
		if (ds===undefined||ds===null) ds='.';

		var dr=d.getFullYear().toString()+ds+$.fillnull(d.getMonth()+1,2)+ds+$.fillnull(d.getDate(),2);
		
		if(t!==undefined&&t!==null&&t)
		{
			if (ts===undefined||ts===null) ts=':';				
			dr+=' '+$.fillnull(d.getHours(),2)+ts+$.fillnull(d.getMinutes(),2)+ts+$.fillnull(d.getSeconds(),2);
		}
		return dr;
	},

	// Update last access to server
	update_access: function()
	{
		PSIntra.prt_lastaccess = new Date().getTime();
	},
	
	// Get milis since last access
	milis_since_lastacc: function()
	{
		return new Date().getTime() - PSIntra.prt_lastaccess;		
	},	
	
	// Drop a heartbeat to server
	do_heartbeat: function()
	{
		// Next heartbeat
		var nxhb=PSIntra.heartbeat_milis;		
		// There is no pending ajax request
		if ( PSIntra.prt_pajax === null )
		{
			// Need a heartbeat now?
			var no_acc = $.milis_since_lastacc();
			// If we have to send heartbeat within 3 secs
			if( ( no_acc + 3000 ) > PSIntra.heartbeat_milis )
			{			
				var pdta = {};
				pdta[PSIntra.prt_ajaxfunc]=PSIntra.heartbeat_func;
				$.addsid(pdta);
				$.mypost('ajaxgate.php',pdta,null,false,'text/html');
			}
			// No heartbeat need within 3 secs, set timout to lastaccess			
			else
			{
				nxhb = PSIntra.heartbeat_milis - no_acc;				
			}			
		}
		setTimeout($.do_heartbeat,nxhb);
	},
	
	// Get something by sync post ajax
	mygetbypost: function( url, data, type, erret ) 
	{		
		var jsonret={},ret='',iserr=false;
		$.update_access();
		var areq=jQuery.ajax({
			type: "POST",
			url: url,
			data: data,
			dataType: type,
			async: false,
			success:
				// 'Success' callback
				function(retdta)
				{
					if( type == 'json' ) jsonret = retdta;					
				},
			complete: 
				// 'Complete' callback
				function(req,stat)
				{
					// Is error?
					if ( stat != "success" )
					{
						iserr = true;
						var errmsg = $.striptags( PSIntra.prt_pfe.ajaxerr + ': ' + stat + ' ' + req.status + ' ' + req.statusText ); 
						alert( errmsg );
						
						if( erret !== undefined )
						{
							var ep=erret.indexOf('*error*');
							if( ep >= 0 )
							{
								erret = erret.substr(0,ep) + errmsg + erret.substr(ep+7);
							}
						}
	   			}
	   			else
	   			{
	   				ret = req.responseText;
	   			}
	 			}			
		});

		// Was error?
		if( iserr )
		{
			if( erret === undefined ) return '';
			return erret;
		}
		
		// If json, drop back the java object		
		if( type == 'json' ) return jsonret;

		// Textual: Trim leading whitespaces, fucked Apache/PHP
		var cpos=0;
		while( cpos<ret.length && ret.charCodeAt(cpos)<=32 ) cpos++;
		if( cpos==0 ) return ret;
		return ret.substr(cpos);
	},		

	// Post something in ajax, sync / async (issync)
	mypost: function( url, data, callback, issync, type ) 
	{
		if ( jQuery.isFunction( data ) ) {
			callback = data;
			data = {};
		}
		
		if ( issync===undefined||issync===null ) issync=false;

		$.update_access();		
		return jQuery.ajax({
			type: "POST",
			url: url,
			data: data,
			complete: callback,
			async: !issync,			
			dataType: type
		});
	},

	// Make an ajax call ('load', or async post 'pos', or snyc post 'posts')
	myajax: function(opt,padd)
	{
		var opts=$.extend({
			ajaxmethod:   'load', // Used ajax method
			showajaxdlg:  false,  // Show ajax dialog
			ajaxabort:    false,  // Ajax call abortable		
			addsessid:    true,   // Add session id to ajax call
			ajaxfunc:		  '',     // Ajax function 
			ajaxurl:      'ajaxgate.php', // AJAX url to call
			baseelem:		  '',		  // Base element, which will be replaced
			targetelem:   '',     // AJAX target element (if empty and load, use parent elem)
			errdiv:       'port_warning',  // Error div selector, if empty use 'port_warning', if '-' use 'alert'
			onnohtml:     null,   // No html result loaded callback
			onokcallback: null,   // OK callback
  		jumpelem:		  '' 		  // Id, which located after load
			}, opt || {} );
				
		var pdta=$.extend({}, padd || {}), has_error='';
		
		// Show dialog if need
		if (opts.showajaxdlg) { $.showdialog(PSIntra.prt_pfe.ajaxprog,opts.ajaxabort?PSIntra.prt_pfe.ajaxcanabort:PSIntra.prt_pfe.plswait,opts.ajaxabort?32:0,null,opts.ajaxabort?'$.abort_ajax':''); }
		// add session id to ajax call ?
		if (opts.addsessid&&PSIntra.prt_phpsess!==undefined) { var sidn=PSIntra.prt_phpsess.split('='); pdta[sidn[0]] = sidn[1]; }		
		// Ajax function
		if (PSIntra.prt_ajaxfunc!==undefined&&PSIntra.prt_ajaxfunc!==''&&opts.ajaxfunc!=='') { pdta[PSIntra.prt_ajaxfunc]=opts.ajaxfunc; }
		
		if( opts.ajaxmethod == 'load' )
		{
			// No target element
			if(opts.targetelem==='')
			{
				if(opts.baseelem!=='') opts.targetelem=$($.formid(opts.baseelem)).parent().eq(0).attr('id');
				if(opts.targetelem==='') return $.drop_error(opts.errdiv,PSIntra.prt_pfe.ajaxnotarget);
			}
						
			// Do ajax load call
			jQuery($.formid(opts.targetelem)).myload(opts.ajaxurl, pdta, 
				// 'Complete' callback
				function(rt,stat,req)
				{
					// Hide dialog if visible
					if (opts.showajaxdlg && opts.showajaxdlg !== 1) { jQuery.dlgbtnclick(0); }
					// Is error?
					if ( stat != "success" && stat != "notmodified" )
					{
						has_error = $.drop_error( opts.errdiv, PSIntra.prt_pfe.ajaxerr + ': ' + stat + ' ' + req.status + ' ' + req.statusText );
	   			}
	   			// locate jumpto if need
	   			else
	   			{
	   				if( opts.jumpelem !== '' ) 
	   				{
   						document.location.hash=$.formid(opts.jumpelem);
	   				}
	   						
						// Do OK callback	   				
						if( opts.onokcallback !== null ) opts.onokcallback();
	   			}
	 			}, {onnohtml: opts.onnohtml} );
	 	}
	 	else if ( opts.ajaxmethod == 'post' )
	 	{
	 		PSIntra.prt_pajax = jQuery.mypost( opts.ajaxurl, pdta,
				// 'Complete' callback
				function(req,stat)
				{
					// Clear pending ajax request
					PSIntra.prt_pajax = null;
					// Hide dialog if visible
					if (opts.showajaxdlg && opts.showajaxdlg !== 1) { jQuery.dlgbtnclick(0); }
					// Is error?
					if ( stat != "success" && stat != "notmodified" )
					{
						has_error = $.drop_error( opts.errdiv, PSIntra.prt_pfe.ajaxerr + ': ' + stat + ' ' + req.status + ' ' + req.statusText );
	   			}
	 			}, false );	 		
	 	}
	 	else if( opts.ajaxmethod == 'posts' || opts.ajaxmethod == 'postsget' )
	 	{
	 		jQuery.mypost( opts.ajaxurl, pdta,
				// 'Complete' callback
				function(req,stat)
				{
					// Hide dialog if visible
					if (opts.showajaxdlg && opts.showajaxdlg !== 1) { jQuery.dlgbtnclick(0); }
					// Is error?
					if ( stat != "success" && stat != "notmodified" )
					{
						has_error = $.drop_error( opts.errdiv, PSIntra.prt_pfe.ajaxerr + ': ' + stat + ' ' + req.status + ' ' + req.statusText );
	   			}
	   			else
	   			{
	   				PSIntra.prt_last_get = req.responseText;
	   			}
	 			}, true );
	 	}
	 	else 
	 	{
			has_error = $.drop_error( PSIntra.prt_pfe.ajaxunknown + ': ' + opts.ajaxmethod );
	 	}
	 	return has_error;
	}
	
});	

// DOM object dependent functions
// call by $(selector).functionname(params)
jQuery.fn.extend({

	// Replace DOM element
  myreplaceWith: function( value ) 
  {  	
    return this.each( function () { 
        var e = $(this); 
        var p = e.parent(); 
        var s = e.prev(); 
        e.remove(); 
        
        if (s[0]) 
          s.after(value); 
        else 
          p.prepend(value); 
    }); 
  }, 
	
	// Set / get element(s) visibility
	myvisible: function( value )
	{
		if ( value===undefined )
		{
			if ( !this.length ) { return undefined; }
			return !jQuery( this[0] ).hasClass('hidden');
		}
		
		return this.each(function()
		{
			if ( value=='t')
			{
				jQuery(this).toggleClass('hidden');
			}
			else if ( value===true )
			{
				jQuery(this).removeClass('hidden');
			}
			else
			{
				jQuery(this).addClass('hidden');
			}
		});
	},
	
	// Readonly / Not-readonly elements
	// no-value 		: get readonly true / false
	// value = true : set elements as readonly
	// value = 't'  : swap readonly / not-readonly on elements
	// other-value  : set elements as not-readonly
	myreadonly: function(value)
	{
		// Get 'readonly'
		// True, if element has class 'p_readonly' or has attribute 'readonly'
		if ( value===undefined )
		{
			if ( !this.length ) { return undefined; }
			return jQuery( this[0] ).hasClass('p_readonly') || jQuery( this[0] ).attr('readonly') !== undefined;
		}
		
		return this.each(function()
		{
			// Swap readonly state
			if ( value=='t')
			{
				// If readonly
				if ( jQuery(this).hasClass('p_readonly') || jQuery(this).attr('readonly') !== undefined )
				{	
					// Set not-readonly
					jQuery(this).removeAttr('readonly').removeClass('p_readonly');
				}
				else
				{
					// Set readonly
					jQuery(this).attr('readonly','readonly').addClass('p_readonly').removeClass('p_error');
				}
			}
			// Set as readonly
			else if ( value===true )
			{
				jQuery(this).attr('readonly','readonly').addClass('p_readonly').removeClass('p_error');
			}
			// Set as not readonly
			else
			{
				jQuery(this).removeAttr('readonly').removeClass('p_readonly');				
			}
			return;
		});
	},
	
	// Enable / Disable elements
	myenable: function( value )
	{
		if ( value===undefined )
		{
			if ( !this.length ) { return undefined; }
			return !jQuery( this[0] ).hasClass('disabled');
		}
		
		return this.each(function()
		{
			if ( value=='t')
			{
				if ( jQuery(this).hasClass('disabled') )
				{
					jQuery(this).removeAttr('disabled').removeClass('disabled');
				}
				else
				{
					jQuery(this).attr('disabled','disabled').addClass('disabled').removeClass('p_error');
				}
			}
			else if ( value===true )
			{
				jQuery(this).removeAttr('disabled').removeClass('disabled');
			}
			else
			{
				jQuery(this).attr('disabled','disabled').addClass('disabled').removeClass('p_error');
			}
			return;
		});
	},

	// Get label for element (implicit defined or paired label object)
	mylab: function( value )
	{
		// Get value
		if ( value===undefined||(typeof value=="object"&&value.constructor != Array) ) 
		{
			if ( !this.length ) { return undefined; }
			var a=jQuery( this[0] ); var pl=a.attr('plabel'), l=pl;
			if (pl===undefined || pl===null || pl.indexOf('%1')>=0 )
			{	
				var t=( value!==undefined&&value.ctyp!==undefined)?value.ctyp:'';
				if (t==='') { var apt=a.attr( 'ptype' ); t=( apt===undefined||apt==='' )?0:parseInt(apt.split(';')[0],10); }				
				var id=a.attr('id'); l=(t==7)?$($.formid(id)+' legend').text():$("label[@for='" +id+ "']").text();
				if (l===undefined||l==='') { l=PSIntra.prt_pfcn[t]; }
				if (l!==''&&l.charAt(l.length-1)==':') { l=l.substr(0,l.length-1); }
				if (l!==''&&l.charAt(0)=='-') { l=l.substr(1); }
			}
			if (pl!==undefined&&pl!==null&&pl.indexOf('%1')>=0) { l=pl.replace('%1', l); }
			return l;
		}
		
		// Set value
		if ( !this.length ) { return; }
		
		return this.each(function()
		{
			var a=jQuery( this );
  		var t=(typeof value=="object"&&value.constructor==Array)?value[0]:undefined;
	  	var l=(typeof value=="object"&&value.constructor==Array)?value[1]:value;
			if ( a.attr('plabel')!==undefined ) { return a.attr('plabel', l ); }
			if (t===undefined) { var apt=a.attr( 'ptype' ); t=( apt===undefined||apt==='' )?0:parseInt(apt.split(';')[0],10); }
			var id=a.attr('id'); var lo=(t==7)?$($.formid(id)+' legend'):$("label[@for='" +id+ "']");
			if (lo!==undefined) { lo.text( l ); }
			return;
		});		
	},
	
	// Set select box text / value for given params
	// txt: text change to (if empty, not set)
	// idx: item index to set (if undefined or < 0, then selectedindex used)
	// val: value change to (if undefined, not set)
	setseltext: function(txt, idx, val )
	{
		if( this.length ) 
		{
			var elem = this[0];
			if( jQuery.nodeName( elem, "select" ) ) 
			{
				if( idx === undefined || idx < 0 ) idx=elem.selectedIndex;
				if( idx < 0 || idx >= elem.options.length ) return;
				if( txt !== '' ) elem.options[idx].text = txt;
				if( val !== undefined ) elem.options[idx].value = val;
			}
		}		
	},
	
	// Clear select box elements (options)
	clearselitems: function()
	{
		if( this.length ) 
		{
			var elem = this[0];
			if( jQuery.nodeName( elem, "select" ) ) 
			{
				while( elem.length > 0 ) 
				{
					elem.remove(0);	
				}
			}
		}		
	},	

	// Select next matcing element in a select box (search in options)
	selnextmatch: function(txt)
	{
		if( this.length ) 
		{
			var elem = this[0];
			if( jQuery.nodeName( elem, "select" ) ) 
			{
				var idx=elem.selectedIndex+1, src=txt.toLowerCase(), nidx=-1;
				while( nidx<0 && idx<elem.options.length ) 
				{
					if( elem.options[idx].text.toLowerCase().indexOf(src) >=0 ) nidx = idx;
					idx++;
				}				
				
				if( nidx >=0 ) 
				{
					elem.selectedIndex = nidx;
				}
				else if( elem.options.length > 0 )
				{
					elem.selectedIndex = 0;
				}
			}			
		}		
	},
	
	// Index of select box text (option text index in option list)
	indexofseltext: function(txt)
	{
		if( this.length ) 
		{
			var elem = this[0];
			if( jQuery.nodeName( elem, "select" ) && txt !== '' ) 
			{
				for( var i=0; i<elem.options.length; i++ ) 
				{
					if( elem.options[i].text == txt ) return i;
				}
				return -1;
			}			
		}		
		return undefined;
	},
	
	// Index of select box value (option value index in option list)
	indexofselval: function(txt)
	{
		if( this.length ) 
		{
			var elem = this[0];
			if( jQuery.nodeName( elem, "select" ) && txt !== '' ) 
			{
				for( var i=0; i<elem.options.length; i++ ) 
				{
					if( elem.options[i].value == txt ) return i;
				}
				return -1;
			}			
		}		
		return undefined;		
	},
	
	// Drop 'idx' indexed item from select box option list
	dropselitem: function(idx)
	{
		if( this.length ) 
		{
			var elem = this[0];
			if( jQuery.nodeName( elem, "select" ) ) 
			{
				if( idx === undefined || idx < 0 ) idx=elem.selectedIndex;
				if( idx < 0 || idx >= elem.options.length ) return;
				elem.remove(idx);
				if( elem.options.length > 0 ) 
				{
					if( idx >= elem.options.length ) idx--;				
					elem.selectedIndex = idx;
				}
			}
		}		
	},
	
	// Add option element to a select box
	addselitem: function(txt, val)
	{
		if( this.length ) 
		{
			var elem = this[0];
			if( jQuery.nodeName( elem, "select" ) ) 
			{
				elem.options[elem.length] = new Option(txt,val);
				elem.selectedIndex = elem.options.length - 1;
			}
		}		
	},

	// Insert 'iv' to a memo box text
	insertmemo: function (iv) 
	{
  	return this.each(function()
  		{
      	//IE support
        if (document.selection) 
        {
        	this.focus();
          sel = document.selection.createRange();
          sel.text = iv;
          this.focus();
        }
        
        //MOZILLA/NETSCAPE support
        else if (this.selectionStart || this.selectionStart == '0') 
        {
        	var startPos = this.selectionStart;
					var endPos = this.selectionEnd;
					var scrollTop = this.scrollTop;
					this.value = this.value.substring(0, startPos) + iv + this.value.substring(endPos,this.value.length);						
          this.focus();
          this.selectionStart = startPos + iv.length;
          this.selectionEnd = startPos + iv.length;
          this.scrollTop = scrollTop;
				} 

				// UNKNOWN / OTHER				
				else 
				{
        	this.value += iv;
          this.focus();
        }
      });
	},

	// Set or get elements css value as integer	
	myelemdim: function(kind, val)
	{
		if( this.length < 1 )
		{
			return undefined;	
		}
		
		if( val === undefined )
		{			
			var ao = $(this[0]), aval = parseInt( ao.css(kind), 10 );
			if( isNaN(aval) )
			{
				if( kind == 'height' )
					aval = ao.height();
				else if( kind == 'width' )
					aval = ao.width();
			}
			return aval;
		}
		
		val = parseInt( val, 10 );	
		
		return this.each(function()
		{
			jQuery(this).css(kind,val+'px');	
			return;		
		});
	},
		
	// Get selected text(s) from combo box
	getseltxt: function(index)
	{
		if( this.length ) 
		{
			var elem = this[0];
			// We need to handle select boxes special
			if( jQuery.nodeName( elem, "select" ) ) 
			{
				if( index === undefined ) index = elem.selectedIndex;
				var values  = [],
						options = elem.options,
						one     = elem.type == "select-one";

				// Nothing was selected or index is bad
				if ( index < 0 || index >= options.length ) return null;

				// Loop through all the selected options
				for( var i=one ? index : 0, max=one ? index+1 : options.length; i<max; i++ ) 
				{
					var option = options[i];
					if ( option.selected || index == i ) 
					{
						// Get the specific value for the option
						value = option.text;

						// We don't need an array for one selects
						if( one ) return value;

						// Multi-Selects return an array
						values.push( value );
					}
				}
				return values;
			}
		}
 		return undefined;
	},

	// Get selected value(s) from combo box
	getselval: function(index)
	{
		if( this.length ) 
		{
			var elem = this[0];
			// We need to handle select boxes special
			if( jQuery.nodeName( elem, "select" ) ) 
			{
				if( index === undefined ) index = elem.selectedIndex;
				var values  = [],
						options = elem.options,
						one     = elem.type == "select-one";

				// Nothing was selected or index is bad
				if ( index < 0 || index >= options.length ) return null;

				// Loop through all the selected options
				for( var i=one ? index : 0, max=one ? index+1 : options.length; i<max; i++ ) 
				{
					var option = options[i];
					if ( option.selected || index == i ) 
					{
						// Get the specific value for the option
						value = option.value;

						// We don't need an array for one selects
						if( one ) return value;

						// Multi-Selects return an array
						values.push( value );
					}
				}
				return values;
			}
		}
 		return undefined;
	},
	
	// Get / set value of input element
	myval: function( value ) 
	{
		// Get value
		if ( value===undefined||(typeof value=="object"&&value.constructor != Array) ) 
		{			
			if ( !this.length ) { return undefined;	}
			var	a = jQuery( this[0] );
			var t = ( value!==undefined&&value.ctyp!==undefined)?value.ctyp:'';
			if ( t==='' )
			{						
				var apt = a.attr( 'ptype' );
				if ( apt===undefined||apt===null||apt==='' ) { return a.val(); }
				t=parseInt(apt.split(';')[0],10);
			}
			var v='';
			switch(t) 
			{
				// CheckBox	
				case PSIntra.ftype.CheckBox: 
					if (a.is(':checked')) { v=a.val(); } else { v=a.attr('uvalue'); } 
					break;
				// Radiogroup
				case PSIntra.ftype.RadioGroup: 
					v=$("input[@name='"+a.attr('pname')+"']:checked").val(); 
					break;
				// Select
				case PSIntra.ftype.ComboBox: 
					v=a.val(); if (v=="-") { v=""; } 
					break;
				// Others
				default: 
					v=a.val(); 
					break;
			}	
			return (v===undefined||v===null)?"":v;
		}
		
		// Set value
		if ( !this.length ) { return; }
		
		return this.each(function()
		{
			// Only the radiogroup is special
			var apt=jQuery(this).attr('ptype'),t=0;
			if ( apt!==undefined&&apt!==null&&apt!=='' ) t = parseInt(apt.split(';')[0],10);
			switch(t)
			{
				// Radiogroup
				case PSIntra.ftype.RadioGroup:
					return $("input[@name='"+jQuery(this).attr('pname')+"']").val([value]);				
					break;

				// CheckBox	
				case PSIntra.ftype.CheckBox: 
				  if( jQuery(this).attr('uvalue') == value ) this.checked = false;
					// Leave run to others...
										
				// Others
				default:
					return jQuery(this).val(value);
					break;
			}
		});
	},					

	// Load something by AJAX	
	myload: function( url, params, callback, opt ) 
	{ 
		var off = url.indexOf(" ");
		if ( off >= 0 ) 
		{
			var selector = url.slice(off, url.length);
			url = url.slice(0, off);
		}

		var opts=$.extend({
			onnohtml:     null   // No html result loaded callback
			}, opt || {} );
	
		callback = callback || function(){};
	
		// Default to a GET request
		var type = "GET";
	
		// If the second parameter was provided	
		if ( params )
		{
			// If it's a function
			if ( jQuery.isFunction( params ) ) 
			{
				// We assume that it's the callback
				callback = params;
				params = null;
	
			// Otherwise, build a param string
			} 
			else 
			{
				// If it's a 'reload' call, and path not given...
				if( params[PSIntra.prt_ajaxfunc]=='reload'&&params['_cpa']===undefined)
				{
					params['_cpa'] = this.attr('psrc');
					if ( params['_cpa']===null||params['_cpa']===undefined ) params['_cpa'] = '';
				}
	
				params = jQuery.param( params );
				type = "POST";
			}
		}
		
		var self = this;
	
		// Request the remote document
		$.update_access();
		PSIntra.prt_pajax = jQuery.ajax({
			url: url,
			type: type,
			dataType: "html",
			data: params,
			complete: function(res, status){
				PSIntra.prt_pajax = null;
				// If successful, inject the HTML into all the matched elements
				if ( status == "success" || status == "notmodified" )
				{
					var inject=true, cpos=0;
					if( opts.onnohtml !== null )
					{
						while( cpos<res.responseText.length && res.responseText.charCodeAt(cpos)<=32 ) cpos++;
						inject = cpos<res.responseText.length && res.responseText.charCodeAt(cpos) == 60;
					}					
				
					if( inject )
					{
						// See if a selector was specified
						self.html( selector ?
		  				// Create a dummy div to hold the results
			  			// inject the contents of the document in, removing the scripts
							// to avoid any 'Permission Denied' errors in IE					
							// Locate the specified elements
							jQuery("<div/>").append(res.responseText.replace(/<script(.|\s)*?\/script>/g, "")).find(selector) :
							// If not, just inject the full result
							res.responseText );
					}
					else
					{
						opts.onnohtml( cpos==0 ? res.responseText : res.responseText.substr( cpos ) );
					}
				}
				self.each( callback, [res.responseText, status, res] );
			}
		});
		return this;
	}
});

// Validate and AJAX a portal form
jQuery.formvalidate = function(f,opt,padd) 
{
	var opts=$.extend({
		skip_sel:		 '',		 					// Skip selectors (if there are many not checked/not posted controls
		nocheck:     false,  					// Don't check, just post
		limiter:		 '',		 					// Limiter container, if empty f_f willbe used
		showerrdlg:  true,   					// Show error dialog
		cutformname: true,   					// Cut form name from post var names to post
		doajaxonok:  'load', 					// Do ajax call on ok
		showajaxdlg: false,  					// show ajax dialog on post
		ajaxabort:   false,  					// ajax call abortable		
		addsessid:   true,   					// add session id to ajax call
		ajaxfunc:		 '',     					// Ajax function to call
		ajaxurl:     'ajaxgate.php', 	// AJAX url to call
		targetelem:  '',     					// AJAX target element (if empty, full page reload)
		errdiv:      'port_warning',  // Error div selector, if '-' use 'alert'
		showerrdiv:  false,  					// Use errdiv to show form errors?
		okcallback:  null,   					// callback on data ok: bool okcallback( object data_to_post )
		maxerrors:   10,		 					// Maximum error count, when check is stop (to prevent too large error messages)
		jumpelem:		 '',  	 					// Element ID, which is located after ajax load
		showstat:		 false,  					// Show statistics
		callerform:	 null							// Caller form object
		}, opt || {} );
			
	var msgs=[], foce=null, focet=0, stat={ elcnt: 0, elchk: 0, elsbm: 0, eltyp: {}, startt: 0, selt: 0, endt: 0 };
	var pdta=$.extend({}, padd || {});

	// Format a message (sm-constant, or m-from prt_pfe), with two parameters (p1,p2)
	function fm(m,p1,p2,sm)
	{
		if (sm===undefined) { sm=PSIntra.prt_pfe[m]; } if (p1==='') { return sm+'<br />';	}
		var r=fh(sm,'1',p1);  if (p2==='') { return r+'<br />'; }
		return fh(r,'2',p2)+'<br />';		
	}

  // Replace parameter 'i'. (%1 .. %n)
	// In a message 'm', for a value 'p'
	// Use hungarian 'a' or 'az' if needed (signed by '(z)', in the message)
	function fh(m,i,p)
	{
		if ( m.indexOf('(z) %'+i)>= 0 )
		{
			if ( 'euioaöüóőúéáű15'.indexOf(p.substr(0,1).toLowerCase())>=0 )
			{
				m=m.replace('(z) %'+i,'z %'+i); 
			}
			else 
			{
				m=m.replace('(z) %'+i,' %'+i);
			}
		}
		return m.replace('%'+i,'<b>'+p+'</b>');		
	}
	
	// Base selector for checked DOM objects
	// + Input AND Visible AND NOT(Disabled OR Button)
	// - opts.skip_sel
	// + Input-Hidden + Fieldset (Radio Group)
	var asel=":input:visible:not(.disabled,:button)"+opts.skip_sel+",input[@type='hidden'],fieldset";
	
	if( opts.showstat )
	{		
		stat.startt = new Date().getTime();
		stat.selt   = stat.startt;
	}
	
	// Limiter container for element selection
	// Default: 'formname_formname'
	var lmc = ( opts.limiter != '' ) ? opts.limiter : f+'_'+f;
	
	// See through DOM object to check / post
	jQuery.each( $(asel, $.formid(lmc)), function(eidx,o)
	{	
		// Statisctics
		if( opts.showstat )
		{
			if( eidx==0 ) stat.selt = new Date().getTime(); stat.elcnt++;		
			var atn=o.tagName.toLowerCase(); if( atn === 'input' ) atn=atn+'-'+o.type;
			stat.eltyp[atn] = (stat.eltyp[atn] || 0 )+1;
		}
		
		// PTYPE is: type;check_flags;minlen;minval;maxval;spec_call
		// Elemenet has a form input type + Need to check, Need to submit
		var a=jQuery(o), pt=a.attr("ptype"), n_c=false, n_s=false;

		// If has check val visible
		if ( pt!==undefined&&pt!==null )
		{
			// Parameter array
			var pr=pt.split(';'), prl=pr.length, i=prl-1; 
			while(i>=0&&pr[i]==='') { i--; } prl=i+1;
			// Input type
			var t=parseInt(pr[0],10);								
			// has to submit?
  		n_s=!isNaN(t)&&a.is(':enabled');
  		// has to check?
  		n_c=n_s&&t!=6; // &&a.is(':visible'); - put to selector
  		// If need check, let's see parents visible...  		
  		if (n_c)
  		{
  			// Check if parents visible... (just up to the container-form element or to the for 'check-visible-stop' element)
				var p=a.parents(), j=0;				 
				while(j<p.length && jQuery(p[j]).is(':visible') ) 
				{
					if( jQuery(p[j]).attr('id') == f+'_'+f || jQuery(p[j]).attr('pvisistop') == '1' )
						j=p.length;
					else					 
						j++; 
				}
				// If not hidden and not visible, no check, no submit
  			n_c=(j==p.length); n_s=n_c;  			
  		}
  		
			// If need to submit or need to check			
			if (n_c||n_s)
			{
				// Taborder
				var tabor=parseInt(a.attr('tabindex'),10), tabo='00000';
				if (isNaN(tabor))
				{ 
					tabor=0; 
				} 
				else 
				{ 
					tabo = tabor.toString() + ':';				
					while(tabo.length<5) { tabo='0'+tabo; }
				}
								
				// VALUE
				var v=a.myval({ctyp: t});
				
				// Check flag
				var cc=prl>1?parseInt(pr[1],10):0;
				
				// Added: read-only not-check
				var is_ro = a.attr('readonly');
				if( is_ro!==false && is_ro!==undefined && is_ro!=='' && is_ro!==null ) n_c=false;				

				// if need to check
				if (!opts.nocheck&&n_c&&(cc>0||prl>2))
				{					
					stat.elchk++;
					// ID / LABEL / ERR element
					var id=a.attr('id'), l=a.mylab(), ee=t!=4?a:$($.formid('wrap_'+id));
	
					// Start Check
					var ok=true;
					
					// ------- FLAG: Showit
					if (cc&128) { alert ( '"' + l + '" value: :' + v + ':' ); }
									
					// ------- FLAG: Required
					if (ok&&(cc&1)&&(v===""))
					{	
						msgs.push(tabo+fm(t==4?'e_req2':(t==3||t==7?'e_req3':'e_req1'),l,'')); ok=false;
					}

					// ------- FLAG: Integer
					if (ok&&(cc&8)&&(v!==""))
					{
						ok=( parseInt(v,10).toString()==v );
						if (!ok) { msgs.push(tabo+fm('e_int',l,'')); }
					}				

					// ------- FLAG: Float
					if (ok&&(cc&16)&&(v!==""))
					{
						ok=!isNaN(parseFloat(v));
						if (!ok) { msgs.push(tabo+fm('e_real',l,'')); }					
					}				
				
					// ------- ATTR: Has min length
					if (ok&&prl>2&&pr[2]!==""&&v!=="")
					{
						var ml=parseInt(pr[2],10); ok=(isNaN(ml)||ml===0||v.length>=ml);
						if (!ok) { msgs.push(tabo+fm('e_minl',l,ml.toString())); }
					}
					
					// ------- FLAG: Phone = 1/123-4567, 12/123-4567, 12/123-456 
					// can contains only space, number, '/' and '-'
					if (ok&&(cc&32)&&v!=="")
					{
						i=0; while(ok&&i<v.length) { ok=(' 0123456789/-'.indexOf(v.charAt(i++))>=0); }
						if (!ok) { msgs.push(tabo+fm('e_phon',l,i)); }
					}

					// ------- FLAG: Email	
				  if ( ok&&(cc&2)&&(v!=="") )
				  {
						ok = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(v);
						if (!ok) 
						{ 
							msgs.push(tabo+fm('e_mail',l,'')); 
						}
						else
						{
							ok = !/[\ö\ü\ó\ő\ú\é\á\ű\í\Ö\Ü\Ó\Ő\Ú\É\Á\Ű\Í]/.test(v);
						
							if( !ok )
							{
								msgs.push(tabo+fm('e_mlac',l,''));
							}
						}
				  }
				
					// ------- FLAG: Date = yyyy.mm.dd
					var ad, ymd;
				  if ( ok&&(cc&4)&&(v!=="") )
				  {
				  	// No '.' - reformat
				  	if( v.length == 8 ) {	v = $.reformatdate( v, a );	}
				  	ad = $.getdateYMD(v);
				  	ok = ( ad !== null );
				  	if (!ok) { msgs.push(tabo+fm('e_date',l,'')); }
				  }
				  
				  // ------- FLAG: Bank account
				  if ( ok&&(cc&512)&&(v!=="") )
				  {
				  	// No '-' - reformat
				  	if( v.length == 16 )
				  	{				  		
				  		v = v.substr(0,8) + '-' + v.substr(8,8);
				  	}
				  	else if( v.length == 24 )
				  	{
				  		v = v.substr(0,8) + '-' + v.substr(8,8) + '-' + v.substr(16,8);				  		
				  	}
				  	ok = $.checkhunba(v);
				  	if (!ok) { msgs.push(tabo+fm('e_bbad',l,'')); }
					}

					// ------- FLAG: DateTime = yyyy.mm.dd hh:mm
				  if ( ok&&(cc&64)&&(v!=="") )
				  {
				  	// No '.' - reformat
				  	if( v.length == 8 ) {	v = $.reformatdate( v, a );	}
				  	ad = $.getdatetimeYMDhm(v);
				  	ok = ( ad !== null );
				  	if (!ok) { msgs.push(tabo+fm('e_dati',l,'')); }
				  }

					// ------- ATTR: Minval
					if ( ok&&(v!=="")&&prl>3&&pr[3]!=="" )
					{
						// Date
						if (cc&4)
						{
							// Min is valid (and what is it?)
							var cd=$.getdatecheckval(pr[3],false);
						
							if ( cd!==null )
							{
								cd.setHours(0,0,0,0); ok=ad>=cd; 
				  			if (!ok) { msgs.push(tabo+fm('e_minv',l,$.getdateSTR(cd,false))); }
							}
						}				
						// Date-Time
						else if (cc&64)
						{
							// Min is valid (and what is it?)
							var cd=$.getdatecheckval(pr[3],true);
						
							if ( cd!==null )
							{
								ok=ad>=cd; 
				  			if (!ok) { msgs.push(tabo+fm('e_minv',l,$.getdateSTR(cd,false))); }
							}
						}										
						// Integer
						else if (cc&8)
						{	
							var cv=pr[3]=='y'?(new Date().getFullYear()):parseInt(pr[3],10); 
							ok=isNaN(cv)||(parseInt(v,10)>=cv);							
				  		if (!ok) { msgs.push(tabo+fm('e_minv',l,cv.toString())); }
						}		
						// Float
						else if (cc&16)
						{
							var cv=parseFloat(pr[3]); ok=isNaN(cv)||(parseFloat(v)>=cv);							
				  		if (!ok) { msgs.push(tabo+fm('e_minv',l,pr[3])); }
						}
					}

					// ------- ATTR: Maxval
					if ( ok&&(v!=="")&&prl>4&&pr[4]!=="" )
					{
						// Date
						if (cc&4)
						{
							// Max is valid (and what is it?)
							var cd=$.getdatecheckval(pr[4],false);
							
							if ( cd!==null )
							{
								cd.setHours(0,0,0,0); ok=ad<=cd; 
				  			if (!ok) { msgs.push(tabo+fm('e_maxv',l,$.getdateSTR(cd,false))); }
							}
						}				
						// Date-Time
						else if (cc&64)
						{
							// Max is valid (and what is it?)
							var cd=$.getdatecheckval(pr[4],true,'23:59');
							
							if ( cd!==null )
							{
								ok=ad<=cd; 
				  			if (!ok) { msgs.push(tabo+fm('e_maxv',l,$.getdateSTR(cd,false))); }
							}
						}										
						// Integer
						else if (cc&8)
						{
							var cv=pr[4]=='y'?(new Date().getFullYear()):parseInt(pr[4],10);
							ok=isNaN(cv)||(parseInt(v,10)<=cv);							
				  		if (!ok) { msgs.push(tabo+fm('e_maxv',l,cv.toString())); }
						}		
						// Float
						else if (cc&16)
						{
							var cv=parseFloat(pr[4]); ok=isNaN(cv)||(parseFloat(v)<=cv);
				  		if (!ok) { msgs.push(tabo+fm('e_maxv',l,pr[4])); }
						}
						// String (only MEMO)
						else if (t==2)
						{
							var cv=parseInt(pr[4],10);
							ok=isNaN(cv)||(v.length<=cv);
							if(!ok) { msgs.push(tabo+fm('e_maxl',l,pr[4])); }
						}
					}
					
					// ------- ATTR: Spec. check
					// proto is: string check( int input_type, string label, string curr_value, jquery object_itself );
					if ( ok&&prl>5&&pr[5]!==""&&(v!==""||(cc&256)) )
					{
						var ejs = pr[5]+"("+t+",'"+l+"','"+v.replace(/\'/gi, "\\'")+"',a);";
						var am=eval(ejs);
						ok=am===undefined||am===""; if (!ok) { msgs.push(tabo+fm('',l,'',am)); }
					}
										
				  // ------- FINAL: Every check evaluated ------
				  if ( ee!==undefined&&ee!==null ) 
				  {
				  	if (ok)
				  	{
				  		if (ee.hasClass('p_error')) 
				  		{ 
				  			ee.removeClass('p_error'); 
				  			if (t==7) { $($.formid(id)+' legend').removeClass('p_error'); }
				  		}
				  	}
				  	else
				  	{
				  		if (!ee.hasClass('p_error') ) 
				  		{
				  			ee.addClass('p_error');   	
				  			if (t==7) { $($.formid(id)+' legend').addClass('p_error'); }
				  		}
				  		if (foce===null||tabor<focet) { foce=t!=7?a:$($.formid('i0_')+id); focet=tabor; }
				  	}
					}	
					
				}	// end need_check
				
				// Submit value
				// put here to end, because of 'reformatdate'
				if (n_s)
				{
					var n=t!=7?a.attr("name"):a.attr("pname");
					if (n!==undefined&&n!==null&&n!=='')
					{
						if ( opts.cutformname && n.indexOf(f+'_')===0 ) { n=n.substr(f.length+1); }		
						
						// Handle CSS 'text-transform' at editbox
						if(t==1)
						{
							var ttr=a.css('text-transform');
							if ( ttr=='uppercase' ) v=v.toUpperCase();
							else if( ttr=='lowercase' ) v=v.toLowerCase();
							else if( ttr=='capitalize' ) v=$.mycapital(v);
						}
						pdta[n]=v;						
						stat.elsbm++;
					}
				}
				
			}	// end need_check or need_submit
		} // end has ptype
	});
	
	// Show stat, if need
	if( opts.showstat )
	{
		// Ending time
		stat.endt = new Date().getTime();
		var tstat='', tims = 
			'\n- Select time: ' + ( stat.selt - stat.startt ) + 
			' msec\n- Parsing time: ' + ( stat.endt - stat.selt ) +
			' msec\n- Total time: ' + ( stat.endt - stat.startt ) + ' msec';
		for( var j in stat.eltyp ) tstat += '\n    - ' + j + ': '+ stat.eltyp[j];
		alert( 'Statistics:\n- Selector: '+asel+'\n- Total elems: '+stat.elcnt+tstat+'\n- Checked: '+stat.elchk+'\n- Errors: '+msgs.length+'\n- Sumbitted: '+stat.elsbm+tims );
	}

	// Save error messages
	PSIntra.prt_plasterr='';
	var errcnt=msgs.length;
	if (errcnt>0)
	{
		msgs.sort(); for(var i=0;i<errcnt;i++) { if(i<opts.maxerrors) { PSIntra.prt_plasterr+=msgs[i].substr(5); } }
		if( errcnt>opts.maxerrors && opts.maxerrors > 1 ) { PSIntra.prt_plasterr+=PSIntra.prt_pfe.e_maxe };
	}
 	
	// We have errors
	if (PSIntra.prt_plasterr!=='') 
	{ 
		if (opts.showerrdlg) 
		{ 
			$.showdialog(PSIntra.prt_pfe.errorcap,'<ul class="err_ul">'+PSIntra.prt_plasterr+'</ul>',1+512,foce); 
		} 
		else if (opts.showerrdiv)
		{
			if( opts.errdiv!=='-' )
			{
				$(opts.errdiv).html('<div class="skn_messE"><ul class="err_ul">'+PSIntra.prt_plasterr+'</ul></div>' );
			}
			else
			{
				alert( $.striptags(PSIntra.prt_plasterr) );
			}			
			if (foce!==null) { foce.focus(); }
		}
		return false;
	}

	// We have on_ok callback? (extend posted data)
	if ( opts.okcallback !== null )
	{
		var ret = opts.okcallback( pdta, opts.callerform );
		if( ret === false ) return false;
		else if( typeof ret == "object" ) pdta=$.extend(pdta, ret || {});						
	}

	// Show post data
	if( opts.showstat )
	{
		var tstat='';
		for( var j in pdta ) tstat += '\n - ' + j + ' : "'+ pdta[j]+'"';
		alert( 'Post data:' + tstat );
	}

	// Do ajax call?	
	if ( opts.doajaxonok !== '' )
	{		
		PSIntra.prt_plasterr = $.myajax(
			{
			ajaxmethod:  opts.doajaxonok,
			showajaxdlg: opts.showajaxdlg,
			ajaxabort:   opts.ajaxabort,
			addsessid:   opts.addsessid,
			ajaxfunc:		 opts.ajaxfunc,
			ajaxurl:     opts.ajaxurl,
			baseelem:		 f+'_'+f,
			targetelem:  opts.targetelem,
			errdiv:      opts.errdiv,
			jumpelem:		 opts.jumpelem
			}, pdta );
	}	
	return (PSIntra.prt_plasterr==='');
};

// General form class declaration
var psform =
{
  params 			 : {},									// Form user parameters
  formname 		 : '',  								// Form name
  postajaxfunc : '',  								// Ajax func name on post
  showpostdata : PSIntra.globaldebug, // Show post data?
  targetblock  : '',									// Target block to load-in
	baseblock    : '',									// Base block to load-in
  errorblock   : '',									// Error block
  stepdirvar   : '',									// Step direction var (at post)
  stepcurrvar  : '',									// Step current var (at post)
  currstep     : '',  								// Current step
  ajaxgate     : 'ajaxgate.php',  		// Ajax Gate URL

	// Called before AJAX call (stepnext, stepback, steptomain)
	extrapostcallback : function( pdta, stepdir )
	{
		return pdta;
	},
	
	// Deep copy of the object (for extend / inheritance)
	createform: function()
	{
		return $.extend( {}, psform );
	},
	
	// Called from formvalidate-okcallback stepnext
	formnextokcallback : function( pdta, theform )
	{
		return true;
	},

	// Called from formvalidate-okcallback stepback
	formprevokcallback : function( pdta, theform )
	{
		return true;	
	},
	
	// Get elem as object, by 'name' ON the form
	// ename  - element name
	// ascont - as container element? (for dimensions)
  getelem : function(ename,ascont)
  {
  	// Alapértelmezett: 'nem konténerként'
  	if( ascont === undefined ) ascont = false;
  	
  	// Ha nincs megadva a név, akkor a form maga az elem
  	var theform = $('#'+this.formname+'_'+this.formname);
  	if( ename === "" || ename === undefined) { return theform;	}
  	
  	// Az elem maga
  	var baseelem = $('#'+this.formname+'_'+ename, theform );
  	
  	// Ha nem találjuk, nézzük meg a globális DOM-ban, mert
  	// pl. a showdialog átlinkeli a target div-et a formról
  	// magára
  	if( baseelem.length == 0 )
  	{
  		baseelem = $('#'+this.formname+'_'+ename );
  		// Ha itt sincs, nincs mit tenni...
  		if( baseelem.length == 0 )
  		{
  			return baseelem;
  		}
  	}
  	
  	// Ha nem konténerként, akkor ennyi
  	if( !ascont ) return baseelem;
  	
  	// Elem típusa, ha nincs, akkor ennyi
  	var p=baseelem.attr('ptype');
  	if( p===undefined || p==='' )
  	{  		
  		// <A> ellenőrzése (gomb)
  		if( baseelem[0].tagName == 'A' && baseelem.parent().hasClass('p_cbwrapper') )
  		{
  			return baseelem.parent();	
  		}
  		return baseelem;	
  	}	
  	
  	// A checkboxnak van wrappere
  	// Checkbox (div+ input-checkbox + label)
  	if( parseInt(p.split(';')[0], 10) == PSIntra.ftype.CheckBox )
  	{
  		return $('#wrap_'+this.formname+'_'+ename, theform );	
  	}

		// A többinél ugyanaz a konténerelem, amire hivatkozott az ID  	
	  // Unknown, rendered as red rectangle (div)
		// Editbox (input-text)
		// Memo (textarea)
		// Combobox (select)
		// Button (input - button/submit/reset, or skin rendered (<a>...</a>)
		// Hidden (input-hidden)
		// Radiogroup (fieldset-legend+input-radios)
		// Panel (div)
		// GroupBox (container div + header div)
		// Label (label)
		// Link (a)
		// Rendered as div+HTML content
		// Captha code image (div+img)
		// File upload (input-file)
		// DBGrid (jqgrid/div)
		return baseelem;
  },

	// Get form caption as Jquery object
	// Set caption html for cnt (if given)
	formcaption : function(cnt)
	{
		var capel = $('#caption_' + this.formname);
		if( cnt !== undefined && capel.length > 0 )
		{
			capel.html(cnt);	
		}
		return capel;
	},
	
	// Get elem value, by 'name' ON the form
  getelemval : function(ename)
  {
    return this.getelem(ename).myval();
  },

	// Set elem value, by 'name' ON the form
  setelemval : function(ename,aval)
  {
    return this.getelem(ename).myval(aval);
  },

	// Get elem value as INT, by 'name' ON the form
  getelemvalasint : function(ename)
  {
    return parseInt(this.getelemval(ename), 10 );
  },

	// Get elem specified dimension
	// left / top / width / height
	getelemdim : function(ename, dimnam)
	{
		var ao = this.getelem(ename,true), aval = parseInt( ao.css(dimnam), 10 );
		if( isNaN(aval) )
		{
			if( dimnam == 'height' )
				aval = ao.height();
			else if( dimnam == 'width' )
				aval = ao.width();
		}
		return aval;
	},

	// Set elem specified dimension
	// left / top / width / height
	setelemdim : function(ename, dimnam, dimval)
	{
		return this.getelem(ename,true).css(dimnam,dimval+'px');	
	},

	// Modify elem specified dimension
	// left / top / width / height
	modelemdim : function(ename, dimnam, modval)
	{
		var dimval = this.getelemdim(ename,dimnam) + modval;
		return this.setelemdim(ename,dimnam,dimval);
	},

	// Get / set element visibility
	elemvisible : function(ename, isvisi )
	{
		if( isvisi === undefined )
		{
			return this.getelem(ename,true).myvisible();
		}
		
		return this.getelem(ename,true).myvisible(isvisi);
	},
	
	// Get / set element enabled
	elemenable : function(ename, isenab )
	{
		if( isenab === undefined )
		{
			return this.getelem(ename).myenable();
		}
		
		return this.getelem(ename).myenable(isenab);
	},

	// Get / set element readonly
	elemreadonly : function(ename, isro )
	{
		if( isro === undefined )
		{
			return this.getelem(ename).myreadonly();
		}
		
		return this.getelem(ename).myreadonly(isro);
	},
	
  // Rendszám ellenőrzése check callback
  checkrendszam : function(typ,lab,val,ao)
  {
  	if( val.toUpperCase().match(/^[A-Z0-9\-]{6}$/) )
  	{
  		return '';	
  	}
  	return '<li>A(z) %1 nem érvényes formátumú.';
  },

	// Check hungarian ZIP check callback
  checkirsz : function(typ,lab,val,ao)
  {
    var pdta = {irsz: val}; $.addsid(pdta); pdta[PSIntra.prt_ajaxfunc]='zipcheck';
    if ( val!=$.mygetbypost( 'ajaxgate.php', pdta ) )
    { return PSIntra.prt_pfe.e_bzip; }
    else
    { return ''; }
  },

	//----------------------------------------------------------------------------------------
	// Redraw background stripes from top to down alternate
	//----------------------------------------------------------------------------------------	
	// Inputs:
	// container - konténer elem, amin belül a stripe-okat keressük (ha nincs megadva, a form maga)
	// classbase - CSS class kezdete, amire stripe-nak tekintünk egy container-child elemet
	// c1				 - classbase+c1 lesz a CSS classa a felülről számolva PÁRATLAN (első, harmadik...) csíkoknak
	// c2				 - classbase+c2 lesz a CSS classa a felülről számolva PÁROS (második, negyedik...) csíkoknak	
	// start1    - Ha true, akkor a fentiek szerint csíkoz. Ha false, akkor fordítva. (ha nincs megadva, true)
	// Returns:
	// - True:  Ha c2 classú volt a legalsó színezett elem
	// - False: Ha c1 classú volt a legalsó színezett elem
	//----------------------------------------------------------------------------------------	
	redrawstripes : function( classbase, c1, c2, start1, container )
	{
		if( start1 === undefined )
		{
			start1 = true;	
		}
		
		if( container === undefined ) 
		{
			container = this.getelem('');
		}
		
		return $.restripes( container, classbase, c1, c2, start1 );
	
		/*
		// Stripes on form
		var stripes = $('div[class^="'+classbase+'"]', this.getelem(''));
		if( stripes.length == 0 ) return;
		
		// Save stripe data
		var stdat = [];
		for( var i=0; i < stripes.length; i++ )
		{			
			if( $(stripes[i]).myvisible() )
			{
				var atop = parseInt( $(stripes[i]).css('top'), 10 );
				stdat.push( {idx: i, top: atop} );
			}
		}
		
		// Sort stripe data
		stdat.sort( function(a,b)	{	if( a.top == b.top ) return a.idx - b.idx; else return a.top - b.top; } );
		
		// Re-classify by sort order
		var cends = [c1,c2];
		for( var i=0; i < stdat.length; i++ )
		{
			var ac1 = cends[i%2], ac2 = cends[1-(i%2)];
			$(stripes[stdat[i].idx]).removeClass(''+classbase+ac2).addClass(''+classbase+ac1);
		}	
		*/		
	},

	// Form tetejének bescrollozása a view-ba, ha nincs benne
	scrollforminview : function()
	{
	  // Ugrás a form tetejére, ha nincs a view-ban
    var pagetop = $(document).scrollTop();
    var poffset = this.getelem('').parent().offset();
    if( poffset.top < pagetop ) window.scrollTo(poffset.left, poffset.top);
  },

	// Fill select box with city names, by hungarian ZIP code
  fillvarosbyirsz : function( a, ai )
  {
    var pdta = {irsz: ai}; $.addsid(pdta); pdta[PSIntra.prt_ajaxfunc]='getcity';
    var avar = $.mygetbypost( 'ajaxgate.php', pdta );
    a.html(avar);
  },
  
  // Step to the next form (in a wizard)
  stepnext : function(extrapost)
  {
  	// If we have a pending AJAX, drop the call
    if (PSIntra.prt_pajax!==null) return false;

		// Setup extra post data
    var stepdata = $.extend( {}, extrapost || {} );
    // Current step + direction
    stepdata[this.stepdirvar]  = 2;
    stepdata[this.stepcurrvar] = this.currstep;
		// Extend with extra data callback
		stepdata = this.extrapostcallback( stepdata, 2 );

		// Do form validation and post the data and load next stage
    $.formvalidate(this.formname,
    {
    	callerform:		this,
    	showstat:			this.showpostdata,
    	okcallback:   this.formnextokcallback,
      nocheck: 			false,
      showerrdlg:		true,
      cutformname:	true,
      doajaxonok:		'load',
      showajaxdlg:	false,
      ajaxabort:		false,
      addsessid:		true,
      ajaxfunc: 		this.postajaxfunc,
      ajaxurl: 			this.ajaxgate,
      targetelem: 	this.targetblock,
      baseelem: 		this.baseblock,
      errdiv: 			this.errorblock,
      showerrdiv:	  false
    }, stepdata );
    return false;
  },
 
  // Step to the previous form (in a wizard)
  stepback : function(extrapost)
  {
  	// If we have a pending AJAX, drop the call
    if (PSIntra.prt_pajax!==null) return false;

		// Setup extra post data
    var stepdata = $.extend( {}, extrapost || {} );
    // Current step + direction
    stepdata[this.stepdirvar]  = 1;
    stepdata[this.stepcurrvar] = this.currstep;
		// Extend with extra data callback
		stepdata = this.extrapostcallback( stepdata, 1 );

		// Don't do form validation (because we step backward)
		// Just post the data and load previous stage
    $.formvalidate(this.formname,
    {
    	callerform:		this,    	
    	showstat:			this.showpostdata,
    	okcallback:   this.formprevokcallback,
    	nocheck: 			true,
      showerrdlg:		false,
      cutformname:	true,
      doajaxonok:		'load',
      showajaxdlg:	false,
      ajaxabort:		false,
      addsessid:		true,
      ajaxfunc: 		this.postajaxfunc,
      ajaxurl: 			this.ajaxgate,
      targetelem: 	this.targetblock,
      baseelem: 		this.baseblock,
      errdiv: 			this.errorblock,
      showerrdiv:		false
    }, stepdata );
    return false;
  },
  
  // Step back to main page (from first step)  
	stepbacktomain: function(nodeid, extrapost)
	{
		// Node id jump to (default 0 - main page)
		if( nodeid === undefined ) nodeid = 0;
		
  	// If we have a pending AJAX, drop the call
	  if (PSIntra.prt_pajax!==null) return false;

		// Setup extra post data
    var stepdata = $.extend( { _norender: 1 }, extrapost || {} );
    // Current step + direction
    stepdata[this.stepdirvar]  = 1;
    stepdata[this.stepcurrvar] = this.currstep;
		// Extend with extra data callback
		stepdata = this.extrapostcallback( stepdata, 1 );
		
		// Don't do form validation (because we step backward)
		// Just (synchron) post the data. Don't load anything.
	  var pok = $.formvalidate(this.formname,
	  {
    	callerform:		this,	  	
	  	showstat:			this.showpostdata,
    	okcallback:   this.formprevokcallback,
	    nocheck: 			true,
	    showerrdlg:		false,
	    cutformname:	true,
	    doajaxonok:		'posts',
	    showajaxdlg:	false,
	    ajaxabort:		false,
	    addsessid:		true,
      ajaxfunc: 		this.postajaxfunc,
      ajaxurl: 			this.ajaxgate,
      targetelem: 	this.targetblock,
      baseelem: 		this.baseblock,
      errdiv: 			this.errorblock,
      showerrdiv:		false
	  }, stepdata );
	
		// After, we made the post, load the main page...
	  if( pok ) location.href = 'index.php?nod='+nodeid+'&' + PSIntra.prt_phpsess;
	  return false;
	}  
  
};
