/*	
	WWW SQL Designer, (C) 2005 Ondra Zara, o.z.fw@seznam.cz

    This file is part of WWW SQL Designer.

    WWW SQL Designer is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    WWW SQL Designer is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with WWW SQL Designer; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA	
*/

/*
	strategie: vsichni potomci tabulky musi mit vyplneny atribut parent_number, aby z nich bylo snadno poznat,
	ke kteremu objektu prislusi. Dal musi mit vischni vyplneny typ.
*/


/*
	objekt abstractParent:
		setTitle() - zmena textu v _title
		select(), deselect() - vyber
		select => je-li vybrano
		_title => html element
		_div => html element
*/


/**********  CODE BEGIN  **********/

function moveit(obj, x, y){
	obj.style.left=parseInt(obj.style.left)+x+"px";
	obj.style.top=parseInt(obj.style.top)+y+"px";
}
  		
function print_view() {
	var elem;
	elem = document.getElementById("bar");
	elem.parentNode.removeChild(elem);
	elem = document.getElementById("map");
	elem.parentNode.removeChild(elem);
	elem = document.getElementById("root").getElementsByTagName("DIV");
	
	for(var i = 0; i < elem.length; i++) {
		moveit(elem[i], 0, -100);
	}
}	

/**********  CODE END  **********/

function abstractParent_setTitle(text) {
	this._title.innerHTML = text;
}

function abstractParent_destroy() {
	this._div.parentNode.removeChild(this._div);
	if (this._mini) {
		this._mini.parentNode.removeChild(this._mini);
	}
}

function abstractParent_select() {
	this._div.className = this._div.className + " " + this._div.className + "_selected";
	this.selected = true;
}

function abstractParent_deselect() {
	this._div.className = this._div.getAttribute("defaultClassName");
	this.selected = false;
}

function abstractParent(type, parent_number, row_number, className) {
	this._div = document.createElement("div");
	this._title = document.createElement("div");

	this._title.className = "title";
	this._div.className = className;

	this._div.setAttribute("defaultClassName",className);
	this._div.setAttribute("parent_number",parent_number);
	this._div.setAttribute("row_number",row_number);
	this._div.setAttribute("element_type",type);
	
	this._title.setAttribute("parent_number",parent_number);
	this._title.setAttribute("row_number",row_number);
	this._title.setAttribute("element_type",TYPE_TITLE);

	this._div.appendChild(this._title);
	
	this.selected = false;
	this.select = abstractParent_select;
	this.deselect = abstractParent_deselect;
	this.destroy = abstractParent_destroy;
	this.setTitle = abstractParent_setTitle;
/*	universalAttacher(this._div,"mousedown",global_event_mousedown); */
}

/*
	objekt Row
		setPK(), losePK() - primary key
		setFK(), loseFK() - foreign key
		setIndex(), loseIndex() - index
		setNN(), loseNN() - not null
		setDef() - default
		updateTitle() - updatne title="xxx" atribut
		setTitle() - updatne title="xxx" atribut
		setType() - updatne typ a defaultni hodnotu
		updateSpecial() - updatne special
		updateColor() - updatne pozadi dle datoveho typu
		_special - drzadlo na specialni PK a FK, vpravo
		
		pk - je-li primary key
		fk - je-li foreign key
		index - je-li index
		nn - je-li notnull
		def - defaultni hodnota
		type - datovy typ (resp. jeho index)
		spec - delka ci vycet
*/

function Row_setPK() {
	this.pk = 1;
	this.setIndex();
	this.updateTitle();
	this.updateSpecial();
	this._title.style.fontWeight = "bold";
}

function Row_losePK() {
	this.pk = 0;
	this.updateTitle();
	this.updateSpecial();
	this._title.style.fontWeight = "normal";
}

function Row_setFK() {
	this.fk = 1;
	this.updateTitle();
	this.updateSpecial();
}

function Row_loseFK() {
	this.fk = 0;
	this.updateTitle();
	this.updateSpecial();
}

function Row_setNN() {
	this.nn = 1;
	this.updateTitle();
}

function Row_loseNN() {
	this.nn = 0;
	this.updateTitle();
}

function Row_setIndex() {
	this.index = 1;
	this.updateTitle();
	this._title.style.fontStyle = "italic";
}

function Row_loseIndex() {
	this.index = 0;
	this.updateTitle();
	this._title.style.fontStyle = "normal";
}

function Row_updateTitle() {
	str = this._title.innerHTML + ": ";
	str += SQL_TYPES_DEFAULT[this.type];
	if (SQL_TYPES_SPEC[this.type]) {
		str += "(" + this.spec + ")";
	}
	str += ", default: '" + this.def + "'";
	if (this.pk) {
		str += ", Primary key";
	}
	if (this.fk) {
		str += ", Foreign key";
	}
	if (this.nn) {
		str += ", NOT NULL";
	}
	if (this.index) {
		str += ", Index";
	}
	this._div.setAttribute("title",str);
	this._title.setAttribute("title",str);
}

function Row_setDef(value) {
	this.def = value;
	this.updateTitle();
}

function Row_setSpec(value) {
	this.spec = value;
	this.updateTitle();
}

function Row_setType(type) {
	this.type = type;
	this.def = SQL_TYPES_VALUES[type];
	this.updateTitle();
	this.updateColor();
}

function Row_setFormInput(forminput) {
	this.forminput = forminput;
	//this.def = INPUT_TYPES_VALUES[type];
}
function Row_setFI_path (fi_path){this.fi_path = fi_path;}
function Row_setFI_type (fi_type){this.fi_type = fi_type;}
function Row_setFI_name (fi_name){this.fi_name = fi_name;}
function Row_setFI_dbfield (fi_dbfield){this.fi_dbfield =fi_dbfield ;}
function Row_setFI_title (fi_title){this.fi_title = fi_title;}
function Row_setFI_value (fi_value){this.fi_value = fi_value;}
function Row_setFI_nolayout (fi_nolayout){this.fi_nolayout = fi_nolayout;}
function Row_setFI_size (fi_size){this.fi_size = fi_size;}
function Row_setFI_maxlength (fi_maxlength){this.fi_maxlength = fi_maxlength;}
function Row_setFI_mandatory (fi_mandatory){this.fi_mandatory = fi_mandatory;}
function Row_setFI_bubble (fi_bubble){this.fi_bubble = fi_bubble;}
function Row_setFI_xplaintxt (fi_xplaintxt){this.fi_xplaintxt = fi_xplaintxt;}
function Row_setFI_attribute (fi_attribute){this.fi_attribute = fi_attribute;}
function Row_setFI_optionVal (fi_optionVal){this.fi_optionVal = fi_optionVal;}
function Row_setFI_optionLbl (fi_optionLbl){this.fi_optionLbl = fi_optionLbl;}
function Row_setFI_optionSel (fi_optionSel){this.fi_optionSel = fi_optionSel;}

function Row_updateSpecial() {
	var str = "";
	if (this.pk) str += "PK";
	if (this.pk && this.fk) str += ",";
	if (this.fk) str += "FK";
	this._special.innerHTML = str;
}

function Row_updateColor() {
	var total = 0;
	for (var i=0;i<SQL_TYPES_DIVISION.length;i++) {
		for (var j=0;j<SQL_TYPES_DIVISION[i].count;j++) {
			if (this.type == total) {
				this._div.style.backgroundColor = SQL_TYPES_DIVISION[i].color;
			}
			total++;
		}
	}
}

function Row_appendRelation(relation) {
	var count = get_free_index(this.relations);
	this.relations[count] = relation; /* dame si objekt do pole */
}

function Row_updateRelations() {
	for (var i=0;i<this.relations.length;i++) {
		if (this.relations[i]) {
			this.relations[i].update();
		}
	}
}

function Row_hideRelations() {
	for (var i=0;i<this.relations.length;i++) {
		if (this.relations[i]) {
			this.relations[i].hide();
		}
	}
}

function Row_showRelations() {
	for (var i=0;i<this.relations.length;i++) {
		if (this.relations[i]) {
			this.relations[i].show();
		}
	}
}

function Row_removeRelation(global_index) {
	for (var i=0;i<this.relations.length;i++) {
		if (this.relations[i] && this.relations[i]._div.getAttribute("parent_number") == global_index) {
			this.relations[i] = null;
		}
	}
}

