//KeyCodes
var kReturn=13;
var kTab=9;
var kEsc=27;

// Support for expanders @ Lister

var expander_open=new Array();    
	/* we remember opened expanders so we know what to do when clicked */
var inline_active=new Array();
	/* same as for expanders, but applying to inline edits. 
	they should be processed differently 
	this array contains URLs to close inlines
	*/
function inline_is_active(name,id){
		if(inline_active[name])return inline_active[name][id];
		else return false;
}

function expander_is_open(name,id,button){
	/*
	* This would just return exander's state on a button click. If another expander is
	* open, it would not do anything, just return it's button's name.
	*/
	//inlines should be hidden anyway
	if(inline_is_active(name,id))return "inline_active";

	id=name+"_"+id;

	if(expander_open[id]==button){
		expander_open[id]='';
		return "_closing";
	}else if(expander_open[id]){
		return expander_open[id];
	}else{
		expander_open[id]=button;
		return "_opening";
	}
}

function button_on(id){
	/*
	* Highlight expander button as it was pressed
	*/
	button=document.getElementById(id);

	for(c=button.parentNode.firstChild;c;c=c.nextSibling){
		if(c==button)continue;
		if(!c.style)continue;
		c.className='expanded_other';
	}

	button.className='expanded_this';
}

function button_off(id){
	/*
	* highlight expander button as it was released
	*/
	button=document.getElementById(id);

	for(c=button.parentNode.firstChild;c;c=c.nextSibling){
		if(c==button)continue;
		if(!c.style)continue;
		c.className='not_expanded';
	}

	button.className='not_expanded';
}

function expand(id,step){
	/*
	* This adds a bit of animation. It would "grow" div over time. Use this on a temporary div,
	* so that when it's gone from the page, expanding effect will cease itself
	*/
	if(step>200)return;
	expander=document.getElementById(id);
	if(!expander)return;
	expander.style.paddingBottom=step+"px";
	setTimeout("expand('"+id+"',"+(30+step)+")",50);
}

