// filter word treba dodelat. Filtruje slova, ale zatim se to neprojevuje na tabulce


function classAppEdit(opt)
{
var root = this;
this.name = 'classApp';

this.tbl = {};		// start: 0, end: 1
this.filter_rows = {};	// start: 0, end: 1
this.table = {};	// table options
this.table.structure = {};
this.table.key_all = {};
this.table.filter_all = {};
this.table.data = [];
this.filex = {};


this.event = {};
this.event.func = {};

this.event.func.read = function (event)
	{
	SCREEN.func.log('---event---');
	return {
		'event' : event || window.event,
		'target': event.target || event.srcElement
		};
	}

this.func = {};

this.func.log = null;


this.func.tableReadKeys = function(row)
	{
	root.func.log(root.name + '.func.tableReadKeys');
	var i, i_end, val, key_all;
	key_all = {};
	key_all.by_id   = [];
	key_all.by_name = {};
	i_end = row.length;
	for (i=0;i<i_end;i++)
		{
		val = row[i];
		key_all.by_id[i]     = val;
		key_all.by_name[val] = i;
		}
	return key_all;
	}






this.func.htmlCreateHead = function(key_by_id)
	{
	root.func.log(root.name + '.func.htmlCreateHead');
	var tpl, arr, i, j, i_end, str, word;
	tpl = {};
	tpl.th = '{text}';
	// --- table head ---
	j      = 0;
	arr    = [];
	arr[j] = [];
	i_end  = key_by_id.length;
/*
	for (i=0;i<i_end;i++)
		{
		arr[j][i] = '';
		}
	j++;
	arr[j] = [];
*/
	for (i=0;i<i_end;i++)
		{
		name = key_by_id[i];
		arr[j][i] = render(tpl.th,{
//			'text': escapeHtml(name)
			'text': '<span title="'+escapeHtml(name)+'">'+escapeHtml(name)+'</span>'
			});
		}
//	j++;
//alert(arr);
	return arr;
	}

/*
this.func.tableApplyFilters = function(arr)
	{
	var key_by_id;
	key_by_id = root.table.key_all.by_id;
	arr = arrayClone2(arr);
	root.func.log('classArrayFilters.func.where (' + arr.length + ', start='+root.tbl.start+')');
	arr = FILTER.func.where(arr, key_by_id, root.table.filter_all, root.fw.checked, root.tbl.start);
	arr = root.func.tableOrderBy(arr, key_by_id, root.fms.order_by_all);
	return arr;
	}
*/

function cloneWidth(div0,div1)
	{
	var i, i_end, div0_tbl, div1_tbl, div0_tr, div0_th, div1_tr, div1_th;
//alert(div0.getElementsByTagName('TABLE')[0].offsetWidth)
//alert(div1.getElementsByTagName('TABLE')[0].offsetWidth)

div0_tbl = div0.getElementsByTagName('TABLE')[0];
div1_tbl = div1.getElementsByTagName('TABLE')[0];
div1_tbl.style.width = div0_tbl.offsetWidth + 'px';
//div1_tbl.style.tableLayout = 'fixed';

	div0_tr = div0.getElementsByTagName('TR')[0]
	div0_th = div0_tr.getElementsByTagName('TH');
	div1_tr = div1.getElementsByTagName('TR')[0]
	div1_th = div1_tr.getElementsByTagName('TH');
	i_end = div0_th.length;
	for (i=0;i<i_end;i++)
		{
		div1_th[i].style.width = (div0_th[i].offsetWidth - 14 - 1) + 'px';	// -padding, border
//		div1_th[i].innerHTML = div0_th[i].offsetWidth+'<br>'+(div1_th[i].offsetWidth);
//		div1_th[i].innerHTML = div1_th[i].offsetWidth;
		}
//div1.getElementsByTagName('TABLE')[0].style.width = div0.getElementsByTagName('TABLE')[0].offsetWidth + 'px';
//	obj1.style.width = obj0.offsetWidth + 'px';
	}

function clone2(div0,div1)
	{
	var i, i_end, div0_tr, div0_th, div1_tr, div1_th;
t0 = div0.getElementsByTagName('TABLE')[0]
t1 = div1.getElementsByTagName('TABLE')[0]
	div0_tr = div0.getElementsByTagName('TR')[0]
	var clone = div0_tr.cloneNode(true);
	t1.getElementsByTagName('THEAD')[0].appendChild(clone); 
	}

this.func.tableClick = function(event)
	{
	var ev_data, el, pos;
	ev_data = root.event.func.read(event);
	el      = ev_data.target;
	if (el.nodeName=='TD')
		{
//		pos_tbl = getPos($('table'), false, false);
//		pos = getPos(el, true, true)
//		$('cur').style.left = pos.x + pos_tbl.x + 'px';
//		$('cur').style.top  = pos.y + pos_tbl.y + 'px';
//		$('cur').getElementsByTagName('INPUT')[0].focus();
		}
	
	}

this.func.tableApplyChanges = function()
	{
	PERF.getTime();
	root.func.log(root.name + '.func.tableApplyChanges');
	var head, str, arr, key_by_id, el;
	key_by_id = root.table.key_all.by_id;
	arr = root.table.data;
//	arr = root.func.tableApplyFiltersXX(arr);
	// show stat
	root.stat.rows   = {};
	root.stat.rows.a = arr.length;
	root.stat.rows.b = root.tbl.end - root.tbl.start;
//	root.func.log(Math.floor(PERF.getTime()));
//	root.fms.func.tableReadFMS();
	head = root.func.htmlCreateHead(key_by_id);
//	root.func.log('time '+Math.floor(PERF.getTime()));
	str  = HTML.func.createTable(2, arr, head, [], root.tbl.start, root.tbl.end, root.tbl.row_id, []);
	SCREEN.func.table(str);

//	$('table').onclick = root.func.tableClick;
	$('table').onclick = root.edit.func.inputOpen;

/*
fixed zahlavi
	str  = HTML.func.createTable(2, [], head, [], root.tbl.start, root.tbl.end, root.tbl.row_id, []);
	SCREEN.func.fixed1(str);
	cloneWidth($('table'),$('fixed1'));
	scrollFixed();
*/
//	SCREEN.func.fixed1('<table class="tbl"><thead></thead></table>');
//	clone2($('table'),$('fixed1'));
	
//	root.fw.func.containerCloseAll();
//	root.fw.func.focus();
	root.func.log('time '+ Math.floor(PERF.getTime()));
	}

this.func.tableRender = function()
	{
	root.func.log(root.name + '.func.tableRender');
	arr = arrayClone2(root.table.data);
//alert(['tableRender\n',arr.join('\n')])
	arr = root.func.tableApplyFiltersXX(arr);
//alert(['tableRender\n',arr.join('\n')])
//	root.func.log(root.name + '.func.tableApplyFiltersXX END');
	// show stat
	root.stat.rows   = {};
	root.stat.rows.a = arr.length;
	root.stat.rows.b = root.tbl.end - root.tbl.start;
	head = root.func.htmlCreateHead(key_by_id);
	str  = HTML.func.createTable(2, arr, head, [], root.tbl.start, arr.length, root.tbl.row_id, []);
	SCREEN.func.table(str);
	root.edit.func.colorizeTable();
	$('table').onclick = root.edit.func.inputOpen;
/* fixed zahlavi
	str  = HTML.func.createTable(2, [], head, [], root.tbl.start, root.tbl.end, root.tbl.row_id, []);
	SCREEN.func.fixed1(str);
	cloneWidth($('table'),$('fixed1'));
	scrollFixed();
*/




	root.func.log('time '+Math.floor(PERF.getTime()));
	}

/*
this.func.tableApplyFiltersXX = function(arr)
	{
	root.func.log(root.name + '.func.tableApplyFiltersXX');
	var i, j, k, l, m, i_end, j_end, k_end, l_end, out, q_insert, q_update, q_delete, clear, row;
//	arr = arrayClone2(arr);
	// create clear array
	clear = [];
	i_end = arr[0].length;
	for(i=0;i<i_end;i++)
		{
		clear[i] = '';
		}
	q_insert = root.edit.data.q_insert;
	q_update = root.edit.data.q_update;
	q_delete = root.edit.data.q_delete;
	i_end = arr.length;
	j_end = q_insert.length;
	k_end = q_update.length;
	l_end = q_delete.length;
	i = 0;
	j = 0;
	k = 0;
	l = 0;
	m = 0;
	out = [];
//alert(arr)
mm = Math.max(i_end,j_end)
	while (i<i_end || j<j_end || k<k_end || l<l_end)
		{
		row = null;
		if (isArray(q_insert[j]))
			{
//alert('insert');
			row = arrayClone1(clear);
			}
		else	{
//alert('row');
			if (isArray(arr[i]))
				{
				row = arrayClone1(arr[i]);
				}
			i++;
			}
		j++;
		if (isArray(q_update[k]))
			{
//alert('update');
			row = arrayClone1(q_update[k]);
			}
		k++;
		if (isArray(q_delete[l]))
			{
//alert('delete');
			l++;
			continue;
			}
		l++;
		out[m] = row;
		m++;
*/
/*
if (m>mm)
	{
	alert ([
		i<i_end || j<j_end || k<k_end || l<l_end,
		i<i_end, j<j_end, k<k_end, l<l_end,
		i,i_end, j,j_end, k,k_end, l,l_end
		]);
	alert ('max m');
	break;
	}
*/
//		}
/*
	while (i<i_end && j<j_end && k<k_end && l<l_end)
		{
		if (isExist(q_insert[j]))
			{
alert('insert');
			row = arrayClone(clear);
			}
		else	{
alert('row');
			row = arrayClone(arr[i]);
			i++;
			}
		j++;
		if (isExist(q_update[k]))
			{
alert('update');
			row = arrayClone(q_update[k]);
			}
		k++;
		if (isExist(q_delete[l]))
			{
alert('delete');
			l++;
			continue;
			}
		out[m] = row;
		m++;
		}
*/
//alert(out)
/*
	root.func.log(root.name + '.func.tableApplyFiltersXX END');
	return out;
	}
*/

this.file = {};
this.file.func = {};

this.file.func.exportAll = function()
	{
	READER.func.saveTextAsFile(root.filex.export_name_all, CSV.export(root.table.data));
	}


this.file.func.importCB1 = function(str)
	{
	var arr, str, head,skip;
	root.func.log(root.name + '.func.fileImportCB1');
	arr = CSV.import(str);
	root.tbl.start  = 1;
	root.tbl.end    = arr.length;
	root.func.log('time '+Math.floor(PERF.getTime()));
//	root.tbl.row_id = arr[0].length;	// position row_id at end
//	str  = '';
//	col_skip   = [root.tbl.row_id];
	root.table = {};
	root.table.data       = arr;
	root.table.key_all    = root.func.tableReadKeys(arr[0], []);	// vynech posledni sloupec (id radku)
	key_by_id = root.table.key_all.by_id;
	root.func.log('time '+Math.floor(PERF.getTime()));
	root.func.tableApplyChanges();
	}

this.file.func.import = function()
	{
	root.func.log(root.name + '.func.fileImport');
//	path = 'actual/zas.csv';	// disk
//	path = '../actual/zas.csv';	// aura
//	url = path;
	READER.func.init({log:SCREEN.log, cbEnd:root.file.func.importCB1});
	READER.func.fileFromUrl(root.filex.import_root + root.filex.import_path);
	}

this.stat = {};
this.stat.rows = {};
this.stat.func = {};



this.open = {}
this.open.files = [];
this.open.func = {};

this.open.func.readUrlParams = function(url)
	{
	var dict, str;
	dict = {};
	str = url.replace(/^.*?\?|\#.*$/g,'');	// remove XXX?...#XXX
	str.split("&").forEach(
		function(item)
			{
			arr = item.split("=");
			dict[unEscapeUrl(arr[0])] = unEscapeUrl(arr[1]);
			}
		);
	return dict;
	//alert(dict.toSource());
	}

this.open.func.readUrlServer = function(url)
	{
	return url.replace(/^.*?\/+(.*?)\/+.*$/g,'$1');	// remove XXX//.../XXX
//	 file:///C: | // http://localhost | // http://webapp
	}

this.open.func.openFromUrl = function(url,def)
	{
//alert(url);
	var dict, server, opt;
	dict   = root.open.func.readUrlParams(url);
	server = root.open.func.readUrlServer(url);
//alert(server)
//alert(dict.toSource())
	if (!isExist(dict['file']) && isExist(def))
		{
		dict['file'] = def;
		}
	if (!isExist(dict['file']))
		{
		SCREEN.func.message('openFromUrl: Neplatny nazev souboru v url.','error');
		return;
		}
	path = (server=='webapp.fpf.slu.cz' || server=='localhost' ? 'zas3-view.php?file=' : 'actual/') + dict['file'];
	opt = {
		data: {
			filex: {
				import_root: '',
				import_path: path,
				export_name_all     : dict['file'],
				export_name_filtered: dict['file']
				}
			}
		};
	//alert(opt.toSource())
	root.func.init(opt);
	root.file.func.import();
	root.open.func.htmlNavCreate([dict['file']]);
	}

this.open.func.htmlNavCreate = function(selected)
	{
	var selected = isArray(selected) ? selected : [];
	var tpl, str, i, i_end, item_,url;
	root.open.files = [
		{file:'zas_bn13.csv'},
		{file:'zas_bn14.csv'},
		{file:'zas_h17.csv'},
		{file:'zas_h10.csv'}
		];
	tpl   = {};
	tpl.a = '<span class="butt {class}"><a href="{url}" title="{title}">{name}</a></span>';
	url   = '?file=';
	path  = ''
	str   = '';
	item_all = root.open.files;
	i_end = item_all.length;
	for (i=0;i<i_end;i++)
		{
		item_ = item_all[i];
		item_.name  = escapeHtml(item_.file.replace(/.*?\_([a-z0-9]+)\..*/g,'$1'));	// odstran vse pred '_' a vse za '.'
		item_.title = item_.name;
		item_.class = arrayFindIndex(selected,item_.file)!==false ? 'sel' : '';
		item_.url   = escapeHtml(url + escapeUrl(path + item_.file));
		str  += (str.length>0 ? ' ': '') + render(tpl.a,item_);
		}
	$('nav').innerHTML = str;
	}


this.func.init = function(opt)
	{
	var bool, i, j;
	if (root.func.log)
		{
		root.func.log(root.name + '.func.init');
		}
	if (!isObject(opt))
		{
		return;
		}
	if (isObject(opt.func))
		{
		for (i in opt.func)
			{
			if (isFunction(opt.func[i]))
				{
				root.func[i] = opt.func[i];
				}
			}
		}
	if (isObject(opt.data))
		{
		for (i in opt.data)
			{
			if (isObject(opt.data[i]))
				{
//				if (i=='fmsx' || i=='fwx')
//					{continue;}
				if (!isObject(root[i]))
					{
					root[i] = {};
					}
				for (j in opt.data[i])
					{
					root[i][j] = opt.data[i][j];
					}
				}
			}
//		if (isArray(opt.data['fmsx']))
//			{
//			root.fms['fmsx'] = opt.data['fmsx'];
//			}
//		if (isArray(opt.data['fwx']))
//			{
//			root.fms['fwx'] = opt.data['fwx'];
//			}
		}
	}

this.edit = {};
this.edit.input = null;
this.edit.input_id = null;
//this.edit.history = [];
//this.edit.changes = [];	// changed rows

this.edit.data = {};
this.edit.data.q_insert = [];
this.edit.data.q_update = [];
this.edit.data.q_delete = [];

this.edit.func = {};

this.edit.func.log = function (str)
	{
	root.func.log(root.name + ".edit.func." + str);
	}

this.edit.func.dataSelect = function(row_id,col_id)	//y, x
	{
//	return root.table.data[row_id][col_id];
	var row;
	if (isArray(root.table.data[row_id]))
		{
		row = arrayClone1(root.table.data[row_id]);
		if (isExist(col_id))
			{
			if (isExist(row[col_id]))
				{
				return row[col_id];	// row[x]
				}
			return false;
			}
		return row;	// row
		}
	return false;
	}

/*
this.edit.func.dataInsertMiddleEmpty = function(row_id,pos)
	{
	var row, i, i_start, i_end;
	var pos = isExist(pos) && pos!=0 ? 1 : 0;	// je mozne pridat jen pod a na stejny radek
	if (isArray(root.table.data[row_id]))
		{
		// vytvor prazdny
		row = [];
		i = 0;
		i_end = root.table.data[row_id].length;
		while (i<i_end)
			{
			row[i] = '';
			i++;
			}
		// posun tabulku o +1 radek dolu	// above=false
//alert([i,i_end,row])
//above = !above;
		i_start = pos==0 ? row_id : row_id+pos;
//alert([i_start,row_id])
		i = root.table.data.length;
		while (i>i_start)
			{
			root.table.data[i] = root.table.data[i-1];
			i--;
			}
		root.table.data[i_start+1] = row;
//		row = arrayClone1(row);
//		return row;	// row
		}
	return false;
	}
*/


/*
this.edit.func.dataUpdate = function(row_id,col_id,str)
	{
	root.table.data[row_id][col_id] = str;
	}
*/
/*
this.edit.func.historyInsert = function(row_id)
	{
	if (!isArray(root.edit.history[row_id]))
		{
		root.edit.history[row_id] = root.edit.func.dataSelect(row_id);
//arrayClone1(root.table.data[row_id]);
		return root.edit.history[row_id];
		}
	return false;
	}

this.edit.func.historySelect = function(row_id,col_id)
	{
	var row;
//alert(1)
	if (isArray(root.edit.history[row_id]))
		{
//alert(2)
		row = root.edit.history[row_id];
		if (isExist(col_id))
			{
//alert(3)
			if (isExist(row[col_id]))
				{
//alert(4)
				return row[col_id];
				}
			return false;
			}
		return row;
		}
	return false;
	}
*/

this.edit.func.q_updateUpdate = function(row_id, col_id, str)	// y, x, str
	{
	root.edit.func.log('q_updateUpdate');
	root.edit.data.q_update[row_id][col_id] = str;
	return root.edit.data.q_update[row_id];
	}

this.edit.func.q_updateInsert = function(row_id, row_orig)
	{
	root.edit.func.log('q_updateInsert');
	if (!isArray(root.edit.data.q_update[row_id]))
		{
//		root.edit.data.q_update[row_id] = arrayClone1(root.table.data[row_id]);
		root.edit.data.q_update[row_id] = arrayClone1(row_orig);
		return root.edit.data.q_update[row_id];
		}
	return false;
	}

this.edit.func.q_updateSelect = function(row_id,col_id)
	{
	root.edit.func.log('q_updateSelect');
	var row;
	if (isArray(root.edit.data.q_update[row_id]))
		{
		row = root.edit.data.q_update[row_id];
		if (isExist(col_id))
			{
			if (isExist(row[col_id]))
				{
				return row[col_id];
				}
			return false;
			}
		return row;
		}
	return false;
	}

this.edit.func.q_fnInsertMiddle = function(arr, row_id, row, pos)
	{
	var row, i, i_start, i_end;
	var above = isExist(above) && above==true ? true : false;
	var pos   = isExist(pos) && pos!=0 ? 1 : 0;	// je mozne pridat jen pod a na stejny radek
		// posun tabulku o +1 radek dolu	// above=false
		i_start = pos==0 ? row_id : row_id+pos;
		i = arr.length;
		while (i>i_start)
			{
			if (isArray(arr[i-1]))
				{
				arr[i]   = arr[i-1];
//alert(i)
//				arr[i-1] = null;
				}
			i--;
			}
//alert(row)
		arr[i_start+1] = row;
	return arr;
	}

this.edit.func.dataInsertMiddle = function(row_id, row, pos)
	{
//alert(root.table.data[0]);
	root.table.data = root.edit.func.q_fnInsertMiddle(root.table.data, row_id, row, pos);
//	root.tbl.start = root.tbl.start;
	root.tbl.end   = root.table.data.length;	//root.tbl.end + 1;
//alert(	root.table.data.join('\n'))
	return false;
	}

this.edit.func.q_updateInsertMiddle = function(row_id, row, pos)
	{
	root.edit.data.q_update = root.edit.func.q_fnInsertMiddle(root.edit.data.q_update, row_id, row, pos);
	return false;
	}


this.edit.func.q_deleteInsertMiddle = function(row_id, row, pos)
	{
	root.edit.data.q_delete = root.edit.func.q_fnInsertMiddle(root.edit.data.q_delete, row_id, row, pos);
	return false;
	}

//root.edit.func.data.qApplyOnTable = function()
//	{
/*
		i_start = pos==0 ? row_id : row_id+pos;
		i = arr.length;
		while (i>i_start)
			{
			if (isArray(arr[i-1]))
				{
				arr[i]   = arr[i-1];
				arr[i-1] = null;
				}
			i--;
			}
		arr[i_start+1] = row;
*/
//	}

this.edit.func.getXY = function(el,bool_split)
	{
	root.edit.func.log('getXY');
	var str, arr;
	str = el.className;
//alert('getXY: '+str)
	str = str.replace(/^.*?p(\d+\_\d+)\D*.*$|.*()/g,'$1');	// vyber pCislo_Cislo nebo uplne smaz
//	str = str.replace(/^p(\d+\_\d+).*$/g,'$1');
//alert('getXY: '+str)
	if (bool_split==false)
		{return str;}
//alert(str)
	arr = str.split('_');
//alert(arr)
	arr[0] = arr[0]*1;
	arr[1] = arr[1]*1;
	return arr;
	}

this.edit.func.getTdByXY = function(html_td,x,y)
	{
	root.edit.func.log('getTdByXY');
//	root.func.log(html_td.nodeName);
	var e, c;
	e = html_td;	// TD
	e = e && e.parentNode ? e.parentNode : null;	// TR
	e = e && e.parentNode ? e.parentNode : null;	// TBODY
//root.func.log([x,y].join(', '))
	if (!e)
		{
root.func.log('Error 0: TBODY not exist. (table, thead, tfoot)')
return null;}
	c = e.getElementsByTagName('TR');
	if (!isExist(c[y]))
		{
root.func.log('Error 1: TR['+y+'] not exist in ' + e.nodeName);
return null;}
//root.func.log(e[y].nodeName)
	c = c[y].getElementsByTagName('TD');
	if (!isExist(c[x]))
		{
root.func.log('Error 2: TD['+x+'] not exist in ' + c[y].nodeName);
return null;}
	return c[x];
	}


this.edit.func.getTrByY = function(y)
	{
	root.edit.func.log('getTrByXY');
	var e;
	e = $('table');	// div table
	e = e ? e.getElementsByTagName('TABLE') : null;	// TBODY
	if (!e || !isExist(e[0]))
		{
		root.func.log('Error 0: TABLE[0] not exist in ' +  (e ? e.nodeName : null));
		return null;
		}
	e = e[0];
	e = e ? e.getElementsByTagName('TBODY') : null;	// TBODY
	if (!e || !isExist(e[0]))
		{
		root.func.log('Error 0: TBODY[0] not exist in ' +  (e ? e.nodeName : null));
		return null;
		}
	e = e[0];
	e = e.getElementsByTagName('TR');	// TR
	if (!isExist(e[y]))
		{
		root.func.log('Error 0: TR['+y+'] not exist in ' + e.nodeName);
		return null;
		}
	return e[y];
	}
/*
this.edit.func.classRemove = function(str, name)
	{
	var patt, reg;
	patt = '^'+name+'$' +'|'+'^'+name+' ' +'|'+' '+name+'$' +'|'+' '+name+' ';
	reg =  new RegExp(patt, 'g');
	return str.replace(reg,'');
	}

this.edit.func.classAdd = function(str, name)
	{
	return str += ' '+name;
	}
*/

this.edit.func.trColorize = function(html_tr, q_update_row, data_row)
	{
	root.edit.func.log('rowColorize');
	var bool, bool_td, i, i_end, j, j_end, html_td_all, html_td;
	// colorize row
	bool  = true;
	i_end = data_row.length;
	html_td_all = html_tr.getElementsByTagName('TD');
	j_end = html_td_all.length;
	for(i=0;i<i_end;i++)
		{
		if (!isExist(q_update_row))
			{
			continue;	// pri insert row posouvas pole, muze tam byt null
			}
		if (!isExist(q_update_row[i]) || !isExist(data_row[i]))
			{
			alert('Error 0: Not exist q_update_row[i] or data_row[i].');
			}
//		bool &= td_all[i].innerHTML==data_row[i];
		bool_td = q_update_row[i]==data_row[i];
		bool &= bool_td;
		if (bool_td==false)
			{
			// colorize col
//			for(j=1;j<j_end;j++)	// skip first col, head
//				{
				html_td = html_td_all[i];
				HTML.func.classRemove(html_td, 'm');
				HTML.func.classAdd(html_td, 'm');
//				}
			//break;
			}
		}
//	bool = !bool;
//alert([4,html_tr.nodeName,html_tr.className])
	HTML.func.classRemove(html_tr, 'm');	// colorize row
	if (bool==false)
		{
//alert([5,html_tr.nodeName,html_tr.className])
		HTML.func.classAdd(html_tr, 'm');
//		cl += ' m';
		}
//	html_tr.className = cl;
	}

this.edit.func.tdUpdate = function(html_td, val)
	{
	var fn = root.edit.func;
	fn.log('tdUpdate');
	var html_tr, xy, i, i_end, rows;
	rows = {};
	if (!isExist(html_td))
		{
		return rows;
		}
	html_tr = html_td.parentNode;	// html tr
	xy      = fn.getXY(html_td, true);
	rows.data     = fn.dataSelect(xy[0]);
	rows.q_update = fn.q_updateSelect(xy[0]);
	if (rows.q_update==false)
		{
		rows.q_update = fn.q_updateInsert(xy[0], rows.data);
		}
	if (rows.q_update==false)
		{
		alert('Error 0: Not exist rows.q_update.');
		}
	fn.q_updateUpdate(xy[0], xy[1], val);
	return rows;
//	fn.inputRemove(html_td, val);	//, data_row[xy[1]]==val
//	fn.trColorize(html_tr, q_update_row, data_row);
	}

this.edit.func.inputClose = function()
	{
	var fn = root.edit.func;
	fn.log('inputClose');
	var html_input, html_td, html_tr, val, xy, i, i_end, data_row, q_update_row, rows;	//hist_row, 
	if (root.edit.input!=null)
		{
		html_input = root.edit.input;		// html input
		html_td    = html_input.parentNode;	// html td
		html_tr    = html_td.parentNode;	// html tr
		val = html_input.value;
//		xy  = fn.getXY(html_td, true);
/*
//		// uloz do history original a prepis data
		data_row    = fn.dataSelect(xy[0]);
		q_update_row = fn.q_updateSelect(xy[0]);
		if (q_update_row==false)
			{
			q_update_row = fn.q_updateInsert(xy[0],data_row);
			}
		if (q_update_row==false)
			{
			alert('Error 0: Not exist q_update_row.');
			}
		fn.q_updateUpdate(xy[0], xy[1], val);
*/
		rows = fn.tdUpdate(html_td, val);
		fn.inputRemove(html_td, val);
//		fn.tdTrColorize(html_td,val, data_row[xy[1]]==val);
		fn.trColorize(html_tr, rows.q_update, rows.data);
		}
	root.edit.input    = null;
	root.edit.input_id = null;
//	root.edit.func.log('close END');
	}
/*
		hist_row = root.edit.func.historySelect(xy[0]);
//alert(hist_row)
		if (hist_row==false)
			{
			hist_row = root.edit.func.historyInsert(xy[0]);
			}
		if (hist_row==false)
			{
			alert('edit.func.close: Error not exist hist_row.');
			}
*/
//alert(hist_row)
//alert([
//data_row[xy[1]]==val,
//data_row[xy[1]]==val,
//data_row[xy[1]],val,
//'edit.func.close'
//])
//alert([
//data_row,
//"\n",
//q_update_row
//]);
//alert([
//data_row[xy[1]]==val,
//data_row[xy[1]],val,
//'edit.func.close'
//])
/*
		fn.dataUpdate(xy[0], xy[1], val);
*/

this.edit.func.tdTrColorize = function(html_td, val, bool)
	{
	HTML.func.classRemove(html_td, 'm');
	if (bool==false)
		{
		HTML.func.classAdd(html_td.parentNode, 'm');	// TR
		HTML.func.classAdd(html_td, 'm');
//alert([3,el.nodeName,el.className])
		}
	}

this.edit.func.inputRemove = function(html_td,val)	// el = TD	,bool
	{
	root.edit.func.log('inputRemove');
	var cl, x,y,xy1,fn;
	fn = root.edit.func;
	html_td.innerHTML = val;
//alert([el1, el1.toSource()])
// x,y el.parentNode.neco
	// colorize col
//alert([1,el.nodeName,el.className])
	HTML.func.classRemove(html_td, 'edit');
		xy1 = fn.getXY(html_td, true);
		x = xy1[1];
		y = xy1[0] - 1;
//alert([x,y])
		HTML.func.classRemove(fn.getTdByXY(html_td, x  , y-1), 'edit1');
		HTML.func.classRemove(fn.getTdByXY(html_td, x-1, y  ), 'edit2');
//alert([2,el.nodeName,el.className])
//	cl = root.edit.func.classRemove(el.className, 'm');
//	if (bool==false)
//		{
//		cl += ' m';
//		}
//	el.className = cl;
	}

this.edit.func.inputCreate = function(el)	// el = TD
	{
	root.edit.func.log('inputCreate');
	var xy, xy1,x,y;
	xy = root.edit.func.getXY(el,false);
//alert(['xy',xy,typeof xy])
	if (xy!=="")
		{
//alert([7,el.nodeName,el.className])
		HTML.func.classAdd(el,'edit')
		xy1 = root.edit.func.getXY(el,true);
		x = xy1[1];
		y = xy1[0] - 1;
//alert([x,y])
		HTML.func.classAdd(root.edit.func.getTdByXY(el,x  ,y-1),'edit1');
		HTML.func.classAdd(root.edit.func.getTdByXY(el,x-1,y  ),'edit2');
//alert([8,el.nodeName,el.className])
//111	el.
		el.innerHTML = '<input class="edit" value="'+el.innerHTML+'" onpaste="APPEDIT.edit.func.inputOnPaste(event);">';
		el = el.getElementsByTagName('INPUT')[0];
		el.focus();
		el.value = el.value;
		el.selectionStart  = el.selectionEnd = el.value.length;
		root.edit.input    = el;
		root.edit.input_id = xy;
		}
	}

this.edit.func.inputOpen = function(event)
	{
	root.edit.func.log('open');
	var ev_data, el;
	ev_data = root.event.func.read(event);
	el      = ev_data.target;	// td or input
	if (el.nodeName=='TH')
		{
		root.edit.func.insertRowClick(el);
		}
	//root.func.log('.func.open node '+el.nodeName);
	xy = root.edit.func.getXY(el.parentNode,false);
	if (xy!=="" && root.edit.input_id==xy)
		{
//	root.func.log('.func.open input_id==xy');
		return;
		}
	root.edit.func.inputClose();
	if (isExist(el) && el.nodeName=='TD')
		{
		root.edit.func.inputCreate(el);
		}
//	root.func.log('.func.open END');
	}


this.edit.func.insertRowClick = function(html_th)
	{
	root.edit.func.log('insertRowClick');
	var xy, xy1,x,y, fn, clear_row;
	fn = root.edit.func;
	fn.inputClose();	// input edit close
	xy = fn.getXY(html_th, true);
	x  = xy[1];
	y  = xy[0] - 1;
var str, arr, i;
//str = '';
//for (i=0;i<root.table.data.length;i++)
//str+=root.table.data[i].join(', ')+"\n"
//alert(str)
//str = '';
//for (i=0;i<root.table.data.length;i++)
//str+=root.table.data[i].join(', ')+"\n"
//alert(str)
//arr = root.edit.data.q_update;
//str = ''; for (i=0;i<arr.length;i++) {if (isArray(arr[i])) {str+=i+': '+arr[i].join(', ')+"\n";}}
//alert(str)
	clear_row = arrayClone1Clear(root.table.data[0]);
	fn.dataInsertMiddle(y,clear_row,0);
//alert(root.table.data.join('\n'))
	fn.q_updateInsertMiddle(y,clear_row,0);
//alert(root.edit.data.q_update.join('\n'))
	fn.q_deleteInsertMiddle(y,null,0);
//arr = root.edit.data.q_update;
//str = ''; for (i=0;i<arr.length;i++) {if (isArray(arr[i])) {str+=i+': '+arr[i].join(', ')+"\n";}}
//alert(str)
//	root.func.tableApplyChanges();
//	root.edit.func.applyOnTable();
root.func.tableRender();
//alert(root.table.data[y+3])
	}

this.edit.func.colorizeTable = function()
{
	root.edit.func.log('colorizeTable');

	var i, j, k, l, m, i_end, j_end, k_end, l_end, out, q_insert, q_update, q_delete, clear, row, arr;
	var p, fn;
	arr = root.table.data;
	p = {};
	p.row    = null;
	p.update = null;
	p.clear = arrayClone1Clear(arr[0],'');// create clear array
	fn = {};
	fn.start_CB     = function (p)   {p.row = null; p.update = null; return p;};
	fn.insert_CB    = function (p)   {p.row = arrayClone1(p.clear); alert('error: insert by nastat nemelo'); return p;};
	fn.original0_CB = function (p,a) {p.row = arrayClone1(a); return p;};
	fn.original1_CB = function (p)   {return p;};
	fn.original2_CB = function (p)   {alert('chyba: arr[i] je null;'); return p;};
	fn.update_CB    = function (p,a) {
//alert([p.row,'\n',a])

p.update = arrayClone1(a); return p;};
	fn.delete_CB    = function (p)   {return p;};
	fn.end_CB       = function (p,m) {
		if (p.update!=null)
			{
//alert(p.toSource())
			m = m - 1;	// ignore csv head-row
			root.edit.func.log('--color-- '+m);
			html_tr = root.edit.func.getTrByY(m);
			if (!isExist(html_tr))
				{
				alert('error: radek m mel existovat');
				return p;
				}
//alert(['colorizeTable','\n',m,'\n',p.update,'\n', p.row])
			root.edit.func.trColorize(html_tr, p.update, p.row);
			}
		return p;
                };
	root.edit.func.tableCycle(arr, p, fn);
	root.edit.func.log('colorizeTable END');
}

this.func.tableApplyFiltersXX = function(arr)
	{
	root.func.log(root.name + '.func.tableApplyFiltersXX START');
	var i, j, k, l, m, i_end, j_end, k_end, l_end, out, q_insert, q_update, q_delete, clear, row;
//	arr = arrayClone2(arr);
	var p, fn;
	p = {};
	p.out = [];
//alert(['p.out1',p.out.join("\n")])
	p.row = [];
	p.clear = arrayClone1Clear(arr[0],'');// create clear array
//	i_end = arr[0].length;
//	for(i=0;i<i_end;i++)
//		{
//		p.clear[i] = '';
//		}
//alert(p.clear)
	fn = {};
	fn.start_CB     = function (p)   {p.row = null; return p;};
	fn.insert_CB    = function (p)   {p.row = arrayClone1(p.clear); alert('error: insert by nastat nemelo'); return p;};
	fn.original0_CB = function (p,a) {p.row = arrayClone1(a); return p;};
	fn.original1_CB = function (p)    { return p;};
	fn.update_CB    = function (p,a) {
//alert([p.row,'\n',a])
p.row = arrayClone1(a); return p;};
	fn.delete_CB    = function (p)    {return p;};
	fn.end_CB       = function (p,m) {p.out[m] = p.row; return p;};
	root.edit.func.tableCycle(arr, p, fn);
	root.func.log(root.name + '.func.tableApplyFiltersXX END');
//alert(['tableApplyFiltersXX\np.out2\n',p.out.join("\n")])
	return p.out;
	}

this.edit.func.tableCycle = function(arr, params, fn)
	{
	root.edit.func.log('tableCycle');
	var i, j, k, l, m, i_end, j_end, k_end, l_end, q_insert, q_update, q_delete;
//	arr = arrayClone2(arr);
	q_insert = root.edit.data.q_insert;	// q_insert je vzdy prazdne, insert vlozi prazdny radek do data, update i delete
	q_update = root.edit.data.q_update;
//alert(['tableCycle','\n',arr.join('\n')])
	q_delete = root.edit.data.q_delete;
	i_end = arr.length;
	j_end = q_insert.length;
	k_end = q_update.length;
	l_end = q_delete.length;
	i = 0;
	j = 0;
	k = 0;
	l = 0;
	m = 0;
//alert(['q_update',q_update.join('\n')])
//alert(arr)
//mm = Math.max(i_end,j_end)
	while (i<i_end || j<j_end || k<k_end || l<l_end)
		{
//		row = null;
		params = fn.start_CB(params);
		if (isArray(q_insert[j]))
			{
//alert('insert');
//			row = arrayClone1(clear);
			params = fn.insert_CB(params);			// insert
			}
		else	{
//alert('original');
			if (isArray(arr[i]))
				{
//				row = arrayClone1(arr[i]);
				params = fn.original0_CB(params, arr[i]);	// original
//alert(['original',i,'\n',arr[i],'\n',params.row]);
				}
			else	{
			params = fn.original2_CB(params);
}
			params = fn.original1_CB(params);
			i++;
			}
		j++;
		if (isArray(q_update[k]))			// update
			{
//alert(['update',k,i-1,'\n','update','\n',q_update[k],'\n','orig','\n',arr[i-1],'\n','p.row','\n',params.row]);
//			row = arrayClone1(q_update[k]);
			params = fn.update_CB(params, q_update[k]);
			}
		k++;
		if (isArray(q_delete[l]))
			{
//alert('delete');
			params = fn.delete_CB(params);			// delete
			l++;
			continue;
			}
		l++;
//	root.edit.func.log('ijkl'+[i,j,k,l].join(','));
//		out[m] = row;
		params = fn.end_CB(params, m);
		m++;
		}
	return params;
	}

/*
//this.edit.func.trColorize = function(html_tr, q_update_row, data_row)
	// obarveni;
	q_insert = root.edit.data.q_insert;
	q_update = root.edit.data.q_update;
	q_delete = root.edit.data.q_delete;
	i_end = arr.length;
	j_end = q_insert.length;
	k_end = q_update.length;
	l_end = q_delete.length;
	i = 0;
	j = 0;
	k = 0;
	l = 0;
	m = 0;
//alert(arr)
	while (i<i_end || j<j_end || k<k_end)
		{
		bool = false;
		if (isArray(q_insert[j]))
			{
			bool = false;
			}
		else	{
			if (isArray(arr[i]))
				{
				}
			bool = false;
			i++;
			}
		j++;
		if (isArray(q_update[k]))
			{
			bool = true;
			}
		k++;
		if (isArray(q_delete[l]))
			{
			l++;
			continue;
			}
		l++;
		m++;
		}
*/


this.edit.func.inputOnPasteCB = function(event, content)
	{
	var ev_data, el, el_td, el_td_main, arr, i, i_end, xy, x,y, html_td, html_tr, rows;
	var val, data_row, fn;
	fn = root.edit.func;
	fn.log('inputOnPasteCB');

	ev_data = root.event.func.read(event);
	el = ev_data['target'];		// INPUT

	if (el.nodeName=='INPUT')
		{
		el = el.parentNode;	// html td
		fn.inputClose();	// close input, if opened
		}
	if (el.nodeName!='TD')
		{
		return;
		}
	html_td = el;

//	content = content.replace(/^[\r\n\t]+|[ \r\n\t]+$/g,'');

//alert([content.indexOf("\t"), content.indexOf("\n")]);
	// single cell
	if (content.indexOf("\t")===-1 && content.indexOf("\n")===-1)
		{
// !!! proc mi to neuklada hodnotu? !!!
		//el.innerHTML = content;
		html_tr = html_td.parentNode;
		fn.tdUpdate(html_td, content);
		rows = fn.tdUpdate(html_td, content);
//		fn.tdTrColorize(html_td,val, data_row[xy[1]]==val);
		fn.trColorize(html_tr, rows.q_update, rows.data);
		return;
		}
alert(content.replace(/\n/g,'NNN').replace(/\t/g,'TTT'))
// -------
/*
		fn.data.q_updateUpdate(xy[0], xy[1], val);
		fn.inputRemove(html_td, val, data_row[xy[1]]==val);
		fn.trColorize(html_tr, q_update_row, data_row);
		}
	root.edit.input    = null;
	root.edit.input_id = null;
*/
	// more cols, divided by tabelator \t
	arr = content.split("\t");
	el.value = arr[0];
	el_tr = el.parentNode;
	xy = root.edit.func.getXY(el_tr,true);	// TD
	x = xy[1];
	y = xy[0] - 1;
	i_end = arr.length;

data_row = fn.dataSelect(y+1);
		q_update_row = fn.data.q_updateSelect(y+1);
		if (q_update_row==false)
			{
			q_update_row = fn.data.q_updateInsert(y+1,data_row);
			}
		if (q_update_row==false)
			{
			alert('Error 0: Not exist q_update_row.');
			}

	for(i=1;i<i_end;i++)
		{
		el_td = root.edit.func.getTdByXY(el_tr,x+i,y);
		if (isExist(el_td))
			{
//			el_td.innerHTML = arr[i];
		val = arr[i];
		q_update_row = fn.data.q_updateUpdate(y, x+i, val);
		fn.inputRemove(el_td, val);	//, data_row[x+i]==val

			}
//		HTML.func.classRemove(el_td,'edit1');
		}
	fn.trColorize(el_tr, q_update_row, data_row);
	}

this.edit.func.inputOnPaste = function(event)
	{
	root.edit.func.log('inputOnPaste');
	var content;
	event.preventDefault();
	if( event.clipboardData )
		{
		content = event.clipboardData.getData('text/plain');
		root.edit.func.inputOnPasteCB(event, content);
		return false;
		}
	else if( window.clipboardData )
		{
		content = window.clipboardData.getData('Text');
		root.edit.func.inputOnPasteCB(event, content);
		}
	}

//this.edit.func.insertRowButtonClick = function(event)
//	{
//	}



this.func.init(opt);
}



var APPEDIT, opt;
opt = {
	func: {log: SCREEN.log},
	data: {
		filex: {
//			import_root: 'file:///C:/pp/js-zas3/',				// mlich
//			import_root: 'file:///C://Users/vlha/Downloads/Tajemnik/',	// vlha
			import_root: '',
			import_path: 'actual/zas.csv',	// disk
			export_name_all     : 'zas_bn13.csv',
			export_name_filtered: 'zas_bn13.csv'
			}
//		fmsx: [
//			{'col':3, 'order':'asc'},
//			{'col':1, 'order':'asc'}
//			],
//		fwx: [
//			]
		}
	};


function getPos(el, scroll_left, scroll_top)
	{
	var scr;
	scr = document.documentElement || document.body;
	return {
		x: el.offsetLeft + (scroll_left ? (scr.scrollLeft || scr.clientLeft) : 0),
		y: el.offsetTop  + (scroll_top  ? (scr.scrollTop  || scr.clientTop ) : 0)
		}
	}

function scrollFixed()
	{
	var fix = $('fixed1');
	var tbl = $('table');
	var pos = getPos(tbl, false, true);
//	body = document.documentElement || document.body;
//	fix.style.position = 'absolute';
//	fix.style.left = (tbl.offsetLeft) + 'px';	// + (body.scrollLeft || body.clientLeft)
//	fix.style.top  = (tbl.offsetTop  + (body.scrollTop  || body.clientTop))  + 'px';
	fix.style.left = pos.x + 'px';
	fix.style.top  = pos.y + 'px';
	}

APPEDIT = new classAppEdit(opt);
//APP.file.func.import();
APPEDIT.open.func.htmlNavCreate([]);
APPEDIT.open.func.openFromUrl(location.href,'zas_bn13.csv');

window.onscroll = scrollFixed;
