var DELIMITER_COLS = "%`";
var DELIMITER_ROWS = "]|";
var filterCache = new Array();
var Conditions  = new Array(new Condition("=","1"),
							new Condition("<","2"),
							new Condition(">","4"),
							new Condition("Like","8"),
							new Condition("Not Like","72"),
							new Condition("<>","65"),
							new Condition(">=","5"),
							new Condition("<=","3"),
							new Condition("In","16"));

 function Field(name,code,conditions,renderMethod,getValueMethod,setValueMethod,defaultValue,parentField,callBackCall,dataProvider,setDataMethod)	{  
  this.name = name;
  this.code = code;
  this.renderMethod = renderMethod;
  this.getValueMethod = getValueMethod;
  this.setValueMethod = setValueMethod;
  this.conditions = conditions;
  this.defaultValue = defaultValue;
  this.parentField = parentField;
  this.callBackCall = callBackCall;
  this.dataProvider = dataProvider;
  this.setDataMethod = setDataMethod;
 }

function Condition(name,code){
	this.name = name;
	this.code = code;
}

 function AddField(filter,field,value,andOr) {
  filter[filter._cnt] = field;
  filter._cnt++;
  filter.cnt_real = 0;
  filter.isFirstTime = true; 
 }

 function AddRow(rows,code,condition,value,andOr)	{
	row =  new Object();
	row.code = code;
	row.condition = condition;
	row.andOr = andOr;
	row.value = value;
    rows[rows._cnt] = row;
	rows._cnt++;
	rows.cnt_real = 0;
	rows.isFirstTime = true; 
 }


function generateFilter(filter, rows) {
	if (documentAll(filter.name+"_buttons")==null || documentAll(filter.name+"_div")==null)
		return;

	var res;
	res = "";
	res += "<table align='right' border='0'>";
	if (filter.cnt_real == 0 && rows._cnt > 0) filter.cnt_real = rows._cnt;
	var j = 0;
	var c = filter.cnt_real;
	for (j=0;j< c + 1; j++ ) {
		res += "<tr>";
		res += "  <td class='andor'>" + generateAndOr(filter, rows, j) + "</td>";
		res += "  <td>" + generateFieldsSelect(filter, rows, j)+ "</td>";
		if (j<c)
		{
			res += "  <td>" + generateConditionsSelect(filter, rows, j)+ "</td>";
			res += "  <td>" + generateValues(filter, rows, j) + "</td>";
			res += "</tr>";
		}

	}
	if (c!=0) res +="<td colspan='2'>"+documentAll(filter.name+"_buttons").innerHTML+"</td>";
	res += "</table>";
	documentAll(filter.name+"_div").innerHTML = res;
	for (j=0;j< c + 1; j++) 
			setValues(filter,rows,j);	
	for (j=0;j< c + 1; j++) {						
		if (rows[j]!=null)
		{			
			idx = findInDB(filter, rows[j].code);
			if (filter[idx].parentField != '') {						
				var parentNum;
				for (k=0;k< c; k++) 
					if (rows[k].code == filter[idx].parentField) {						
						CallBack(filter,rows,filter.name+"_fltr_val_"+k,filter[idx].parentField);
					}
			}
		}			
	}	
	for (j=0;j< c + 1; j++) 
			setValues(filter,rows,j);
	if(c>0){
		OpenFilterTab();
	}
	
}

function generateAndOr(filter, rows, n) {
	var res = ""; 
	if (n == 0) {return "&nbsp;";}
	res += "<select name='"+filter.name+"_fltr_andor_"+n+"'>";
	var selected = "OR";
	res += "<option value='0'>OR</option>";
	if (rows[n] && (rows[n].andOr == "1" || rows[n].andOr.toLowerCase() == 'and') ) {
		res += "<option value='1' selected>AND</option>";
	} else {
		res += "<option value='1'>AND</option>";
	}
	res += "</select>"
	return res;
}

function generateFieldsSelect(filter, rows, n){
	var res;
	res = "<select name='"+filter.name+"_fltr_fld_"+n+"' onChange='saveCurrentState("+filter.name+","+rows.name+","+n+");'>";
	res +="<option value=''></option>";
	var selected;
	for (var i=0;i<filter._cnt;i++) {

		if (filter[i].parentField != '' && parentAlreadyShownID(rows, filter[i].parentField) == -1) continue;
		if (rows[n]) {
			selected = (filter[i].code == rows[n].code)?" selected" : "";
		}else {
			selected = "";
		}
		res += "<option value='"+filter[i].code+"'"+selected+">"+filter[i].name+"</option>";
	}
	res +="</select>";
	return res;
}

function generateConditionsSelect(filter, rows, n){
	var res = "";
	var selected;
	if (rows[n]) {
		res = "<select class='condition' name='"+filter.name+"_fltr_cond_"+n+"'>"; 
		field = FieldByCode(filter, rows[n].code);
		for (var cond in field.conditions) {
			for (var i=0; i<Conditions.length; i++)
			{
				if (Conditions[i].code == field.conditions[cond])
				{
					selected = (rows[n].condition == field.conditions[cond])?" selected" : "";
					res += "<option value='"+Conditions[i].code+"'"+selected+">"+Conditions[i].name+"</option>";
				}
			}			
		}
		res +="</select>";
	}
	return res;
}