function expander_flip(name,id,button,expander_url){
	/*
	* This opens / closes lister's expander. Use this function
	* under 'onclick' for your table row. It will take care of
	* adding additional row and loading content there. expander_url is
	* a prefix, which will have id appended
	*/

	row=document.getElementById(name+"_"+id);
	expander_status = expander_is_open(name,id,button);
	if(expander_status=="_closing"){
		nextrow=row.nextSibling;
		row.parentNode.removeChild(nextrow);

		button_off(name+"_"+button+"_"+id);
	}else if(expander_status=="inline_active"){
		inline_hide(name,id);
		expander_flip(name,id,button,expander_url);
	}else if(expander_status=="_opening"){
		
		tmp=document.getElementById(row.id);
		tmp=tmp.getElementsByTagName('TD');
		cs=0;
		while (tmp[cs] != null) cs++;
		newrow=document.createElement("tr");
		nextrow=row.nextSibling;
		if(!nextrow){
			row.parentNode.appendChild(newrow);
		}else{
			row.parentNode.insertBefore(newrow,nextrow);
		}
		/* -- rem by chk
		my_td=document.createElement("td");
		my_td.colspan=cs;
		-- /rem by chk*/
		
		/* TODO: here is some template-dependant stuff. It's better to move this thing
		* out. Not sure if the temporary thing can me removed easily, but the background
		* color should be customizable. And it's even better to use class names, BTW!
		*/
//        bg="#FFFFFF";
		
		/* chk */
		//tmp = row./*parentNode.firstChild.*/childNodes;
		//alert(tmp.length);

		cll = newrow.insertCell(0);
		cll.style.backgroundColor = "#FFFFFF";
		cll.style.borderWidth = '0 1px 1px 1px';
		cll.style.borderColor = '#000';
		cll.style.borderStyle = 'solid';
		cll.style.padding = '15px';
		
		cll.colSpan = cs; //row.parentNode.firstChild.childNodes.length;
		
		//cll.id = name+"_expandedcontent_"+id;        
		cll.setAttribute('id', name+"_expandedcontent_"+id);
		
		cll.innerHTML = '<table cellspacing=0 cellpadding=0 border=0><tr><td valign=top><img alt="" src="'+am_loading+'"></td><td>&nbsp;</td><td class="smalltext" align=center id="autoexpander_'+id+'" valign=top><b>Loading. Stand by...</b></td></tr></table>';
		
		/* /chk */
	
		//newrow.innerHTML='<td style="background: '+bg+'; border: 1px solid black; border-top: 0px; padding: 15px" colspan="'+cs+'" id="'+name+"_expandedcontent_"+id+'" ><table cellspacing=0 cellpadding=0 border=0><tr><td valign=top><img src="'+am_loading+'"></td><td>&nbsp;</td><td class="smalltext" align=center id="autoexpander_'+id+'" valign=top><b>Loading. Stand by...</b></td></tr></table></td>';
		// http://dev.adevel.com/chk/fssub.html 
		// http://dev.adevel.com/chk/tmp/aaa&bbb=ccc
		
		aasn(name+"_expandedcontent_"+id, expander_url+id);
		
		//aasn(name+"_expandedcontent_"+id, 'http://php5.chk/freespech/admin/'+expander_url+id);
		expand('autoexpander_'+id,0);

		button_on(name+"_"+button+"_"+id);
	}else{
		/* other button is active. Close that one and open new one */
		expander_flip(name,id,expander_status,expander_url);
		expander_flip(name,id,button,expander_url);
	}
}
/******* InlineEdit functions ********/
function getInlineValue(inline_id){
	//var value=new String(document.getElementById(inline_id).innerHTML);
	/* stripping any tags from a value 
	initial string is: <font color="blue">Value</font>
	*/
	//v=value.split(">");
	//now we have v=array(0=>'<font color="blue"', 1=>'Value</font'
	//value=new String(v[1]).split("<");
	//value='edt';
	//return value[0];
	return document.getElementById(inline_id).title;
}
function isKeyPressed(e, kCode){
	var characterCode;

	if(e && e.which)characterCode = e.which;
	else characterCode=e.keyCode;

	return characterCode == kCode;
}
function denyEnter(e){
	return !isKeyPressed(e, kReturn);
}

function modifierPressed(e){
	var ctrlPressed=0;
	var altPressed=0;
	var shiftPressed=0;

	if (parseInt(navigator.appVersion)>3) {

	var evt = navigator.appName=="Netscape" ? e:event;

	if (navigator.appName=="Netscape" && parseInt(navigator.appVersion)==4) {
	// NETSCAPE 4 CODE
	var mString =(e.modifiers+32).toString(2).substring(3,6);
	shiftPressed=(mString.charAt(0)=="1");
	ctrlPressed =(mString.charAt(1)=="1");
	altPressed  =(mString.charAt(2)=="1");
	self.status="modifiers="+e.modifiers+" ("+mString+")"
	}
	else {
	// NEWER BROWSERS [CROSS-PLATFORM]
	shiftPressed=evt.shiftKey;
	altPressed  =evt.altKey;
	ctrlPressed =evt.ctrlKey;
	self.status=""
		+  "shiftKey="+shiftPressed 
		+", altKey="  +altPressed 
		+", ctrlKey=" +ctrlPressed 
	}
	}
	result=new Array(ctrlPressed,altPressed,shiftPressed);
	return result;
}


function detect_ie(){
	var agent=navigator.userAgent.toLowerCase();
	var i=agent.indexOf('msie');
	if (i!=-1) return parseFloat(agent.slice(i+5));
	else return false;
}


function detect_opera(){
	var agent=navigator.userAgent.toLowerCase();
	var i=agent.indexOf('opera');
	if (i!=-1) return parseFloat(agent.slice(i+6));
	else return false;
}