Row.prototype = new abstractParent();
function Row(parent_number,row_number,title,type,forminput) {
	this.base = abstractParent;
	this.base(TYPE_ROW, parent_number, row_number, "row");
	this.relations = Array();
	this.setPK = Row_setPK;
	this.losePK = Row_losePK;
	this.setFK = Row_setFK;
	this.loseFK = Row_loseFK;
	this.setIndex = Row_setIndex;
	this.loseIndex = Row_loseIndex;
	this.setNN = Row_setNN;
	this.loseNN = Row_loseNN;
	this.setType = Row_setType;
	this.setSpec = Row_setSpec;
	this.updateTitle = Row_updateTitle;
	this.updateSpecial = Row_updateSpecial;
	this.updateColor = Row_updateColor;
	this.setDef = Row_setDef;
	
	this.setFormInput = Row_setFormInput;
	this.setFI_path = Row_setFI_path;
	this.setFI_type = Row_setFI_type;
	this.setFI_name = Row_setFI_name;
	this.setFI_dbfield = Row_setFI_dbfield;
	this.setFI_title = Row_setFI_title;
	this.setFI_value = Row_setFI_value;
	this.setFI_nolayout = Row_setFI_nolayout;
	this.setFI_size = Row_setFI_size;
	this.setFI_maxlength = Row_setFI_maxlength;
	this.setFI_mandatory = Row_setFI_mandatory;
	this.setFI_bubble = Row_setFI_bubble;
	this.setFI_xplaintxt = Row_setFI_xplaintxt;
	this.setFI_attribute = Row_setFI_attribute;
	this.setFI_optionVal = Row_setFI_optionVal;
	this.setFI_optionLbl = Row_setFI_optionLbl;
	this.setFI_optionSel = Row_setFI_optionSel;
	
	this.appendRelation = Row_appendRelation;
	this.updateRelations = Row_updateRelations;
	this.showRelations = Row_showRelations;
	this.hideRelations = Row_hideRelations;
	this.removeRelation = Row_removeRelation;
	this.setTitle(title);
	this._title.setAttribute("element_type",TYPE_ROWTITLE);
	this._title.className = "row_title";
	this._special = document.createElement("div");
	this._special.className="special";
	this._special.setAttribute("parent_number",parent_number);
	this._special.setAttribute("row_number",row_number);
	this._sipka = document.createElement("div");
	this._sipka.setAttribute("parent_number",parent_number);
	this._sipka.setAttribute("row_number",row_number);
	this._sipka.className="sipka";
	this._sipka.innerHTML = "&raquo;&nbsp;";
	this._div.insertBefore(this._special,this._title);
	this._div.insertBefore(this._sipka,this._title);
	this.pk = 0;
	this.fk = 0;
	this.index = 0;
	this.def = "";
	this.nn = 0;
	this.spec = "";
	this.setType(type);
	this.setFormInput(forminput);
	this.updateTitle();
	this.updateColor();
}


/*
	objekt Relation:
		update() - upravi pozice na zaklade pozic otcu
		select(), deselect() - ma svuj vlastni select, neb sestava ze 3 casti
		hover(), dehover() - ma svuj vlastni hover, neb sestava ze 3 casti
		parent_1, parent_2 - divy otcovskych tabulek
		row_1, row_2 - divy relevantnich radek
		number_1, number_2 - indexy do poli relaci v tabulkach
		id - id do globalni tabulky
*/

function Relation_show() {
	this._div.style.visibility = "visible";
}

function Relation_hide() {
	this._div.style.visibility = "hidden";
}

function Relation_update() {
	/* 
		prekresleni car:
		rozlisujeme dva pripady,
 		 a) kdyz maji mezi sebou tabulky horizontalni mezeru,
		 b) kdyz ji nemaji
	*/
	
	/* 
		k napozicovani elementu je potreba techto udaju:
			- start_x, start_y, center_x, start_y
			- center_x, start_y, center_x, end_y
			- center_x, end_y, end_x, end_y
	*/

	var left_table, right_table, left_row, right_row, left_1, left_2, right_1, right_2, width_1, width_2;
	var top_table_1, top_table_2, top_row_1, top_row_2;
	if (parseInt(this.parent_1._div.style.left) < parseInt(this.parent_2._div.style.left)) {
		left_table = this.parent_1._div;
		right_table = this.parent_2._div;
		left_row = this.row_1._div;
		right_row = this.row_2._div;
	} else {
		right_table = this.parent_1._div;
		left_table = this.parent_2._div;
		right_row = this.row_1._div;
		left_row = this.row_2._div;
	}
	/* ted uz vime, ktera tabulka ma levou hranu vic vlevo. spocteme dulezita cisla */
	left_1 = parseInt(left_table.style.left); /* leva hrana leve tabulky */
	left_2 = parseInt(right_table.style.left); /* leva hrana prave tabulky */
	width_1 = parseInt(left_table.offsetWidth); /* sirka leve tabulky */
	width_2 = parseInt(right_table.offsetWidth); /* sirka prave tabulky */
	right_1 = left_1 + width_1; /* prava hrana leve tabulky */
	right_2 = left_2 + width_2; /* prava hrana prave tabulky */
	top_table_1 = parseInt(left_table.style.top); /* horni hrana leve tabulky */
	top_table_2 = parseInt(right_table.style.top); /* horni hrana prave tabulky */
	top_row_1 = Math.round(parseInt(left_row.offsetHeight)/2)+parseInt(left_row.offsetTop); /* posun radku v leve tabulce */
	top_row_2 = Math.round(parseInt(right_row.offsetHeight)/2)+parseInt(right_row.offsetTop); /* posun radku v prave tabulce */
	
	/* nyni detekce mezery... */
	if (right_1 < left_2) {
		/* tabulky mezi sebou maji mezeru, standardni postup */
		var width = left_2 - left_1 - width_1 + RELATION_THICKNESS;
		var start_x = left_1 + width_1 - RELATION_THICKNESS;
		var start_y = top_table_1 + top_row_1;
		var end_x = left_2;
		var end_y = top_table_2 + top_row_2;
		var center_x = start_x + Math.round(width / 2);
		/* korekce kvuli borderu... */
		start_x--;
	} else {
		var diff_1 = Math.abs(left_2 - left_1); /* rozdil vlevo */
		var diff_2 = Math.abs(right_2 - right_1); /* rozdil vlevo */
		if (diff_1 < diff_2 + RELATION_THICKNESS) {
			/* "ucho" povede vlevo od obou tabulek */
			start_x = left_1;
			start_y = top_table_1 + top_row_1;
			end_x = left_2;
			end_y = top_table_2 + top_row_2;
			center_x = start_x - RELATION_OFFSET;
		} else {
			/* "ucho" povede vpravo od obou tabulek */
			start_x = Math.max(right_1, right_2) - RELATION_THICKNESS;
			start_y = (right_1 > right_2 ? top_table_1 + top_row_1 : top_table_2 + top_row_2);
			end_x = Math.min(right_1, right_2) - RELATION_THICKNESS;
			end_y = (right_1 < right_2 ? top_table_1 + top_row_1 : top_table_2 + top_row_2);
			center_x = start_x + RELATION_OFFSET;
			/* korekce kvuli borderu... */
			start_x--;
			end_x--;
		}
	}
	
	
	/* a jedem */
	this.elem_1.style.left = Math.min(start_x, center_x) + "px";
	this.elem_1.style.top = start_y + "px"
	this.elem_1.style.width = Math.abs(center_x - start_x) + "px";
	this.elem_2.style.left = center_x;
	this.elem_2.style.top = Math.min(start_y, end_y);
	this.elem_2.style.height = Math.abs(end_y - start_y) + RELATION_THICKNESS + "px";
	this.elem_3.style.left = Math.min(center_x, end_x) + "px";
	this.elem_3.style.top = end_y + "px"
	this.elem_3.style.width = Math.abs(center_x - end_x) + "px";
}

Relation.prototype = new abstractParent(); 
function Relation(parent_1, row_1, parent_2, row_2, id) {
	this.base = abstractParent;
	this.base(TYPE_RELATION, id, row_1, "relation");
	this._title.parentNode.removeChild(this._title);
	this.update = Relation_update; /* funkce na aktualizaci car */
	this.show = Relation_show; /* ukazani */
	this.hide = Relation_hide; /* schovani */
	this.parent_1 = parent_1; /* prvni rodicovska tabulka */
	this.parent_2 = parent_2; /* druha rodicovska tabulka */
	this.row_1 = row_1; /* prvni rodicovska radka */
	this.row_2 = row_2; /* druha rodicovska radka */
	this.elem_1 = document.createElement("div");
	this.elem_2 = document.createElement("div");
	this.elem_3 = document.createElement("div");
	this.elem_1.style.height = RELATION_THICKNESS;
	this.elem_2.style.width = RELATION_THICKNESS;
	this.elem_3.style.height = RELATION_THICKNESS;
	this.elem_1.setAttribute("element_type",TYPE_RELATION_PART);
	this.elem_2.setAttribute("element_type",TYPE_RELATION_PART);
	this.elem_3.setAttribute("element_type",TYPE_RELATION_PART);
	this._div.appendChild(this.elem_1);
	this._div.appendChild(this.elem_2);
	this._div.appendChild(this.elem_3);
}