function FieldByCode(filter,code) {
	for (i=0; i<filter._cnt; i++)
		if (filter[i].code == code)
			return filter[i];
	return null;
}
function generateValues(filter, rows, n){ 
	if (rows[n] != null)
	{
	  field = FieldByCode(filter,rows[n].code);
	  return eval("str = "+ field.renderMethod+"(field,rows[n],n);");
	} else	{
		return "";
	}
}

function setValues(filter,rows,n)	{
	if (rows[n] != null)
	{
		var d = document.forms[0];
		var c = d[filter.name+"_fltr_val_"+n];
		var field = FieldByCode(filter,rows[n].code);	
		eval(field.setValueMethod+"(rows[n],c)");
	}
}

function saveCurrentState(filter, rows, sender){
	var newRows = new Object();
	newRows._cnt = 0;
	newRows.name = rows.name;
	var d = document.forms[0];
	var field; 
	var cond;
	var cnt = 0;
	var parentName, values, value;
	for (var i=0;i < filter.cnt_real + 1 ;i++ ){
		field = findInDB(filter, d.elements[filter.name+"_fltr_fld_"+i].value);		
		if ( field >= 0 ) {			
		
			cnt ++;
			cond_element = d.elements[filter.name+"_fltr_cond_"+i];
			cond = (cond_element)? cond_element.options[cond_element.selectedIndex].value:"";
			andor_element =  d.elements[filter.name+"_fltr_andor_"+i];
			var andor = (!andor_element)?"AND":andor_element.options[andor_element.selectedIndex].value;
			var val ="";
			if ( i != filter.cnt_real)
			{
				if (sender != i)
					val = getCurrentValue(filter,filter[field],i);
			} else {
					val = filter[field].defaultValue;
			}
			AddRow(newRows,filter[field].code,cond,val,andor);			
		} 
	}
	filter.cnt_real = cnt;
	rows = newRows;
	eval(rows.name+' = newRows;');
	
	generateFilter (filter, rows);
	filter.isFirstTime = false; 
	if (window.parent)
		window.parent.resizeCaller();
	return rows;
}

function findInDB(db, code) {
	for (var i=0;i<db._cnt;i++) {
		if (code == db[i].code) return i;
	}
	return -1;
}

function getCurrentValue(filter, field,n) {
	frm = document.forms[0];
	var el = frm.elements[filter.name+"_fltr_val_"+n];		
	if (!el) return '';
	if (field!= null)
	{
		val = eval(field.getValueMethod+"(el);");
		return val;
	} else {
		return '';
	}
}

function refilter(filtername, rowsname){
filter = eval(filtername);
rows = eval(rowsname);
rows = saveCurrentState(filter, rows, true);
switchTab('filter');
}

function parentAlreadyShownID(rows, parentName) {
	for(var i=0;i<rows._cnt;i++) {
		tmp = rows[i];
		if (tmp.code == parentName) return tmp.values;
	}
	return -1;
}

function CallBack(filter,rows,parentInput,parentName,reInit) {

  if (parentName != '') 	{
	var d = document.forms[0];
	var childRowIndexes = new Array();
	parentNum  = parentInput.substr(parentInput.lastIndexOf("_")+1,parentInput.length);	
	parentField = findInDB(filter,parentName);		
	parentValue = getCurrentValue(filter,filter[parentField],parentNum);	
	for (var i=0;i < filter.cnt_real + 1 ;i++ ){
		field = findInDB(filter, d.elements[filter.name+"_fltr_fld_"+i].value);			
		if (field != -1) 
			if (filter[field].parentField == parentName) {
				var childField = filter[field];
				childRowIndexes[childRowIndexes.length] = i;				
			}
	}	;
	if (childField != null && parentValue.length != 0 )
	{
	
		var evalStr = childField.callBackCall+ "('" +childField.dataProvider + "','"+ parentValue+"');";
		var newVal = eval(evalStr);			
		for (var i=0;i < childRowIndexes.length ;i++ ){
			if (parentNum < childRowIndexes[i])
			{
				var elem =  d.elements[filter.name+"_fltr_val_"+childRowIndexes[i]];
				elem.options.length = 0;			
				eval(childField.setDataMethod+"(elem,newVal.value)");
			}	
		}
	}
  }
}

function OpenFilterTab(){
	var FilterArea = getElement("tab_filter");
	if(FilterArea) {
		FilterArea.style.display = "block";
	}
}

//getting element
function documentAll(name) {
	var DOM = document.getElementById ? true : false;
	var ie = document.all ? true : false;
	var nn4 = document.layers ? true : false;

	if (ie) { return document.all[name]; }
	 else if(DOM){ return document.getElementById(name); }
		  else { return document.name; }
}