function inline_process_key(e, name, id, activate_next){
//      alert(e+" "+name+" "+id+" "+activate_next);

	if(isKeyPressed(e, kEsc)){
		//submitting and hiding current inline
		inline_hide(name, id, 'cancel');
		return false;
	}
	if(isKeyPressed(e, kReturn)){
		//submitting and hiding current inline
		inline_hide(name, id, 'update');
		return false;
	}

	if(activate_next&&isKeyPressed(e, kTab)){
		this_row_id=name+'_'+id;
		row=document.getElementById(this_row_id);
		if(e.shiftKey||e.modifiers==4){
			//shit is pressed, locating previous row
			while(row.previousSibling){
				row=row.previousSibling;
				if(row.id&&row.id!=this_row_id)break;
			}
		}else{
			//no shift, locating next row
			while(row.nextSibling){
				row=row.nextSibling;
				if(row.id)break;
			}
		}
		if(row.id){ 
			//we need to parse an ID from row.id
			row_id=new String(row.id);
			while(row_id.indexOf("_")!=-1)
					row_id=row_id.substring(row_id.indexOf('_')+1);
			//storing values cause they will be erased on hide
			active_field=inline_active[name][id]['active_field'];
			submit_url=inline_active[name][id]['submit_url'];
			//submitting and hiding current inline
			inline_hide(name, id, 'update');
			//activating next inline
			inline_show(name,active_field,row_id,submit_url,true,inline_active[name]['show_submit']);
			return false;
		}
	}
	return true;
}

function htmlspecialchars(string, quote_style) {
	
	string = string.toString();
	
	// Always encode
	string = string.replace('/&/g', '&amp;');
	string = string.replace('/</g', '&lt;');
	string = string.replace('/>/g', '&gt;');
	
	// Encode depending on quote_style
	if (quote_style == 'ENT_QUOTES') {
		string = string.replace('/"/g', '&quot;');
		string = string.replace('/\'/g', '&#039;');
	} else if (quote_style != 'ENT_NOQUOTES') {
		// All other cases (ENT_COMPAT, default, but not ENT_NOQUOTES)
		string = string.replace('/"/g', '&quot;');
	}
	
	return string;
}