/*
	objekt Table:
		moveTo() - posun na zadane souradnice
		addRow() - prida radku
		removeRow() - odebere radku
		selectRow() - vybere radku
		appendRelation() - prida relaci
		removeRelation() - zrusi relaci
		updateWidth() - aktualizuje sirku
		updateMini() - aktualizuje minimapku
		updateShadow() - aktualizuje rozbite stiny
		showRelations() - ukaze relevantni relace
		hideRelations() - schova relevantni relace
		rows => pole radku
		_rows => html drzak radku
		relations => pole relaci, ktere se tykaji teto tabulky
*/



function Table_updateMini() {
	var w = parseInt(this._div.offsetWidth);
	var h = parseInt(this._div.offsetHeight);
	var l = parseInt(this._div.style.left);
	var t = parseInt(this._div.style.top);
	this._mini.style.width = Math.round(w * MAP_SIZE / DESK_SIZE) + "px";
	this._mini.style.height = Math.round(h * MAP_SIZE / DESK_SIZE) + "px";
	this._mini.style.left = Math.round(l * MAP_SIZE / DESK_SIZE) + "px";
	this._mini.style.top = Math.round(t * MAP_SIZE / DESK_SIZE) + "px";
}

function Table_moveTo(x,y) {
	this._div.style.left = x + "px";
	this._div.style.top = y + "px";
	this.updateMini();
}

function Table_addRow(title,type,custom_index,forminput) {
	var count = get_free_index(this.rows);
	if (custom_index) {
		count = custom_index;
	}
	var row = new Row(this.number,count,title,type,forminput); /* to je ona */
	this.rows[count] = row; /* dame si objekt do pole */
	this._rows.appendChild(row._div); /* a pridame i do HTML stromu */
	this.updateWidth();
	var x = this;
	var endFuncRef = function() {
		x.updateMini();
		x.updateShadow();
		for (var i=0;i<x.rows.length;i++) {
			if (x.rows[i]) {
				x.rows[i].updateRelations();
				x.rows[i].showRelations();
			}
		}
	}
	start_animation(row._div,1,endFuncRef);
	return row;
}

function Table_removeRow(index,no_animation) {
	/* neprijdeme tim o nejake pekne relace? */
	var row = this.rows[index];
	for (var i=0;i<row.relations.length;i++) {
		if (row.relations[i]) {
			var rel_index = row.relations[i]._div.getAttribute("parent_number");
			remove_relation(rel_index);
		}
	}
	var x = this;
	var endFuncRef = function() {
		x.rows[index].destroy(); 
		x.rows[index] = null;
		x.updateMini();
		x.updateShadow();
		x.updateWidth();
		for (var i=0;i<x.rows.length;i++) {
			if (x.rows[i]) {
				x.rows[i].updateRelations();
				x.rows[i].showRelations();
			}
		}
	}
	if (no_animation) {
		endFuncRef();
	} else {
		start_animation(row._div,-1,endFuncRef);
	}
	var last = -1;
	for (var i=0;i<this.rows.length;i++) {
		if (this.rows[i] && i != index) {
			last = i;
		}
	}
	if (last != -1) {
		this.selectRow(last);
	}
	return (last == -1 ? false : this.rows[last]);
}

function Table_selectRow(index) {
	if (this.selectedRow) {
		this.selectedRow.deselect();
	}
	this.selectedRow = this.rows[index];
	this.selectedRow.select();
}


function Table_updateWidth() {
	var index;
	var orig = parseInt(this._div.style.width);
	var max=this._title.innerHTML.length;
	for (var i=0;i<this.rows.length;i++) {
		if (this.rows[i]) {
			if (this.rows[i]._title.innerHTML.length > max) {
				max = this.rows[i]._title.innerHTML.length;
			}
		}
	}
	var new_ = Math.max(TABLE_WIDTH,80+max*LETTER_WIDTH);
	this._div.style.width = new_ + "px";
	if (new_ != orig) {
		this.updateMini();
		/* pokud jsme tabulce zmenili rozmery, musime aktualizovat relace */
		for (var i=0;i<this.rows.length;i++) {
			if (this.rows[i]) {
				this.rows[i].updateRelations();
			} /* if ziva relace */
		} /* for vsechny relace */
	} /* if hybli sme sirkou */
}

function Table_hideShadow() {
	this.s1.className= "";
	this.s2.className= "";
	this.s3.className= "";
}

function Table_updateShadow() {
	this.hideShadow();
	this.s1.className= "shadow_right";
	this.s2.className= "shadow_bottom";
	this.s3.className = "shadow_corner";
}

function Table_setPK(index) {
	/* primary key */
	var old_primary = -1;
	for (var i=0;i<this.rows.length;i++) {
		if (this.rows[i]) {
			if (this.rows[i].pk) {
				old_primary = i;
				this.rows[i].losePK();
			}
		}
	}
	if (old_primary != -1) {
		/* predtim uz nejaka radka byla primary. pak je mozna potreba predelat relaci. */
		var old = this.rows[old_primary];
		for (var j=0;j<old.relations.length;j++) {
			if (old.relations[j]) {
				if (old.relations[j].parent_1._div.getAttribute("parent_number") == this.number 
					&& old.relations[j].row_1._div.getAttribute("row_number") == old_primary) {
					var count = get_free_index(this.rows[index].relations);
					this.rows[index].relations[count] = old.relations[j];
					this.rows[index].relations[count].row_1 = this.rows[index];
					this.rows[index].relations[count].update();
					old.relations[j] = null;
					if (this.rows[index].relations[count].row_2._div.getAttribute("row_number") == index) {
						/* pokud ted mame relaci, ktera vede sama na sebe, zrusime ji */
						remove_relation(this.rows[index].relations[count]._div.getAttribute("parent_number"));
					} 
				} /* pokud je to relace, ktera tam zacinala */
			} /* pokud relace not null */
		} /* for vsechny relace v te stare radce */
	} /* pokud uz existovala jina PK radka */
	this.rows[index].setPK();
}


Table.prototype = new abstractParent();
function Table(x,y,number,_zIndex,title) {
	this.base = abstractParent;
	this.base(TYPE_TABLE, number, 0, "table");
	this._div.style.width = TABLE_WIDTH + "px";
	this.rows = Array();
	this.selectRow = Table_selectRow;
	this.moveTo = Table_moveTo;
	this.addRow = Table_addRow;
	this.removeRow = Table_removeRow;
	this.updateWidth = Table_updateWidth;
	this.updateMini = Table_updateMini;
	this.updateShadow = Table_updateShadow;
	this.hideShadow = Table_hideShadow;
	this.setPK = Table_setPK;

	this.setTitle(title);
	this._title.className = "table_title";
	this.number = number;
	this.selectedRow = null;

	this._rows = document.createElement("div"); /* sem pujdou radky */
	this._rows.className = "rows"
	
	this._mini = document.createElement("div");
	this._mini.className = "mini";
	this._mini.setAttribute("element_type",TYPE_MAP);
	
	/* provazani do stromove struktury */
	var map = document.getElementById("map");
	map.appendChild(this._mini);
	this._div.appendChild(this._rows);
	
	this.s1 = document.createElement("div");
	this.s2 = document.createElement("div");
	this.s3 = document.createElement("div");
	

	this._div.appendChild(this.s1);
	this._div.appendChild(this.s2);
	this._div.appendChild(this.s3);
	this.updateShadow();
	
	this._div.style.zIndex = _zIndex;
	this.moveTo(x,y);
	this.updateWidth();
}


/*
	objekt TableAdmin:
		cudliky na pridani a smazani tabulek, input na zmenu nazvu
		changeName() - zmena nadpisu tabulky
		manageTable, loseTable() - vybrani a odvybrani tabulky
		addTable, delTable() - zruseni a vytvoreni tabulky
	
*/

function TableAdmin_addTable() {
	this.loseTable();
	this._input.value = "[click anywhere to place table]";
	document.body.style.cursor = "crosshair";
	this.last_number++;
	new_table_flag = 1;
	new_table_name = "table_"+this.last_number;
}
/*add a generic theme to the current schema*/
function TableAdmin_addOpalTheme()
{
	dbprefix = this._input.value;
	Udbprefix = dbprefix.toUpperCase();
	add_table(100,150,"opal_"+dbprefix);
	
	table_array[table_array.length-1].addRow(Udbprefix+"_ID",0); 
	table_array[table_array.length-1].rows[0].setPK();
	table_array[table_array.length-1].rows[0].setIndex();
	table_array[table_array.length-1].rows[0].setNN();
	table_array[table_array.length-1].rows[0].setFormInput(0);
	table_array[table_array.length-1].rows[0].setFI_path("private/form/template/inputGeneric.tpl");
	table_array[table_array.length-1].rows[0].setFI_type("hidden");
	table_array[table_array.length-1].rows[0].setFI_name("id");
	table_array[table_array.length-1].rows[0].setFI_dbfield("`$dbprefix`ID");
	
	table_array[table_array.length-1].addRow(Udbprefix+"_USER",4);
	table_array[table_array.length-1].rows[1].setIndex();
	table_array[table_array.length-1].rows[1].setNN();
	table_array[table_array.length-1].rows[1].setSpec(30);
	table_array[table_array.length-1].rows[1].setFormInput(0);
	table_array[table_array.length-1].rows[1].setFI_path("private/form/template/inputGeneric.tpl");
	table_array[table_array.length-1].rows[1].setFI_type("hidden");
	table_array[table_array.length-1].rows[1].setFI_name("user");
	table_array[table_array.length-1].rows[1].setFI_dbfield("`$dbprefix`USER");
	table_array[table_array.length-1].rows[1].setFI_nolayout(true);
	table_array[table_array.length-1].rows[1].setFI_mandatory(true);
	
	table_array[table_array.length-1].addRow(Udbprefix+"_TYPE",4);
	table_array[table_array.length-1].rows[2].setIndex();
	table_array[table_array.length-1].rows[2].setNN();
	table_array[table_array.length-1].rows[2].setSpec(20);
	table_array[table_array.length-1].rows[2].setFormInput(0);
	table_array[table_array.length-1].rows[2].setFI_path("private/form/template/inputGeneric.tpl");
	table_array[table_array.length-1].rows[2].setFI_type("select");
	table_array[table_array.length-1].rows[2].setFI_name("type");
	table_array[table_array.length-1].rows[2].setFI_title("Type");
	table_array[table_array.length-1].rows[2].setFI_bubble("the presentation will change according to the type");
	
	table_array[table_array.length-1].addRow(Udbprefix+"_ACCESS",4);
	table_array[table_array.length-1].rows[3].setIndex();
	table_array[table_array.length-1].rows[3].setNN();
	table_array[table_array.length-1].rows[3].setSpec(10);
	table_array[table_array.length-1].rows[3].setFormInput(1);
	table_array[table_array.length-1].rows[3].setFI_path("private/form/template/inputAccess.tpl");
	table_array[table_array.length-1].rows[3].setFI_dbfield("`$dbprefix`ACCESS");
	
	table_array[table_array.length-1].addRow(Udbprefix+"_NAME",4);
	table_array[table_array.length-1].rows[4].setIndex();
	table_array[table_array.length-1].rows[4].setNN();
	table_array[table_array.length-1].rows[4].setSpec(60);
	table_array[table_array.length-1].rows[4].setFormInput(0);
	table_array[table_array.length-1].rows[4].setFI_path("private/form/template/inputGeneric.tpl");
	table_array[table_array.length-1].rows[4].setFI_type("text");
	table_array[table_array.length-1].rows[4].setFI_name("name");
	table_array[table_array.length-1].rows[4].setFI_dbfield("`$dbprefix`NAME");
	table_array[table_array.length-1].rows[4].setFI_title("Name or Title");
	table_array[table_array.length-1].rows[4].setFI_bubble("be clear and simple, this helps finding your information in the future");
	table_array[table_array.length-1].rows[4].setFI_size("10");
	table_array[table_array.length-1].rows[4].setFI_maxlength("60");
	table_array[table_array.length-1].rows[4].setFI_mandatory(true);
	
	table_array[table_array.length-1].addRow(Udbprefix+"_DATE",8);
	table_array[table_array.length-1].rows[5].setNN();
	table_array[table_array.length-1].rows[5].setDef("NOW()");
	table_array[table_array.length-1].rows[5].setFormInput(0);
	table_array[table_array.length-1].rows[5].setFI_path("private/form/template/inputGeneric.tpl");
	table_array[table_array.length-1].rows[5].setFI_type("text");
	table_array[table_array.length-1].rows[5].setFI_name("date");
	table_array[table_array.length-1].rows[5].setFI_dbfield("`$dbprefix`DATE");
	table_array[table_array.length-1].rows[5].setFI_value('$smarty.now|date_format:"%Y-%m-%d"');
	table_array[table_array.length-1].rows[5].setFI_title("Date (From)");
	table_array[table_array.length-1].rows[5].setFI_xplaintxt("(YYYY-MM-DD ex: 2005-06-12)");
	table_array[table_array.length-1].rows[5].setFI_size("10");
	table_array[table_array.length-1].rows[5].setFI_mandatory(true);
	
	table_array[table_array.length-1].addRow(Udbprefix+"_DATETO",8);
	table_array[table_array.length-1].rows[6].setFormInput(0);
	table_array[table_array.length-1].rows[6].setFI_path("private/form/template/inputGeneric.tpl");
	table_array[table_array.length-1].rows[6].setFI_type("text");
	table_array[table_array.length-1].rows[6].setFI_name("dateto");
	table_array[table_array.length-1].rows[6].setFI_dbfield("`$dbprefix`DATETO");
	table_array[table_array.length-1].rows[6].setFI_title("Date To (period):");
	table_array[table_array.length-1].rows[6].setFI_bubble("ending date of this information");
	table_array[table_array.length-1].rows[6].setFI_size("10");
	
	table_array[table_array.length-1].addRow(Udbprefix+"_COUNTRY",4);
	table_array[table_array.length-1].rows[7].setNN();
	table_array[table_array.length-1].rows[7].setSpec(60);
	table_array[table_array.length-1].rows[7].setFormInput(2);
	table_array[table_array.length-1].rows[7].setFI_path("private/form/template/inputAddress.tpl");
	
	table_array[table_array.length-1].addRow(Udbprefix+"_ADDRESS",4);
	table_array[table_array.length-1].rows[8].setSpec(150);
	
	table_array[table_array.length-1].addRow(Udbprefix+"_PROVINCE",4);
	table_array[table_array.length-1].rows[9].setSpec(40);
	
	table_array[table_array.length-1].addRow(Udbprefix+"_CITY",4);
	table_array[table_array.length-1].rows[10].setSpec(50);
	
	table_array[table_array.length-1].addRow(Udbprefix+"_CODEPOSTAL",4);
	table_array[table_array.length-1].rows[11].setSpec(20);
	
	table_array[table_array.length-1].addRow(Udbprefix+"_LAT",2);
	table_array[table_array.length-1].rows[12].setNN();
	table_array[table_array.length-1].rows[12].setFormInput(0);
	table_array[table_array.length-1].rows[12].setFI_path("private/form/template/inputGeneric.tpl");
	table_array[table_array.length-1].rows[12].setFI_type("text");
	table_array[table_array.length-1].rows[12].setFI_name("lat");
	table_array[table_array.length-1].rows[12].setFI_dbfield("`$dbprefix`LAT");
	table_array[table_array.length-1].rows[12].setFI_title("Latitude (ex:3.5485)");
	table_array[table_array.length-1].rows[12].setFI_bubble("latitude value of this information");
	table_array[table_array.length-1].rows[12].setFI_size("10");
	table_array[table_array.length-1].rows[12].setFI_mandatory(true);
	
	table_array[table_array.length-1].addRow(Udbprefix+"_LONG",2);
	table_array[table_array.length-1].rows[13].setNN();
	table_array[table_array.length-1].rows[13].setFormInput(0);
	table_array[table_array.length-1].rows[13].setFI_path("private/form/template/inputGeneric.tpl");
	table_array[table_array.length-1].rows[13].setFI_type("text");
	table_array[table_array.length-1].rows[13].setFI_name("long");
	table_array[table_array.length-1].rows[13].setFI_dbfield("`$dbprefix`LONG");
	table_array[table_array.length-1].rows[13].setFI_title("Longitude (ex:57.5465)");
	table_array[table_array.length-1].rows[13].setFI_bubble("longitude value of this information");
	table_array[table_array.length-1].rows[13].setFI_size("10");
	table_array[table_array.length-1].rows[13].setFI_mandatory(true);
	
	table_array[table_array.length-1].addRow(Udbprefix+"_DESC",5);
	table_array[table_array.length-1].rows[14].setFormInput(0);
	table_array[table_array.length-1].rows[14].setFI_path("private/form/template/inputGeneric.tpl");
	table_array[table_array.length-1].rows[14].setFI_type("textarea");
	table_array[table_array.length-1].rows[14].setFI_name("desc");
	table_array[table_array.length-1].rows[14].setFI_dbfield("`$dbprefix`DESC");
	table_array[table_array.length-1].rows[14].setFI_title("Description");
	table_array[table_array.length-1].rows[14].setFI_bubble("add some text to your information(can be HTML)");
	
	table_array[table_array.length-1].addRow(Udbprefix+"_FILE",4);
	table_array[table_array.length-1].rows[15].setSpec(80);
	table_array[table_array.length-1].rows[15].setFormInput(6);
	table_array[table_array.length-1].rows[15].setFI_type("upload");
	table_array[table_array.length-1].rows[15].setFI_path("private/form/template/inputUpload.tpl");
	
	table_array[table_array.length-1].addRow(Udbprefix+"_LINK",4);
	table_array[table_array.length-1].rows[16].setSpec(200);
	table_array[table_array.length-1].rows[16].setFormInput(0);
	table_array[table_array.length-1].rows[16].setFI_path("private/form/template/inputGeneric.tpl");
	table_array[table_array.length-1].rows[16].setFI_type("text");
	table_array[table_array.length-1].rows[16].setFI_name("link");
	table_array[table_array.length-1].rows[16].setFI_dbfield("`$dbprefix`LINK");
	table_array[table_array.length-1].rows[16].setFI_title("Web Link");
	table_array[table_array.length-1].rows[16].setFI_bubble("add an internet page link to this information");
	
	table_array[table_array.length-1].addRow(Udbprefix+"_GPX",4);
	table_array[table_array.length-1].rows[17].setSpec(80);
	table_array[table_array.length-1].rows[17].setFormInput(0);
	table_array[table_array.length-1].rows[17].setFI_path("private/form/template/inputGeneric.tpl");
	table_array[table_array.length-1].rows[17].setFI_type("file");
	table_array[table_array.length-1].rows[17].setFI_name("kmlpath");
	table_array[table_array.length-1].rows[17].setFI_dbfield("`$dbprefix`GPX");
	table_array[table_array.length-1].rows[17].setFI_title("Link a GPX or KML file:");
	table_array[table_array.length-1].rows[17].setFI_size("40");
	table_array[table_array.length-1].rows[17].setFI_bubble("import a file from your GPS unit or your google earth software");
	table_array[table_array.length-1].rows[17].setFI_xplaintxt("(2Mb max.)");
	
	table_array[table_array.length-1].addRow(Udbprefix+"_GROUPID",0);
	table_array[table_array.length-1].rows[18].setFormInput(5);
	table_array[table_array.length-1].rows[18].setFI_path("private/form/template/inputGroupID.tpl");
	
	table_array[table_array.length-1].addRow(Udbprefix+"_KEYWORDS",4);
	table_array[table_array.length-1].rows[19].setSpec(150);
	table_array[table_array.length-1].rows[19].setFormInput(0);
	table_array[table_array.length-1].rows[19].setFI_path("private/form/template/inputGeneric.tpl");
	table_array[table_array.length-1].rows[19].setFI_type("text");
	table_array[table_array.length-1].rows[19].setFI_name("keywords");
	table_array[table_array.length-1].rows[19].setFI_dbfield("`$dbprefix`KEYWORDS");
	table_array[table_array.length-1].rows[19].setFI_size("40");
	table_array[table_array.length-1].rows[19].setFI_title("List of Keywords (Space seperated list of words)");
	table_array[table_array.length-1].rows[19].setFI_bubble("this helps our search engine to find your data");
	table_array[table_array.length-1].rows[19].setFI_xplaintxt("Helps our search engine find your data.");
	
	table_array[table_array.length-1].addRow("TIMESTAMP",11);
	table_array[table_array.length-1].rows[20].setNN();
	table_array[table_array.length-1].rows[20].setDef("CURRENT_TIMESTAMP");
	table_array[table_array.length-1].rows[20].setFormInput(13);
}
function TableAdmin_delTable() {
	if (!this.table_ref) { return; }
	var title = this.table_ref._title.innerHTML;
	if (!confirm("Really delete table '"+title+"' ?")) { return; }
	remove_table(this.table_ref.number);
}