function inline_show(name,active_field,row_id,submit_url,activate_next,show_submit,on_submit_fun,on_cancel_fun){
	// changes row content to a forms with input elements
	// submit_url is an URL that should store changes from inline to DB
	// name is a name of a grid
	// active_field - inline control that should be set active
	// row_id - guess
	// on_submit_fun callback function that executes after Ok button handler executed 
	// on_cancel_fun callback function that executes after Cancel button handler executed
	inline_id=active_field+"_"+row_id;
	//closing all open expanders
	id=name+"_"+row_id;
	if(expander_open[id]){
			expander_flip(name,row_id,expander_open[id]);
	}
	//closing all active inlines
	if(inline_active[name]){
			for(i=0;i<inline_active[name].length;i++){
					if(inline_active[name][i])
							inline_hide(name,i);
			}
	}
	row=document.getElementById(id);
	if(!row)alert("Row is empty: "+row+"\nID used is: "+id);
	//counting columns      

	tmp=document.getElementById(row.id);
	tmp=tmp.getElementsByTagName('TD');
	cs=0;
	while (tmp[cs] != null) cs++;
	
	//changing row contents to the forms. only for inlines...
	col=document.getElementById(inline_id);
	var inline_collection=new Array();
	var index=0;
	//MS IE js works different to Mozilla: nextSibling does needed action erlier
	//so for IE we should delay switching to next sibling
	goback=col.id!=undefined;
			
	id=new String(col.id);
	if(id.indexOf('_inlinex')!=-1) { // extended inline element - ajax content loading
			
		var extend_url=id;
		extend_url_arr = extend_url.split('_');
		extend_url ='';
		for(var i=1;i<extend_url_arr.length-1;i++) {
			extend_url += ((i==1)?'':'_')+extend_url_arr[i];	
		}
		
		extend_url += '&id='+extend_url_arr[extend_url_arr.length-1];

		var form_name='form_'+id;
		aasn(id,extend_url);
		inline_collection[index]=form_name;
		index++;
	} else  if(id.indexOf('_inline')!=-1){
		var form_name='form_'+id;
		
		// setting input size to length of the text in it or 40 max
		value=getInlineValue(id);
		size=value.length+5;
		if(size<6) size=6;
		if(size>40) size=40;
		
		var key;
		if (detect_ie() || detect_opera()){
			key='onKeyDown';
		}
		else{
			key='onKeyPress';
		}
		value=htmlspecialchars(value);
		col.innerHTML='<form id="'+form_name+'" name="'+form_name+'" method="POST" onsubmit="return false;">'+
				'<input id="'+form_name+'_edit" value="'+
				value+'" size="'+size+'" maxlength="255" type="text" '+key+'="'+
				'return inline_process_key(event,\''+name+'\','+row_id+','+activate_next+');"></form>';
		inline_collection[index]=form_name;
		index++;
	}
	if(show_submit){
		//expanding a row with submits
		newrow=document.createElement("tr");
		nextrow=row.nextSibling;
		if(!nextrow){
			row.parentNode.appendChild(newrow);
		}else{
			row.parentNode.insertBefore(newrow,nextrow);
		}
//              bg="#FFFFFF";  

		cll = newrow.insertCell(0);
				cll.align='right';
		cll.style.backgroundColor = "#FFFFFF";
		cll.style.borderWidth = '0 1px 1px 1px';
		cll.style.borderColor = '#000';
		cll.style.borderStyle = 'solid';
		cll.style.padding = '1px';
		cll.colSpan = cs; 
		
		if(typeof(on_submit_fun) == 'undefined') on_submit_fun = '';
		else on_submit_fun = ',\'' + on_submit_fun + '(\\\''+name+'\\\',\\\''+row_id+'\\\')\'';
		
		if(typeof(on_cancel_fun) == 'undefined') on_cancel_fun = '';
		else on_cancel_fun = ',\'' + on_cancel_fun + '(\\\''+name+'\\\',\\\''+row_id+'\\\')\'';
		
		event_handler="inline_hide('"+name+"',"+row_id+",'";
		cll.innerHTML='<form id="'+form_name+'" name="'+form_name+'" method="POST">'+
				'<input type="button" value="OK" onclick="'+event_handler+'update\''+on_submit_fun+');">'+
				'<input type="button" value="Cancel" onclick="'+event_handler+'cancel\''+on_cancel_fun+');">'+
				'</form>';
	}
	
//selecting an edit
	try{
		document.getElementById('form_'+inline_id+'_edit').focus();
		document.getElementById('form_'+inline_id+'_edit').select();
	}catch(e){}
	
	
	//setting an array value for further hiding
	if(!inline_active[name])inline_active[name]=new Array();
	inline_active[name][row_id]=new Array();
	inline_active[name][row_id]['submit_url']=submit_url;
	inline_active[name][row_id]['inline_collection']=inline_collection;
	inline_active[name][row_id]['active_field']=active_field;
	inline_active[name]['show_submit']=show_submit;
}