function TableAdmin_changeName() {
	
	this.table_ref.setTitle(this._input.value);
	this.table_ref.updateWidth();
}

function TableAdmin_manageTable(table) {
	this.table_ref = table;
	this._input.removeAttribute("disabled");
	this._input.value = table._title.innerHTML;
}

function TableAdmin_loseTable() {
	this.table_ref = null;
	this._input.setAttribute("disabled","true");
	this._input.value = "[no table selected]";
}

function getLateFunc(obj, methodName) {
	return (function() {
			return obj[methodName](this);
	});
}

function TableAdmin() {
	this.manageTable = TableAdmin_manageTable;
	this.loseTable = TableAdmin_loseTable;
	this.changeName = TableAdmin_changeName;
	this.addTable = TableAdmin_addTable;
	this.addOpalTheme = TableAdmin_addOpalTheme;
	this.delTable = TableAdmin_delTable;
	this.last_number = 0; /* pro automaticke cislovani tabulek */
	this.table_ref = null; /* odkaz na prave vybranou tabulku */
	this._div = document.getElementById("table_admin"); /* cela cast baru pro tabulky */
	this._movebutton = document.getElementById("table_move_button");
	this._clearbutton = document.getElementById("table_clear_button");
	this._addbutton = document.getElementById("table_add_button");
	this._delbutton = document.getElementById("table_del_button");
	this._addtheme = document.getElementById("table_add_theme");
	this._input = document.getElementById("table_name");
	this._div.setAttribute("element_type",TYPE_BAR);
	this._addbutton.setAttribute("element_type",TYPE_BAR);
	this._addtheme.setAttribute("element_type",TYPE_BAR);
	this._delbutton.setAttribute("element_type",TYPE_BAR);
	this._input.setAttribute("element_type",TYPE_BAR);
	this._movebutton.setAttribute("element_type",TYPE_BAR);
	this._clearbutton.setAttribute("element_type",TYPE_BAR);
	
	universalAttacher(this._addbutton,"click",getLateFunc(this,"addTable"));
	universalAttacher(this._addtheme,"click",getLateFunc(this,"addOpalTheme"));
	universalAttacher(this._delbutton,"click",getLateFunc(this,"delTable"));
	universalAttacher(this._input,"keyup",getLateFunc(this,"changeName"));
	universalAttacher(this._movebutton,"click",reposition_tables);
	universalAttacher(this._clearbutton,"click",clear_tables);

	this.loseTable();
}

/*
	objekt RowAdmin:
		cudliky na pridani a smazani radek, resp. budoucich sloupcu
		changeName() - zmena nazvu
		manageTable, loseTable() - vybrani a odvybrani tabulky
		manageRow, loseRow() - vybrani a odvybrani radku
		addRow, delRow() - zruseni a vytvoreni radku
		upRow, downRow() - presun nahoru a dolu
*/

function RowAdmin_upRow() {
	var div = this.row_ref._div;
	var root = div.parentNode;
	var prev = div.previousSibling;
	if (prev) {
		root.insertBefore(div,prev);
		var idx = prev.getAttribute("row_number");
		this.row_ref.updateRelations();
		this.table_ref.rows[idx].updateRelations();
	}
}

function RowAdmin_downRow() {
	var div = this.row_ref._div;
	var root = div.parentNode;
	var next = div.nextSibling;
	if (next) {
		root.insertBefore(next,div);
		var idx = next.getAttribute("row_number");
		this.row_ref.updateRelations();
		this.table_ref.rows[idx].updateRelations();
	}
}