function inline_hide(name, row_id, action, callback){
	//name is a grid name, id is a row id
	//processing inline: submit or cancel
	//callback - callback function with params
	submit_url=inline_active[name][row_id]['submit_url']+'&row_id='+row_id;
	inline_collection=inline_active[name][row_id]['inline_collection'];
	if(action){
		url=submit_url+'&action='+action;
	}else{
		url=submit_url+'&action=update';
	}
	reload_row=false;
	if(inline_collection){
		url_params="";
		for(i=0;i<inline_collection.length;i++){
			field_name=new String(inline_collection[i]);
			field_name=field_name.substring(name.length+6, field_name.indexOf('_inline'));
			form=document.getElementById(inline_collection[i]);
			if(form){
				url_params+='&'+'field_'+field_name+'='+encodeURIComponent(form.elements[0].value);
				//if form was not found - probably we moved to another page by some ajax action
				//but, may be, it is a browser incompatibility...
				reload_row=true;
			}
		}
		url=url+url_params;
	}
	if(reload_row){
		reloadGridRow(url,name,row_id,callback, true, inline_active[name][row_id]['active_field'] + '_' + row_id);
		//aasn(name+'_'+row_id, url);
		if(inline_active[name]['show_submit']){
			//hiding buttons
			row=document.getElementById(name+'_'+row_id);
			nextrow=row.nextSibling;
			row.parentNode.removeChild(nextrow);
		}
	}
	inline_active[name][row_id]=false;
}




/******* TreeView functions *******/
function treenode_flip(expand,id,url){
	button=new String(document.getElementById('ec_'+id).innerHTML);
	cll=document.getElementById('p_'+id);
	if(expand==1)cll.innerHTML = '<table cellspacing=0 cellpadding=0 border=0><tr><td valign=top><img alt="" src="'+am_loading+'"></td><td>&nbsp;</td><td class="smalltext" align=center id="autoexpander_'+id+'" valign=top><b>Loading. Stand by...</b></td></tr></table>';

	aasn('p_'+id,url);
	
	if(expand==1){
		button=button.replace('plus.gif', 'minus.gif');
		button=button.replace('ec_action=expand', 'ec_action=collapse');
		button=button.replace('treenode_flip(1', 'treenode_flip(0');
	}else{
		button=button.replace('minus.gif', 'plus.gif');
		button=button.replace('ec_action=collapse', 'ec_action=expand');
		button=button.replace('treenode_flip(0', 'treenode_flip(1');
	}
	document.getElementById('ec_'+id).innerHTML=button;
}
// redraws a node specified and its branch
function treenode_refresh(id,url){
		aasn('p_'+id,url);
}

/******* MISC FUNCTIONS *******/
/**
* Reloads a row of a Grid
*/

function reloadGridRow(url,name,row_id,callback,settitle, reload_col){
	//row contents could not be replaced with aasn
	set_row_c = function(response_text, response_xml){
		//exploding string to an array of column values
		cols=response_text.split('<row_end>');
		id=name+'_'+row_id;
		row=document.getElementById(id);
		col=row.firstChild;
		i=0;
		while(col){
			if(col.innerHTML!=undefined){
				if ((reload_col == undefined) || (col.id == reload_col)){
					value=cols[i].split('<t>');
					col.innerHTML=value[0];
					if(settitle==true)col.title=value[1];
					// value[2] contains styles separated by <s>
					if(value[2]!=''){
						styles=value[2].split('<s>');
						for(j=0;j<styles.length;j++){
							// style cannot be assigned directly, 
							// so we analyze and set every property
							style=styles[j].split('::');
							switch(style[0]){
								case 'color':
									col.style.color=style[1];
									break;
								case 'cursor':
									col.style.cursor=style[1];
									break;
								case 'title':
									col.title=style[1];
									break;
							}
						}
					}
				}
				i++;
			}
			col=col.nextSibling;
		}
		try {
			if(typeof(callback) != 'undefined') eval(callback);
		} catch(e) {
				
		}
	}
	display_error = function(response_text,response_xml){
		alert(response_text);
	}
	aarq(url, set_row_c, display_error);
}
function w(url,width,height){
	window.open(url,'','width='+width+',height='+height+',scrollbars=yes,resizable=yes');
}