function RowAdmin_addRow() {
	if (!this.table_ref) { return; }
	var row = this.table_ref.addRow("row",4,null,4);
	row.setNN();
	row.setSpec(32);
	this.manageRow(row);
	if (this.table_ref.selectedRow) {
		this.table_ref.selectedRow.deselect();
	}
	this.table_ref.selectedRow = row;
	row.select();
}

function RowAdmin_delRow() {
	if (!this.row_ref) { return; }
	var title = this.row_ref._title.innerHTML;
	var title2 = this.table_ref._title.innerHTML;
	if (!confirm("Really delete row '"+title+"' from table '"+title2+"' ?")) { return; }
	var index = parseInt(this.row_ref._div.getAttribute("row_number"));
	var last_row = this.table_ref.removeRow(index);
	if (last_row) {
		this.manageRow(last_row); 
	} else {
		this.loseRow();
	}

}

function RowAdmin_changeName() {
	this.row_ref.setTitle(this._input.value);
	this.table_ref.updateWidth();
	this.row_ref.updateTitle();
}

function RowAdmin_changeDef() {
	this.row_ref.setDef(this._def.value);
}

function RowAdmin_changeSpec() {
	this.row_ref.setSpec(this._spec.value);
}

function RowAdmin_manageTable(table) {
	var num=-1;
	if (this.table_ref) {
		num = this.table_ref.number;
	}
	if (num != table.number) {
		/* pokud jsme vybrali nejakou, ktera predtim nebyla vybrana */
		this.loseRow();
		this.table_ref = table; /* reference na tabulku */
		this._input.value = "[no row selected]";
	}
	this._addbutton.style.color = BUTTON_ENABLED;
	this._delbutton.style.color = BUTTON_ENABLED;
}

function RowAdmin_loseTable(table) {
	/* ztratili jsme tabulku */
	this.loseRow();
	this.table_ref = null;
	this._addbutton.style.color = BUTTON_DISABLED;
	this._delbutton.style.color = BUTTON_DISABLED;
	this._upbutton.style.color = BUTTON_DISABLED;
	this._downbutton.style.color = BUTTON_DISABLED;
	this._input.value = "[no table selected]";

}

function RowAdmin_manageRow(row) {
	/* nekdo klikl na radek */
	this.row_ref = row;
	this._upbutton.style.color = BUTTON_ENABLED;
	this._downbutton.style.color = BUTTON_ENABLED;
	this._input.removeAttribute("disabled");
	this._pk.removeAttribute("disabled");
	this._index.removeAttribute("disabled");
	this._nn.removeAttribute("disabled");
	this._def.removeAttribute("disabled");
	this._type.removeAttribute("disabled");
	
	this._forminput.removeAttribute("disabled");
	this._fi_path.removeAttribute("disabled");
	this._fi_type.removeAttribute("disabled");
	this._fi_name.removeAttribute("disabled");
	this._fi_dbfield.removeAttribute("disabled");
	this._fi_title.removeAttribute("disabled");
	this._fi_value.removeAttribute("disabled");
	this._fi_nolayout.removeAttribute("disabled");
	this._fi_size.removeAttribute("disabled");
	this._fi_maxlength.removeAttribute("disabled");
	this._fi_mandatory.removeAttribute("disabled");
	this._fi_bubble.removeAttribute("disabled");
	this._fi_xplaintxt.removeAttribute("disabled");
	this._fi_attribute.removeAttribute("disabled");
	this._fi_optionVal.removeAttribute("disabled");
	this._fi_optionLbl.removeAttribute("disabled");
	this._fi_optionSel.removeAttribute("disabled");
	
	this._input.value = row._title.innerHTML;
	this._pk.checked = (row.pk ? true : false);
	this._index.checked = (row.index ? true : false);
	this._nn.checked = (row.nn ? true : false);
	this._def.value = row.def;
	this._type.selectedIndex = row.type;
	this._spec.value = row.spec;
	if (SQL_TYPES_SPEC[row.type]) {
		this._spec.removeAttribute("disabled");
	} else {
		this._spec.setAttribute("disabled","true");
	}
	if (row.pk) {
		this._index.setAttribute("disabled","true");
	}
	this._forminput.selectedIndex = row.forminput;
	this._fi_path.value = row.fi_path;
	this._fi_type.value = row.fi_type;
	this._fi_name.value = row.fi_name;
	this._fi_dbfield.value = row.fi_dbfield;
	this._fi_title.value = row.fi_title;
	this._fi_value.value = row.fi_value;
	this._fi_nolayout.checked = row.fi_nolayout;
	this._fi_size.value = row.fi_size;
	this._fi_maxlength.value = row.fi_maxlength;
	this._fi_mandatory.checked = row.fi_mandatory;
	this._fi_bubble.value = row.fi_bubble;
	this._fi_xplaintxt.value = row.fi_xplaintxt;
	this._fi_attribute.value = row.fi_attribute;
	this._fi_optionVal.value = row.fi_optionVal;
	this._fi_optionLbl.value = row.fi_optionLbl;
	this._fi_optionSel.value = row.fi_optionSel;
}

function RowAdmin_loseRow() {
	this.row_ref = null;
	this._upbutton.style.color = BUTTON_DISABLED;
	this._downbutton.style.color = BUTTON_DISABLED;
	this._input.setAttribute("disabled","true");
	this._pk.setAttribute("disabled","true");
	this._index.setAttribute("disabled","true");
	this._nn.setAttribute("disabled","true");
	this._def.setAttribute("disabled","true");
	this._type.setAttribute("disabled","true");
	this._spec.setAttribute("disabled","true");
	this._input.value = "[no row selected]";
	
	this._forminput.setAttribute("disabled","true");
	this._fi_path.setAttribute("disabled","true");
	this._fi_type.setAttribute("disabled","true");
	this._fi_name.setAttribute("disabled","true");
	this._fi_dbfield.setAttribute("disabled","true");
	this._fi_title.setAttribute("disabled","true");
	this._fi_value.setAttribute("disabled","true");
	this._fi_nolayout.setAttribute("disabled","true");
	this._fi_size.setAttribute("disabled","true");
	this._fi_maxlength.setAttribute("disabled","true");
	this._fi_mandatory.setAttribute("disabled","true");
	this._fi_bubble.setAttribute("disabled","true");
	this._fi_xplaintxt.setAttribute("disabled","true");
	this._fi_attribute.setAttribute("disabled","true");
	this._fi_optionVal.setAttribute("disabled","true");
	this._fi_optionLbl.setAttribute("disabled","true");
	this._fi_optionSel.setAttribute("disabled","true");
}

function RowAdmin_setPK() {
	/* primary key */
	if (!this.row_ref) { return; }
	var index = parseInt(this.row_ref._div.getAttribute("row_number"));
	this.table_ref.setPK(index);
	this._pk.checked = true;
	this._index.checked = true;
	this._index.setAttribute("disabled","true");	
}

function RowAdmin_changeType() {
	/* zmena typu */
	if (!this.row_ref) { return; }
	this.row_ref.setType(this._type.selectedIndex);
	//set the corresponding forminput for this sql type
	this._forminput.selectedIndex = SQLINPUT_TYPES_VALUES[this.row_ref.type];
	this.row_ref.setFormInput(this._forminput.selectedIndex);
	this._def.value = this.row_ref.def;
	if (SQL_TYPES_SPEC[this.row_ref.type]) {
		this._spec.removeAttribute("disabled");
	} else {
		this._spec.setAttribute("disabled","true");
	}
}

function RowAdmin_changeFormInput() {
	/* zmena typu */
	if (!this.row_ref) { return; }
	this.row_ref.setFormInput(this._forminput.selectedIndex);
	/*if (INPUT_TYPES_SPEC[this.row_ref.forminput]) {
		this._forminputspec.removeAttribute("disabled");
	} else {
		this._forminputspec.setAttribute("disabled","true");
	}*/
}