function ajax_done(){
	/* This function is called last from Ajax class. If this function is not called, then the whole output might contain
	* errors
	*/
}
function w(url,width,height){
	window.open(url,'','width='+width+',height='+height+',scrollbars=yes,resizable=yes');
}
/**
* Switches grouped field when given length is met
*/
function switchFieldOn(check_field_id, switchto_field_id, check_len){
	selected='';
	cf=document.getElementById(check_field_id);
	sf=document.getElementById(switchto_field_id);

	if (window.getSelection)   selected = cf.value.substring(cf.selectionStart, cf.selectionEnd);      
	else if (document.selection)   selected = document.selection.createRange().text;

	if (cf.value.length>=check_len && cf.value!=selected){
		sf.select();
		sf.focus();
		return false;
	}
}
/**
* Checks if session is expired and forces redirect to login if so
* Check is performed by a key string in the results of the aarq request to
* the specified URL
* In order for function not to find a key in self parameters, key is passed with
* spaces replaced by = (equals sign). Make sure your key has spaces :)
* ### Zak ### 
* Changed this to make ajax request to check sesson only if last check was done before mroe than 4 seconds,
* This way server load will be reduced significantly if a lot of JSes needs to be executed.
*/
var last_session_check = 0;

function checkSession(url,key){ 
        if(key==undefined)key='session is expired, relogin';
        // decoding encoded string
        else key=key.replace(/=/g,' ');
        
        var callback=function(response_text,response_xml){
                if(response_text.search(key)!=-1){
                        alert('Your session has expired. Please log in again.');
                        window.location='main.php';
                        return false;
                }
        }

        var curtime = new Date;
        if (last_session_check + 4000 < curtime.getTime()) {
        	last_session_check = curtime.getTime();
        	aarq(url, callback);	
        } else {
        	return true;
        }
}

// Refreshes available months and days for date selector <
function refreshDateSelector(name) {
	
	// Get day select  <
	var days_select = document.getElementById(name + '_day');
	
	// get month and year value <
	var month = document.getElementById(name + '_month').value;
	var year = document.getElementById(name + '_year').value;
	
	// calculate max depending on year and month <
	var max_day;
	switch (month) {
		case '1', '3', '5', '7', '8', '10', '12' : {max_day = 31; break;}
		case '4', '6', '9', '11' : {max_day = 30; break;}
		case '2' : {max_day = (year % 4 ? 28 : 29); break;}
	}

	// Get options <
	var options = days_select.getElementsByTagName('option');
	
	// display all options except the one with the value <
	for (var i = 0; i < options.length; i++) {
		if (options.item(i).value > max_day) {
			options.item(i).style.display = "none";
		} else {
			options.item(i).style.display = "";
		}
	}
	
	// Make new selection if the currently selected is the hidden <
	if (days_select.value > max_day) {
		days_select.value = max_day;
	}
}
// enables or disables DateSelector on checkbox click
function switchDateSelector(control,name){
	var d=document;
	var day=d.getElementById(name+'_day');
	var month=d.getElementById(name+'_month');
	var year=d.getElementById(name+'_year'); 
	
	if(!control.checked){
		if(day)day.disabled=true;
		if(month)month.disabled=true;
		if(year)year.disabled=true;
	}else{
		if(day)day.disabled=false;
		if(month)month.disabled=false;
		if(year)year.disabled=false;
	}
}
// checks the extension of the filename in the field specified
function checkExtension(form_id, field_id, ext){
	if(!ext)ext = new Array("jpg","jpeg","gif","bmp","png");
	filename=aagv(form_id, field_id);
	if(filename==''){
		// no check for empty values, check them by other function
		return true;
	}
	allowSubmit=false;
	while (filename.indexOf("\\") != -1)filename = filename.slice(filename.indexOf("\\") + 1);
	fileext = filename.split(".");
	for (var i = 0; i < ext.length; i++) {
		// file can have multiple extensions like file.jpg.html
		for(j=0;j<fileext.length;j++){
			extStr=fileext[j].toLowerCase();
			if (ext[i] == extStr) { allowSubmit = true; break; }
		}
	}
	if (!allowSubmit){
		alert("Please only upload files with extension "
			+ (ext.join(", ")) + "\nPlease select a new "
			+ "file to upload and submit again.");
		return false;
	}
	return true;
}