function RowAdmin_changeFI_path() {this.row_ref.setFI_path(this._fi_path.value);}
function RowAdmin_changeFI_type() {this.row_ref.setFI_type(this._fi_type.value);}
function RowAdmin_changeFI_name() {this.row_ref.setFI_name(this._fi_name.value);}
function RowAdmin_changeFI_dbfield() {this.row_ref.setFI_dbfield(this._fi_dbfield.value);}
function RowAdmin_changeFI_title() {this.row_ref.setFI_title(this._fi_title.value);}
function RowAdmin_changeFI_value() {this.row_ref.setFI_value(this._fi_value.value);}
function RowAdmin_changeFI_nolayout() {this.row_ref.setFI_nolayout(this._fi_nolayout.value);}
function RowAdmin_changeFI_size() {this.row_ref.setFI_size(this._fi_size.value);}
function RowAdmin_changeFI_maxlength() {this.row_ref.setFI_maxlength(this._fi_maxlength.value);}
function RowAdmin_changeFI_mandatory() {this.row_ref.setFI_mandatory(this._fi_mandatory.value);}
function RowAdmin_changeFI_bubble() {this.row_ref.setFI_bubble(this._fi_bubble.value);}
function RowAdmin_changeFI_xplaintxt() {this.row_ref.setFI_xplaintxt(this._fi_xplaintxt.value);}
function RowAdmin_changeFI_attribute() {this.row_ref.setFI_attribute(this._fi_attribute.value);}
function RowAdmin_changeFI_optionVal() {this.row_ref.setFI_optionVal(this._fi_optionVal.value);}
function RowAdmin_changeFI_optionLbl() {this.row_ref.setFI_optionLbl(this._fi_optionLbl.value);}
function RowAdmin_changeFI_optionSel() {this.row_ref.setFI_optionSel(this._fi_optionSel.value);}

function RowAdmin_changeIndex() {
	/* zmena index on/off */
	if (!this.row_ref) { return; }
	if (this.row_ref.index) {
		this.row_ref.loseIndex();
	} else {
		this.row_ref.setIndex();
	}
}

function RowAdmin_changeNN() {
	/* zmena index on/off */
	if (!this.row_ref) { return; }
	if (this.row_ref.nn) {
		this.row_ref.loseNN();
	} else {
		this.row_ref.setNN();
	}
}

function RowAdmin() {
	this.manageRow = RowAdmin_manageRow;
	this.loseRow = RowAdmin_loseRow;
	this.changeName = RowAdmin_changeName;
	this.changeSpec = RowAdmin_changeSpec;
	this.changeDef = RowAdmin_changeDef;
	this.addRow = RowAdmin_addRow;
	this.delRow = RowAdmin_delRow;
	this.upRow = RowAdmin_upRow;
	this.downRow = RowAdmin_downRow;
	this.manageTable = RowAdmin_manageTable;
	this.loseTable = RowAdmin_loseTable;
	this.setPK = RowAdmin_setPK;
	this.changeType = RowAdmin_changeType;
	this.changeIndex = RowAdmin_changeIndex;
	this.changeNN = RowAdmin_changeNN;
	
	this.changeFormInput = RowAdmin_changeFormInput;
	this.changeFI_path = RowAdmin_changeFI_path;
	this.changeFI_type = RowAdmin_changeFI_type;
	this.changeFI_name = RowAdmin_changeFI_name;
	this.changeFI_dbfield = RowAdmin_changeFI_dbfield;
	this.changeFI_title = RowAdmin_changeFI_title;
	this.changeFI_value = RowAdmin_changeFI_value;
	this.changeFI_nolayout = RowAdmin_changeFI_nolayout;
	this.changeFI_size = RowAdmin_changeFI_size;
	this.changeFI_maxlength = RowAdmin_changeFI_maxlength;
	this.changeFI_mandatory = RowAdmin_changeFI_mandatory;
	this.changeFI_bubble = RowAdmin_changeFI_bubble;
	this.changeFI_xplaintxt = RowAdmin_changeFI_xplaintxt;
	this.changeFI_attribute = RowAdmin_changeFI_attribute;
	this.changeFI_optionVal = RowAdmin_changeFI_optionVal;
	this.changeFI_optionLbl = RowAdmin_changeFI_optionLbl;
	this.changeFI_optionSel = RowAdmin_changeFI_optionSel;
	
	this.last_number = 0; /* pro automaticke cislovani tabulek */
	this.table_ref = null; /* odkaz na prave vybranou tabulku */
	this.row_ref = null; /* odkaz na prave vybranou radku */
	this._div = document.getElementById("row_admin"); /* cela cast baru pro tabulky */
	this._addbutton = document.getElementById("row_add_button");
	this._delbutton = document.getElementById("row_del_button")
	this._upbutton = document.getElementById("row_up_button")
	this._downbutton = document.getElementById("row_down_button")
	this._input = document.getElementById("row_name");
	this._pk = document.getElementById("row_primary");
	this._nn = document.getElementById("row_notnull");
	this._index = document.getElementById("row_index");
	this._def = document.getElementById("row_default");
	this._type = document.getElementById("row_type");
	this._spec = document.getElementById("row_spec");
	/*form input elements*/
	this._forminput = document.getElementById("row_input");
	this._fi_path = document.getElementById("row_inputpath");
	this._fi_type = document.getElementById("row_inputtype");
	this._fi_name = document.getElementById("row_inputname");
	this._fi_dbfield = document.getElementById("row_dbfield");
	this._fi_title = document.getElementById("row_inputtitle");
	this._fi_value = document.getElementById("row_inputvalue");
	this._fi_nolayout = document.getElementById("row_inputnolayout");
	this._fi_size = document.getElementById("row_inputsize");
	this._fi_maxlength = document.getElementById("row_inputmaxlength");
	this._fi_mandatory = document.getElementById("row_inputmandatory");
	this._fi_bubble = document.getElementById("row_inputbubble");
	this._fi_xplaintxt = document.getElementById("row_inputxplaintxt");
	this._fi_attribute = document.getElementById("row_inputattribute");
	this._fi_optionVal = document.getElementById("row_inputoptionVal");
	this._fi_optionLbl = document.getElementById("row_inputoptionLbl");
	this._fi_optionSel = document.getElementById("row_inputoptionSel");
	
	this._div.setAttribute("element_type",TYPE_BAR);
	this._addbutton.setAttribute("element_type",TYPE_BAR);
	this._delbutton.setAttribute("element_type",TYPE_BAR);
	this._upbutton.setAttribute("element_type",TYPE_BAR);
	this._downbutton.setAttribute("element_type",TYPE_BAR);
	this._input.setAttribute("element_type",TYPE_BAR);
	this._pk.setAttribute("element_type",TYPE_BAR);
	this._nn.setAttribute("element_type",TYPE_BAR);
	this._index.setAttribute("element_type",TYPE_BAR);
	this._def.setAttribute("element_type",TYPE_BAR);
	this._type.setAttribute("element_type",TYPE_BAR);
	this._spec.setAttribute("element_type",TYPE_BAR);

	this._forminput.setAttribute("element_type",TYPE_BAR);
	this._fi_path.setAttribute("element_type",TYPE_BAR);
	this._fi_type.setAttribute("element_type",TYPE_BAR);
	this._fi_name.setAttribute("element_type",TYPE_BAR);
	this._fi_dbfield.setAttribute("element_type",TYPE_BAR);
	this._fi_title.setAttribute("element_type",TYPE_BAR);
	this._fi_value.setAttribute("element_type",TYPE_BAR);
	this._fi_nolayout.setAttribute("element_type",TYPE_BAR);
	this._fi_size.setAttribute("element_type",TYPE_BAR);
	this._fi_maxlength.setAttribute("element_type",TYPE_BAR);
	this._fi_mandatory.setAttribute("element_type",TYPE_BAR);
	this._fi_bubble.setAttribute("element_type",TYPE_BAR);
	this._fi_xplaintxt.setAttribute("element_type",TYPE_BAR);
	this._fi_attribute.setAttribute("element_type",TYPE_BAR);
	this._fi_optionVal.setAttribute("element_type",TYPE_BAR);
	this._fi_optionLbl.setAttribute("element_type",TYPE_BAR);
	this._fi_optionSel.setAttribute("element_type",TYPE_BAR);
	
	universalAttacher(this._addbutton,"click",getLateFunc(this,"addRow"));
	universalAttacher(this._addbutton,"click",getLateFunc(this,"addOpalTheme"));
	universalAttacher(this._delbutton,"click",getLateFunc(this,"delRow"));
	universalAttacher(this._upbutton,"click",getLateFunc(this,"upRow"));
	universalAttacher(this._downbutton,"click",getLateFunc(this,"downRow"));
	universalAttacher(this._input,"keyup",getLateFunc(this,"changeName"));
	universalAttacher(this._def,"keyup",getLateFunc(this,"changeDef"));
	universalAttacher(this._spec,"keyup",getLateFunc(this,"changeSpec"));
	universalAttacher(this._pk,"click",getLateFunc(this,"setPK"));
	universalAttacher(this._type,"change",getLateFunc(this,"changeType"));
	universalAttacher(this._index,"click",getLateFunc(this,"changeIndex"));
	universalAttacher(this._nn,"click",getLateFunc(this,"changeNN"));
	
	universalAttacher(this._forminput,"change",getLateFunc(this,"changeFormInput"));
	universalAttacher(this._fi_path,"change",getLateFunc(this,"changeFI_path"));
	universalAttacher(this._fi_type,"change",getLateFunc(this,"changeFI_type"));
	universalAttacher(this._fi_name,"change",getLateFunc(this,"changeFI_name"));
	universalAttacher(this._fi_dbfield,"change",getLateFunc(this,"changeFI_dbfield"));
	universalAttacher(this._fi_title,"change",getLateFunc(this,"changeFI_title"));
	universalAttacher(this._fi_value,"change",getLateFunc(this,"changeFI_value"));
	universalAttacher(this._fi_nolayout,"change",getLateFunc(this,"changeFI_nolayout"));
	universalAttacher(this._fi_size,"change",getLateFunc(this,"changeFI_size"));
	universalAttacher(this._fi_maxlength,"change",getLateFunc(this,"changeFI_maxlength"));
	universalAttacher(this._fi_mandatory,"change",getLateFunc(this,"changeFI_mandatory"));
	universalAttacher(this._fi_bubble,"change",getLateFunc(this,"changeFI_bubble"));
	universalAttacher(this._fi_xplaintxt,"change",getLateFunc(this,"changeFI_xplaintxt"));
	universalAttacher(this._fi_attribute,"change",getLateFunc(this,"changeFI_attribute"));
	universalAttacher(this._fi_optionVal,"change",getLateFunc(this,"changeFI_optionVal"));
	universalAttacher(this._fi_optionLbl,"change",getLateFunc(this,"changeFI_optionLbl"));
	universalAttacher(this._fi_optionSel,"change",getLateFunc(this,"changeFI_optionSel"));
	
	this.loseRow();
}


function apply_xslt(data, xslt) {
	if (document.implementation && document.implementation.createDocument) {	
		
		var xsl_data = document.implementation.createDocument("", "", null);
		xsl_data.async = false;
		xsl_data.load(xslt);
		var xsl = new XSLTProcessor();
		xsl.importStylesheet(xsl_data);

		var parser = new DOMParser();
		var xml = parser.parseFromString(data, "text/xml");
		var result = xsl.transformToDocument(xml);
		alert(result.getElementById("body").hasChildNodes());		
		return result.getElementById("body").innerHTML;		
	} else if (window.ActiveXObject) {
		var xml = new ActiveXObject("Microsoft.XMLDOM");
		xml.async = false;
		xml.loadXML(data);
		var xsl = new ActiveXObject("Microsoft.XMLDOM")
		xsl.async = false;
		xsl.load(xslt);
		var result = xml.transformNode(xsl);
		return result.replace(/<html>|<\/html>|<body id="body">|<\/body>/g,"");
	} else {
		alert("Ooops - no XML parser available");
	}
}

function unescape(data){
data = data.replace(/&lt;/g,"<");
data = data.replace(/&gt;/g,">");
return data;
}


function IOAdmin_go() {
	switch (this._select.value) {
		case "xml_in": /* import xml */
			io_show(true);
		break;
		
		case "xml_in_xml": /* import xml using browser xml functionalities */
			ajax_command(GET,"xml_basecode.php",function(){return true},import_xml2,true);
		break;
		
		case "xml_out": /* export xml */
			io_show(false);
			var data = export_xml();
			var area = document.getElementById("area");
			area.value = data;
			area.select();
		break;

		case "db_in": /* load from db */
			var key = prompt("Keyword:","");
			if (!key) return;
			ajax_command(GET,"io.php?import=import&key="+encodeURIComponent(key),function(){return true},import_xml2);
		break;

		case "db_out": /* save do db */
			var key = prompt("Keyword:","");
			if (!key) return;
			var in_ref = function() {
				var out = "";
				out += "key="+encodeURIComponent(key);
				out += "&data="+encodeURIComponent(export_xml());
				return out;
			}
			var out_ref = function(data) {
				alert("Data stored, keyword='"+key+"'");
			}
			ajax_command(POST,"io.php",in_ref,out_ref);
		break;

		/**********  CODE BEGIN  **********/

		case "show_keywords": /* Show keywords */
			var out_ref = function(data) {
				io_show(false);
				var area = document.getElementById("area");			
				area.value = data;	
			}
			ajax_command(GET,"io.php?show=show",function(){return true},out_ref);
		break;

		case "print_view": /* Open print view */
			print_view();
		break;

		/**********  CODE END  **********/

		case "mysql": /* xslt to mysql */
			io_show(false);
			var data = export_xml();
			data = apply_xslt(data,"xml2mysql.xsl");
			if(confirm("should this file be saved in openatlas/DB/tables/"))
				alert("ajax save to DB " + data);
			else {
				var area = document.getElementById("area");
				area.value = data;
				area.select();
			}
		break;
		
		case "mssql": /* xslt to mssql */
			io_show(false);
			var data = export_xml();
			data = apply_xslt(data,"xml2mssql.xsl");
			var area = document.getElementById("area");
			area.value = data;
			area.select();
		break;
		
		case "postgresql": /* xslt to mssql */
			io_show(false);
			var data = export_xml();
			data = apply_xslt(data,"xml2postgresql.xsl");
			var area = document.getElementById("area");
			area.value = data;
			area.select();
		break;

		case "db_import": /* get schema from real database */
			ajax_command(GET,"import.php",function(){return true},import_xml);
		break;
		
		case "add_script": /*Generates opal insert and update code for this table*/
			io_show(false);
			var data = export_xml();
			data = apply_xslt(data,"xml2addscript.xsl");
			var area = document.getElementById("area");
			area.value = data;
			area.select();
		break;
		
		case "map_HTML": /*Generates map HTML for this table's data*/
			io_show(false);
			var data = export_xml();
			data = apply_xslt(data,"xml2mapHTML.xsl");
			data = unescape(data);
			var area = document.getElementById("area");
			area.value = data;
			area.select();
		break;
		
		case "list_HTML": /*Generates list HTML for this table's data*/
			io_show(false);
			var data = export_xml();
			data = apply_xslt(data,"xml2listHTML.xsl");
			data = unescape(data);
			var area = document.getElementById("area");
			area.value = data;
			area.select();
		break;
		
		case "smarty_prepare": /*Generates php code preparing Smarty data for this table's data*/
			io_show(false);
			var data = export_xml();
			data = apply_xslt(data,"xml2opal_smartyPrepareGeneratedTheme.xsl");
			data = unescape(data);
			var area = document.getElementById("area");
			area.value = data;
			area.select();
		break;
		
		case "smarty_Form": /*Generates smarty code for the Form of this table*/
			io_show(false);
			var data = export_xml();
			data = apply_xslt(data,"xml2opal_smartyFormGeneratedTheme.xsl");
			data = unescape(data);
			var area = document.getElementById("area");
			area.value = data;
			area.select();
		break;
	} /* switch */
}

function IOAdmin_load() {
	var area = document.getElementById("area");
	var data = area.value;
	import_xml(data);
	var io = document.getElementById("io");
	io.style.display = "none";
	area.value = "";
}

function IOAdmin() {

	this.go = IOAdmin_go;
	this.load = IOAdmin_load;

	this._div = document.getElementById("io_admin"); /* cela cast baru pro tabulky */
	this._button = document.getElementById("io_button");
	this._settingsbutton = document.getElementById("io_settings_button");
	this._select = document.getElementById("io_select");
	this._import = document.getElementById("import");

	this._div.setAttribute("element_type",TYPE_BAR);
	this._button.setAttribute("element_type",TYPE_BAR);
	this._settingsbutton.setAttribute("element_type",TYPE_BAR);
	this._select.setAttribute("element_type",TYPE_BAR);
	this._import.setAttribute("element_type",TYPE_BAR);
	
	var tmp = document.getElementById("close");
	tmp.setAttribute("element_type",TYPE_BAR);
	tmp = document.getElementById("io");
	tmp.setAttribute("element_type",TYPE_BAR);
	tmp = document.getElementById("area");
	tmp.setAttribute("element_type",TYPE_BAR);
	
	universalAttacher(this._button,"click",getLateFunc(this,"go"));
/*	universalAttacher(this._settingsbutton,"click",getLateFunc(this,"exp")); */
	universalAttacher(this._import,"click",getLateFunc(this,"load"));
}