/***************************************************************************************************
 *	Texyla
 *  Version:            0.4.2.1
 *  Latest update: 		14. srpna 2007 10:13
 ***************************************************************************************************
 *  Encoding:           UTF-8
 ***************************************************************************************************
 *	Vytvořil: 			Jan Marek
 *						Petr Vaněk aka krteczek
 *						Lukáš Voda
 *
 *	Web: 				http://texyla.jaknato.com
 *
 *  Licence:            Texyla je k dispozici pod GPL licencí
 *  					(její český překlad naleznete v souboru gpl.cs.html)
 *
 *  Tento program je volný software; můžete jej šířit a modifikovat podle
 *  ustanovení Obecné veřejné licence GNU, vydávané Free Software
 *  Foundation; a to buď verze 2 této licence anebo (podle vašeho uvážení)
 *  kterékoli pozdější verze.
 *
 *  Tento program je rozšiřován v naději, že bude užitečný, avšak BEZ
 *  JAKÉKOLI ZÁRUKY; neposkytují se ani odvozené záruky PRODEJNOSTI anebo
 *  VHODNOSTI PRO URČITÝ ÚČEL. Další podrobnosti hledejte ve Obecné
 *  veřejné licenci GNU.
 *
 *  Kopii Obecné veřejné licence GNU jste měl obdržet spolu s tímto
 *  programem; pokud se tak nestalo, napište o ni Free Software Foundation,
 *  Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 **************************************************************************************************/

// Konstruktor
function Texyla (options) {
	// Nastavení
	this.options = options;
	
	// Buď najdeme textareu podle ID, nebo již máme objekt Textarea
	this.textarea = typeof(options.textarea) === 'string' ? document.getElementById(options.textarea) : options.textarea;
	
	// Tlačítková lišta: string -> vybere z přednastavených, objekt -> uživatelská lišta
	this.options.toolbar = typeof(options.toolbar) === "string" ? Texyla.toolbars[options.toolbar] : options.toolbar;
	
	// smajlíky: string -> vybere z přednastavených, objekt -> uživatelské smajly
	this.options.emoticons = typeof(options.emoticons) === 'string' ? Texyla.emoticons[options.emoticons] : options.emoticons;
	
	// Addresy
	this.addr = options.addr;
	// přidá k adrese složky smajlíků složku konkrétního typu smajlů
	this.addr.emoticons += this.options.emoticons.folder;
	
	// Zjistí Internet Explorer
	this.IE = this.isIE();
	
	// Zařídí, aby Texyly neměly společné podobjekty
	this.Buttons = this.Buttons(this);
	this.Texy = this.Texy();
	this.Dom = this.Dom();
	this.View = this.View();
	this.Windows = this.Windows();
	
	// Vytvoří v podobjektech odkaz na hlavní objekt Texyly
	this.Dom.Texyla = this;
	this.View.Texyla = this;
	this.Texy.Texyla = this;
	this.Windows.Texyla = this;
	this.Windows.img.Texyla = this;
	this.Windows.table.Texyla = this;
	this.Windows.emoticon.Texyla = this;
	
	// Spustí texylovatění
	this.Dom.init();
};

// Funkce pro zjištění umístění adresáře s texylou
Texyla.getAddrBase = function () {
	var scripts = document.getElementsByTagName("head")[0].getElementsByTagName("script");
	var src = scripts[scripts.length - 1].src;
	var file = /\/[\w-]+\.js$/;
	var addrBase = src.replace(file, '') + '/';
	
	return addrBase;
};

// Umístění adresáře s Texylou
Texyla.addrBase = Texyla.getAddrBase();

// Nastavení - konfigurátor
Texyla.configurator = {
	// Společné základní nastavení
	defaultCfg: function(textarea) {	
		return {
			// Textarea do které se vkládá Texy
			textarea: textarea,
			
			// Lišta
			toolbar: null,
			
			// Povolit náhled HTML kódu
			allowHtmlPreview: true,
			
			// Typ ikonek - silk | old
			iconType: 'silk',
			
			// Formát ikonek - silk -> png, old -> gif
			iconFormat: 'png',
			
			// Vzhled (default | win_xp)
			theme: 'default',
			
			// Hezký vzhled tlačítek
			coolButtons: true,
			
			// 'auto' -> zachová původní šířku | číslo -> šířka editoru v pixelech
			editorWidth: 'auto',
			
			// odsazení textarey
			textareaMargin: 6,
			
			// Funkce, která se volá při odpovědi na XHR, vrací string - HTML
			AjaxProcessor: null,
			
			// Funkce, která modifikuje nastavení XHR
			AjaxPreProcessor: null,
			
			// Konfigurace Texy, dostupné jsou: admin, forum, oneline
			texyCfg: null,
			
			// smajlíky
			emoticons: 'texy',
			
			// adresáře
			addr: {
				// témata vzhledů
				css: Texyla.addrBase + 'themes/',
				// ikonky tlačítek apod.
				icons: Texyla.addrBase + 'icons/',
				// smajlíky
				emoticons: Texyla.addrBase + 'emoticons/',
				// náhled
				ajax: Texyla.addrBase + 'texyla.php'
			},
			
			// Odeslat formulář po klávesové zkratce
			submitOnCtrlS: true
		};
	},
	
	// nastavení pro administrační rozhraní
	admin: function(textarea) {
		// základ
		var options = Texyla.configurator.defaultCfg(textarea);
		
		// lišta admin
		options.toolbar = 'admin';
		// konfigurák Texy: admin
		options.texyCfg = 'admin';
		
		return options;
	},
	
	// nastavení pro fóra
	forum: function(textarea) {
		// základ
		var options = Texyla.configurator.defaultCfg(textarea);
		
		// lišta fórum
		options.toolbar = 'forum';
		// zakáže HTML náhled
		options.allowHtmlPreview = false;
		// konfigurák Texy: forum
		options.texyCfg = 'forum';
		// zakáže odeslání formuláře po klávesové zkratce
		options.submitOnCtrlS = false;
		
		return options;
	}
};

// Lišty pro Texylu
Texyla.toolbars = {
	// admin lišta
	admin: [
		'h1', 'h2', 'h3', 'h4',
		null,
		'bold', 'italic',
		null,
		'center', ['left', 'right', 'justify'],
		null,
		'ul', 'ol',
		null,
		'sup', 'sub',
		null,
		'link', 'img', 'table', 'emoticon',
		null,
		['del', 'blockquote', 'acronym', 'hr', 'code', 'inlineCode', 'html', 'notexy', 'web']
	],
	// forum lišta
	forum: [
		'bold', 'italic', null, 'ul', 'ol', null, 'link', null, 'emoticon', null, ['web']
	]
};

// smajlíky
Texyla.emoticons = {
	// texy smajlíky, výchozí
	texy: {
		// složka
		folder: 'texy/',
		// formát souborů
		format: 'gif',
		// šířka
		width: 15,
		// výška
		height: 15,
		// seznam ikonek
		icons: {
			':-)': 'smile',
			':-(': 'sad',
			';-)': 'wink',
			':-D': 'biggrin',
			'8-O': 'eek',
			'8-)': 'cool',
			':-?': 'confused',
			':-x': 'mad',
			':-P': 'razz',
			':-|': 'neutral'
		}
	},
	
	// silk smajlíci
	silk: {
		// složka
		folder: 'silk/',
		// formát souborů
		format: 'png',
		// šířka
		width: 16,
		// výška
		height: 16,
		// seznam ikonek
		icons: {
			':-)': 'smile',
			':-(': 'unhappy',
			';-)': 'wink',
			':-D': 'grin',
			':-O': 'surprised',
			':-P': 'tongue'
		}
	}
};

// Texty
Texyla.lng = {
	// popisy tlačítek
	btn_h1: "Největší nadpis",
	btn_h2: "Velký nadpis",
	btn_h3: "Střední nadpis",
	btn_h4: "Nejmenší nadpis",
	btn_bold: "Tučně",
	btn_italic: "Kurzíva",
	btn_del: "Přeškrtnuto",
	btn_center: "Zarovnání na střed",
	btn_left: "Zarovnání vlevo",
	btn_right: "Zarovnání vpravo",
	btn_justify: "Zarovnání do bloku",
	btn_ul: "Seznam",
	btn_ol: "Číslovaný seznam",
	btn_blockquote: "Bloková citace",
	btn_sub: "Dolní index",
	btn_sup: "Horní index",
	btn_link: "Odkaz",
	btn_img: "Obrázek",
	btn_table: "Tabulka",
	btn_acronym: "Vysvětlení zkratky",
	btn_hr: "Čára",
	btn_code: "Kód",
	btn_inlineCode: "Inline kód",
	btn_html: "Vypnutí texy (HTML)",
	btn_notexy: "Vypnutí texy (inline text)",
	btn_web: "Web editoru Texyla",
	btn_emoticon: "Smajlík",
	
	// funkce
	texy_heading_text: "Text nadpisu",
	texy_link_url: "Adresa odkazu",
	texy_acronym_title: "Titulek",
	
	// pohledy
	view_edit: "Upravit",
	view_syntax: "Texy syntaxe",
	view_wait: "Prosím čekejte",
	view_empty: "Textové pole je prázdné!",
	
	// obrázek
	img_heading: "Vložit obrázek",
	img_src: "Adresa obrázku",
	img_alt: "Popis",
	img_align: "Zarovnání",
	img_al_none: "žádné",
	img_al_left: "vlevo",
	img_al_right: "vpravo",
	img_al_center: "na střed",
	
	// tabulka
	tab_heading: "Vložit tabulku",
	tab_cols: "Počet sloupců",
	tab_rows: "Počet řádek",
	tab_th: "Hlavička",
	tab_th_none: "žádná",
	tab_th_top: "nahoře",
	tab_th_left: "vlevo",
	
	// smajlíci
	emoticon_heading: "Vložit smajlík",
	
	// okna
	win_ins: "Vložit",
	win_close: "Zavřít"
};

Texyla.prototype = {	
	// Pole, ve kterém editujeme Texy
	textarea: null,
	
	// Internet Explorer
	IE: null,
	
	isIE: function() {
		// Opera, Firefox
		if (this.textarea.selectionStart || this.textarea.selectionStart === 0) {
			return false;
			
		// IE
		} else {
			if (document.selection) {
				return true;
			}
		}
	},
	
	// Tlačítka	
	Buttons: function(_this) {
		var lng = Texyla.lng;
		return {
			// název tlačítka
				// ikonka, název, funkce
			h1:
				{icon:"h1", name:lng.btn_h1, func: function() {_this.Texy.heading('#');}},
			h2:
				{icon:"h2", name:lng.btn_h2, func: function() {_this.Texy.heading('*');}},
			h3:
				{icon:"h3", name:lng.btn_h3, func: function() {_this.Texy.heading('=');}},
			h4:
				{icon:"h4", name:lng.btn_h4, func: function() {_this.Texy.heading('-');}},
			bold:
				{icon:"bold", name:lng.btn_bold, func: function() {_this.Texy.tag('**', '**');}},
			italic:
				{icon:"italic", name:lng.btn_italic, func: function() {_this.Texy.tag('*', '*');}},
			del:
				{icon:"del", name:lng.btn_del, func: function() {_this.Texy.tag('--', '--');}},
			center:
				{icon:"center", name:lng.btn_center, func: function() {_this.Texy.align('<>');}},
			left:
				{icon:"left", name:lng.btn_left, func: function() {_this.Texy.align('<');}},
			right:
				{icon:"right", name:lng.btn_right, func: function() {_this.Texy.align('>');}},
			justify:
				{icon:"justify", name:lng.btn_justify, func: function() {_this.Texy.align('=');}},
			ul:
				{icon:"ul", name:lng.btn_ul, func: function() {_this.Texy.list('ul');}},
			ol:
				{icon:"ol", name:lng.btn_ol, func: function() {_this.Texy.list('ol');}},
			blockquote:
				{icon:"blockquote", name:lng.btn_blockquote, func: function() {_this.Texy.list('bq');}},
			sub:
				{icon:"sub", name:lng.btn_sub, func: function() {_this.Texy.tag('__', '__');}},
			sup:
				{icon:"sup", name:lng.btn_sup, func: function() {_this.Texy.tag('^^', '^^');}},
			link:
				{icon:"link", name:lng.btn_link, func: function() {_this.Texy.link();}},
			img:
				{icon:"img", name:lng.btn_img, func: function() {_this.Windows.img.open(this);}},
			table:
				{icon:"table", name:lng.btn_table, func: function() {_this.Windows.table.open(this);}},
			acronym:
				{icon:"acronym", name:lng.btn_acronym, func: function() {_this.Texy.acronym();}},
			hr:
				{icon:"hr", name:lng.btn_hr, func: function() {_this.Texy.line();}},
			code:
				{icon:"tag", name:lng.btn_code, func: function() {_this.Texy.block('code');}},
			inlineCode:
				{icon:"inline_code", name:lng.btn_inlineCode, func: function() {_this.Texy.tag('`', '`');}},
			html:
				{icon:"html", name:lng.btn_html, func: function() {_this.Texy.block('html');}},
			notexy:
				{icon:"notexy", name:lng.btn_notexy, func: function() {_this.Texy.tag("''", "''");}},
			web:
				{icon:"web", name:lng.btn_web, func: function() {window.open('http://texyla.jaknato.com/');}},
			emoticon:
				{icon:"emoticon", name:lng.btn_emoticon, func: function() {_this.Windows.emoticon.open(this);}}
		};
	},
	
	// funkce pro práci s výběrem a pro vkládání Texy
	Texy: function() {
		return {
			// oddělovač řádků
			lineFeed: '\r\n',
			// jestli jsme si jisti s formátem oddělovače řádků
			lineFeedKnown: false,
			
			/*selection: {
				txt: null,
				len: null,
				start: null,
				end: null,
				cursor: null
			}, */
			
			// obalí výběr (firstTexy + výběr + secondText)
			tag: function (firstText, secondText) {
				this.changeSelection(false, firstText, secondText);
			},
			
			// nahradí výběr proměnnou replacement
			replaceSelection: function (replacement) {
				this.changeSelection(true, replacement, null);
			},
			
			// změna výběru
			changeSelection: function (replacement, firstText, secondText) {
				this.doSelect();
				
				// Kolik je odrolováno
				var scrolled = this.Texyla.textarea.scrollTop;
				
				// Změněný text
				// replacement = true -----> vyber je nahrazen promennou firstText
				// replacement = false ----> vyber je obalen firstText a secondText
				var changedText = replacement ? firstText : (firstText + this.selection.txt + secondText);
				
				// Změna textu v textaree
				var taval = this.Texyla.textarea.value;
				this.Texyla.textarea.value = taval.substring(0, this.selection.start) + changedText + taval.substring(this.selection.end);
				
				// Vybrat
				// Pri vyberu zohlední: a) je-li vyber nahrazovan b) je-li obalen vyber ci kurzor
				var from = this.selection.start + ((replacement || !this.selection.cursor) ? 0 : firstText.length);
				var length = replacement ? firstText.length : (
					this.selection.cursor ? 0 : firstText.length + this.selection.len + secondText.length
				);
				this.select(from, length);
				
				// Odrolovat na původní pozici
				this.Texyla.textarea.scrollTop = scrolled;
			},
		
			// Funkce zjistí pravděpodobnou podobu formátu nového řádku.
			getLineFeedFormat: function() {
				if (!this.lineFeedKnown) {
					// Pokusí se ho nalézt:
					var unix = this.Texyla.textarea.value.indexOf('\n');
					var mac = this.Texyla.textarea.value.indexOf('\r');
					var win = this.Texyla.textarea.value.indexOf('\r\n');
					
					if (unix >= 0) {
						this.lineFeed = '\n';
					}
					if (mac >= 0) {
						this.lineFeed = '\r';
					}
					if (win >= 0) {
						this.lineFeed = '\r\n';
					}
					
					// V případě úspěchu nastaví proměnnou this.lineFeedKnown na true a funkce již později hledání neopakuje.
					if (unix >= 0 || mac >= 0 || win >= 0) {
						this.lineFeedKnown = true;
					}
					
					// Jinak se nový řádek nastaví provizorně podle prohlížeče.
					if (!this.lineFeedKnown) {
						// O, IE -> win
						if (document.selection) {
							this.lineFeed = '\r\n';
						// FF -> unix
						} else {
							this.lineFeed = '\n';
						}
					}
				}
			},
			
			// Ulož vlastnosti výběru
			saveSelectionProperties: function() {
				this.Texyla.textarea.focus();
				
				var start, end, selectedText, cursor;
				
				// IE
				if (this.Texyla.IE) {
					var backup = this.Texyla.textarea.value;
					
					var ieSelection = document.selection.createRange();
					var bookmark = "[~Z~A~L~O~Z~K~A~]";
					selectedText = ieSelection.text;
					
					ieSelection.text = bookmark + selectedText;
					start = this.Texyla.textarea.value.indexOf(bookmark);
					end = start + selectedText.length;
					
					this.Texyla.textarea.value = backup;
					
				// O, FF
				} else { 
					start = this.Texyla.textarea.selectionStart;
					end = this.Texyla.textarea.selectionEnd;
					selectedText = this.Texyla.textarea.value.substring(start, end);
				}
				
				// Aktualizuje promennou this.selection
				cursor = (end === start);
				this.selection = {
					txt: selectedText,
					len: selectedText.length,
					start: start,
					end: end,
					cursor: cursor
				};
			},
			
			doSelect: function() {
				this.saveSelectionProperties();
				this.select(this.selection.start, this.selection.len); //IE
				this.getLineFeedFormat();
			},
			
			select: function(from, length) {
				if (this.Texyla.IE) {
					var lfCount = this.Texyla.textarea.value.substring(0, from).split("\r\n").length - 1;
					from -= lfCount;
					this.Texyla.textarea.focus();
					this.Texyla.textarea.select();
					var ieSelected = document.selection.createRange();
					ieSelected.collapse(true);
					ieSelected.moveStart("character", from);
					ieSelected.moveEnd("character", length);
					ieSelected.select();
					this.Texyla.textarea.focus();
				} else {
					this.Texyla.textarea.selectionStart = from;
					this.Texyla.textarea.selectionEnd = from + length;
				}
				
				this.Texyla.textarea.focus();
			},
			
			selectBlock: function() {
				this.doSelect();
				var workFrom = this.Texyla.textarea.value.substring(0, this.selection.start).lastIndexOf(this.lineFeed);
				if (workFrom !== -1) {
					workFrom += this.lineFeed.length;
				}
				var from = Math.max(0, workFrom);
				
				var ta = this.Texyla.textarea;
				var workLength = ta.value.substring(workFrom, this.selection.start).length + this.selection.len;
				var fromSelectionEnd = ta.value.substring(this.selection.end, ta.value.length);
				var lineFeedPos = fromSelectionEnd.indexOf(this.lineFeed);
				workLength += lineFeedPos === -1 ? fromSelectionEnd.length : lineFeedPos;
				this.select(from, workLength);
				this.doSelect();
			},
					
			// konkrétní fce
			align: function(type) {
				this.doSelect();
			
				var start = '.' + type + this.lineFeed,
					newPar = this.lineFeed + this.lineFeed,
					found = this.Texyla.textarea.value.substring(0, this.selection.start).lastIndexOf(newPar),
					beforePar = found + newPar.length;
				
				if (found ==- 1) {
					this.Texyla.textarea.value = start + this.Texyla.textarea.value;
				} else {
					this.Texyla.textarea.value = this.Texyla.textarea.value.substring(0, beforePar) + start + this.Texyla.textarea.value.substring(beforePar);
				}
				this.select(this.selection.start + start.length, this.selection.len);
			},
			
			list: function(type) {
				this.selectBlock();
				
				var lines = this.selection.txt.split(this.lineFeed);
				var lineCount = this.selection.cursor ? 3 : lines.length;
				var replacement = '';
				
				for (var i = 1; i <= lineCount; ++i) {
					// UL
					if (type === 'ul') {
						replacement += '- ';
					// OL
					} else if (type === 'ol') {
						replacement += i+') ';
					// Blockquote
					} else if (type === 'bq') {
						replacement += '> ';
					}
					if (this.selection.cursor && i === 1) {
						var firstLength = replacement.length;
					}
					if (!this.selection.cursor) {
						replacement += lines[i - 1];
					}
					if (i !== lineCount) {
						replacement += this.lineFeed;
					}
				}
				
				if (this.selection.cursor) {
					this.tag(replacement.substring(0, firstLength), replacement.substring(firstLength));
				} else {
					this.replaceSelection(replacement);
				}
			},
			
			// Vrátí string, kde bude 'length'krát za sebou 'type'
			headingCreate: function(type, length) {
				var underline = '';
				for (var i=0; i < length; ++i) {
					underline += type;
				}
				return underline;
			},
			
			heading: function(type) {
				this.selectBlock();
				// Nový nadpis
				if (this.selection.cursor) {
					var headingText = prompt(Texyla.lng.texy_heading_text, "");
					if (headingText) {
						this.tag(
							headingText + this.lineFeed + this.headingCreate(type, headingText.length) + this.lineFeed,
							''
						);
					}
				// Vyrobí nadpis z výběru
				} else {
					this.tag(
						'',
						this.lineFeed + this.headingCreate(type, this.selection.len)
					);
				}
			},
			
			link: function() {
				var addr = prompt(Texyla.lng.texy_link_url, 'http://');
				if (addr !== undefined) {
					this.tag('"', '":' + addr);
				}
			},
			
			acronym: function() {
				this.doSelect();
				var title = prompt(this.Texyla.texy_acronym_title, '');
				if (title !== undefined) {
					// Nejsou potřeba uvozovky. př.: slovo((titulek))
					if (this.selection.txt.match(/^[a-zA-ZěščřžýáíéúůĚŠČŘŽÝÁÍÉÚŮ]{2,}$/)) {
						this.tag('','((' + title + '))');
						
					// Jsou potřeba uvozovky. př.: "třeba dvě slova"((titulek))
					} else {
						this.tag('"', '"((' + title + '))');
					}
				}
			},
			
			line: function() {
				this.doSelect();
				var lineText = this.lineFeed + this.lineFeed + '-------------------' + this.lineFeed + this.lineFeed;
				if (this.selection.cursor) {
					this.tag(lineText, '');
				} else {
					this.replaceSelection(lineText);
				}
			},
			
			block: function(what) {
				this.getLineFeedFormat();
				this.tag('/---' + what + this.lineFeed, this.lineFeed + '\\---');
			},
			
			img: function(src, alt, align, descr) {
				this.getLineFeedFormat();
				
				// Zarovnání na střed
				var imgT = align == '<>' ? this.lineFeed + '.<>' + this.lineFeed : '';
				
				// Začátek
				imgT += '[* ' + src + ' ';
				
				// Popis
				imgT += alt ? '.('+ alt +') ' : '';
				
				// Zarovnání
				imgT += (align != '<>' ? align : '*') + ']';
				
				// Popisek
				imgT += descr ? ' *** ' + alt : '';
				
				this.replaceSelection(imgT);
			},
			
			table: function(cols, rows, header) {
				this.getLineFeedFormat();
				var tabTxt = this.lineFeed;
				
				for (var i = 0; i < rows; ++i) {
					// Hlavička nahoře
					if (header === 'n' && i < 2) {
						tabTxt += '|';
						for (var j = 0; j < cols; ++j) {
							tabTxt += '--------';
						}
						tabTxt += this.lineFeed;
					}
					
					// Buňky
					for (j = 0; j < cols; ++j) {
						// Hlavička vlevo
						if (header === 'l' && j === 0) {
							tabTxt += "|* \t";
							
						// Buňka bez hlavičky
						} else {
							tabTxt += "| \t"; 
						}
						if (i === 0 && j === 0) {
							var firstLength = tabTxt.length - 1;
						}
					}
					tabTxt += '|' + this.lineFeed;
				}
				tabTxt += this.lineFeed;
				
				// Vloží tabulku
				this.tag(tabTxt.substring(0, firstLength), tabTxt.substring(firstLength));
			}
		};
	},
	
	
	Dom: function() {
		return {
			//Kontejner na texylu
			//container: null,
			
			// Načtení texyly
			init: function() {
				// načíst CSS
				Texyla.loadStylesheet(this.Texyla.addr.css + 'base.css');
				Texyla.loadStylesheet(this.Texyla.addr.css + this.Texyla.options.theme +'/'+ this.Texyla.options.theme + '.css');
				
				// Textarea
				var ta = this.Texyla.textarea;
				
				// Automatická šířka
				if (this.Texyla.options.editorWidth == 'auto') {
					this.Texyla.options.editorWidth = ta.offsetWidth;
				}
				
				// Kontejner na Texylu
				var skinContainer = ta.parentNode.insertBefore(
					_('div', {className: this.Texyla.options.theme}), ta
				);
				this.container = skinContainer.appendChild( _('div', {className: 'Texyla'}) );
				this.container.style.width = this.Texyla.options.editorWidth + 'px';
				
				// Vytvořit bloky
				this.editBlock();
				
				// Tlačítka pod textareou
				this.createBottomBar();
				
				// Zobrazit
				this.Texyla.View.switchView('edit');
				
				// Klávesové zkratky
				var _this = this;
				
				// přidá fci this.shortcuts textaree na keydown
				if (ta.addEventListener) {
					ta.addEventListener('keydown', function(e) { _this.shortcuts(e) }, false); // O, FF
				} else if (ta.attachEvent) {
					return ta.attachEvent('onkeydown', function(e) { _this.shortcuts(e) }); // IE
				}
			},
			
			//funkce, která umožní vkládání tabulátoru
			shortcuts: function(e) {
				var pressedKey = e.charCode || e.keyCode || -1;
				
				var action = false;
				
				// tučně (Ctrl + B nebo např. Shift + Ctrl + B)
				if (e.ctrlKey && pressedKey == 66 && !e.altKey) {
					this.Texyla.Texy.tag('**','**');
					action = true;				
				}
				
				// kurzíva (Ctrl + I nebo např. Alt + Ctrl + I)
				if (e.ctrlKey && pressedKey == 73) {
					this.Texyla.Texy.tag('*','*');
					action = true;				
				}
				
				// tabulátor (tab)
				if (pressedKey == 9) {
					this.Texyla.Texy.tag('\t','');
					action = true;
				}
				
				// Odeslat formulář (Ctrl + S nebo např. Shift + Ctrl + S), musí být povolené v nastavení
				if ((e.ctrlKey && pressedKey == 83) && this.Texyla.options.submitOnCtrlS) {
					this.Texyla.textarea.form.submit();
					action = true;
				}
				
				// zruší defaultní akce
				if (action) {
					// Firefox & Opera (ale ta na to docela sere)
					if (e.preventDefault && e.stopPropagation) {
						e.preventDefault();
						e.stopPropagation();
						
					// IE
					} else {
						window.event.cancelBubble = true;
						window.event.returnValue = false;
					}
				}				
			},
			
			// Editační blok
			editBlock: function() {
				var editBlock = this.container.appendChild(_('div'));
				var View = this.Texyla.View;
				
				editBlock.appendChild(this.createTopBar());		// Vložení horní lišty
				var textareaParent = editBlock.appendChild( _('div', {className: 'textareaParent' }) );
				textareaParent.appendChild(this.Texyla.textarea);
				
				// Margin textarey
				if (this.Texyla.options.textareaMargin) {
					this.Texyla.textarea.style.width = ( this.Texyla.options.editorWidth - 2 * this.Texyla.options.textareaMargin ) + 'px';
					this.Texyla.textarea.style.margin = this.Texyla.options.textareaMargin + 'px 0';
				}
				
				// Přidá pohled
				View.views.push({
					block: editBlock,
					control: this.button(Texyla.lng.view_edit, "edit", function() {View.switchView('edit');}),
					btn: this.button(Texyla.lng.view_syntax, "help", function() {window.open('http://texy.info/cs/syntax/');})
				});
			},
			/*
			// Náhled
			viewBlock: function() {
				var viewBlock =  this.container.appendChild(_('div'));
				var View = this.Texyla.View;
				viewBlock.appendChild(this.createHeading('view',Texyla.lng.view_preview));
				View.previewDiv = viewBlock.appendChild( _('div', { className: 'preview' }) );
				
				View.views.push({
					block: viewBlock,
					control: this.button(Texyla.lng.view_preview, "view", function() { View.switchView('preview') }),
					btn: null
				});
			},
			
			// Náhled HTML
			htmlBlock: function() {
				var htmlBlock =  this.container.appendChild(_('div'));
				var View = this.Texyla.View;
				htmlBlock.appendChild(this.createHeading('source', Texyla.lng.view_html));
				View.htmlPreviewDiv = htmlBlock.appendChild( _('div', { className: 'htmlPreview' }) );
				
				View.views.push({
					block: htmlBlock,
					control: this.button(Texyla.lng.view_html, "source", function() { View.switchView('HTML') }),
					btn: null
				});
			},*/
			
			// Hlavička
			createHeading: function(icon, text) {
				var dom = _('div', { className: 'heading' });
				dom.appendChild(this.img(icon, text));
				dom.appendChild(_t(text));
				return dom;
			},
			
			// Zobrazení a nápověda
			createBottomBar: function() {
				var blockBtn = this.container.appendChild( _('div', {
					className: 'bottomBar' + (this.Texyla.options.coolButtons ? ' cool' : '')
				}));
				var _this = this.Texyla;
				
				// Tlačítko vpravo dole
				this.bottomRightBar = blockBtn.appendChild( _("span", { className: 'bottomRightBar' }) );
		
				// Tlačítka vlevo dole
				var views = this.Texyla.View.views;
				for (var i=0; i<views.length; i++) {
					var block = blockBtn.appendChild(views[i].control);
				}
			},
			
			// Vytvoří tlačítkovou lištu
			createTopBar: function() {
				var domBar = _("ul", { className: 'toolbar' });
				
				// Tlačítka
				var toolbar = this.Texyla.options.toolbar;
				var buttons = this.Texyla.Buttons;
				
				for (var i=0; i<toolbar.length; i++) {
					// Oddělovač
					if (toolbar[i] === null) {
						domBar.appendChild( _("li", { className: 'separator' }) );
						continue;
					}
					
					// Ikonka
					if (typeof(toolbar[i]) == "string") {
						var li = domBar.appendChild(_("li"));
						var span = li.appendChild(_('span',{className: 'link'}));
						var img = span.appendChild(this.img(buttons[toolbar[i]].icon, buttons[toolbar[i]].name));
						span.onclick = buttons[toolbar[i]].func;
						this.hover(span);
						continue;
					}
					
					// Menu
					if (typeof(toolbar[i]) == "object") {
						var li = domBar.appendChild( _("li", { className: typeof(toolbar[i-1]) == "string" ? "btnmenu" : "menu" }) );
						var menu = li.appendChild(_("ul"));
						var menuArray = toolbar[i];
						this.hover(li);
						
						// Položky
						for (var j=0;j<menuArray.length;j++) {
							var item = menu.appendChild(_("li"));
							item.onclick = buttons[menuArray[j]].func;
							item.appendChild(this.img(buttons[menuArray[j]].icon));
							var span = item.appendChild(_('span'));
							span.appendChild(_t(buttons[menuArray[j]].name));
							this.hover(item);
						}
						continue;
					}
				}
				
				return domBar;
			},
			
			// Hover efekt
			hover: function(el) {
				el.onmouseover = function() { Texyla.hover(el, true); };
				el.onmouseout = function() { Texyla.hover(el, false); };
			},
			
			// vložit element někam
			setContent: function(ref, el) {
				while (ref.hasChildNodes()) {
					ref.removeChild(ref.childNodes[0]);
				}
				if (el) {
					ref.appendChild(el);
				}
			},
			
			button: function(title, icon, func) {
				// Hezké tlačítko
				if (this.Texyla.options.coolButtons == true) {
					var tab = this.table(3,1);
					var btn = tab.table;
					
					btn.className = 'coolButton';
					btn.onclick = func;
					this.hover(tab.table);
					
					//strany
					tab.cells[0][0].className = 'left';
					tab.cells[0][2].className = 'right';
					
					// střed
					var middle = tab.cells[0][1].appendChild( _('div', { className: 'middle' }) );
					if (icon) {
						middle.appendChild(this.img(icon));
					}
					middle.appendChild(_t(title));
					
				// Normální tlačítko
				} else {
					var btn = _('button', { type: 'button' });
					if (icon) {
						btn.appendChild(this.img(icon));
					}
					if (title) {
						btn.appendChild(_t(" " + title));
					}
				}
				
				btn.onclick = func;
				return btn;
			},
			
			img: function(file, title) {				
				var img = _('img', {
					src: this.Texyla.addr.icons + this.Texyla.options.iconType + "/" + file + "." + this.Texyla.options.iconFormat,
					width: 16,
					height: 16,
					alt: title ? title : '',
					title: title ? title : ''
				});
				
				this.pngHack(img);
				
				return img;
			},
			
			pngHack: function (img) {
				//pro IE se nacpe průhledný gif s filtrem png
				var isPng = /png$/;
				var pngIeHack = this.Texyla.IE && isPng.test(img.src);
				
				if (pngIeHack) {
					img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + img.src + "')";
					img.src = this.Texyla.addr.icons + 'pixel.gif';
				}
			},
			
			// vrátí tabulku o rozměrech x × y
			table: function(x, y) {
				var div = _('div');
				div.innerHTML = '<table cellspacing="0" cellpadding="0"></table>';
				var table = div.getElementsByTagName('table')[0];
				var tbody = table.appendChild(_('tbody'));
				var rows = [];
				var cells = [];
				
				if (x !== undefined && y !== undefined) {
					// řádky
					for (var i=0; i<y; i++) {
						rows[i] = tbody.appendChild(_('tr'));
						
						// buňky
						cells[i] = [];
						for (var j=0; j<x; j++) {
							cells[i][j] = rows[i].appendChild(_('td'));
						}
					}
				}
				
				return {
					table: table,
					tbody: tbody,
					rows: rows,
					cells: cells
				}
			},
			
			formInput: function(options) {
				var dom = _('tr');
				
				// th
				var th = dom.appendChild(_('th'));
				var label = th.appendChild(_('label'));
				label.appendChild(_t(options.name));
				
				// td
				var td = dom.appendChild(_('td'));
				switch (options.type) {
					case 'input':
						var inp = td.appendChild(_('input', options.attributes));
						inp.onfocus = function() { this.select() };
					break;
					case 'select':
						var inp = td.appendChild(_('select', options.attributes));
						// options
						for (var i = 0; i < options.options.length; i++) {
							var opt = inp.appendChild( _('option', { value: options.options[i][0] }) );
							opt.appendChild(_t(options.options[i][1]));
							if (options.options[i][2] == true) {
								opt.selected = true;
							}
						}
					break;
				}	
				
				// label for
				label.setAttribute('for', 'winInp' + ++Texyla.Window.maxInput);
				inp.setAttribute('id', 'winInp' + Texyla.Window.maxInput);
				
				return {
					dom: dom,
					inp: inp
				}
			}
		}
	},
	
	View: function() {
		return {
			views: [],
			
			/*
			// Náhled zpracovaného Texy
			previewDiv: null,
			
			// Div s náhledem HTML
			htmlPreviewDiv: null,
			
			// Tlačítka vpravo dole
			bottomRightBar: null,
			
			// Poslední zpracované Texy
			lastPreviewTexy: null,
			*/
			
			switchView: function(viewName) {			
				var changed = this.lastPreviewTexy !== this.Texyla.textarea.value;
				
				if (this.Texyla.textarea.value === '' && viewName !== 'edit') {
					alert(Texyla.lng.view_empty);
					this.Texyla.textarea.focus();
					return false;
				}
				
				if (changed && viewName !== 'edit') {
					var msg = _('p', {className: 'wait' });
					msg.appendChild(_t(Texyla.lng.view_wait));
					
					this.Texyla.Dom.setContent(this.previewDiv, msg);
					
					if (this.Texyla.options.allowHtmlPreview) {
						this.Texyla.Dom.setContent(this.htmlPreviewDiv, msg.cloneNode(true));
					}
					
					this.lastPreviewTexy = this.Texyla.textarea.value;
					
					this.getPreview();
				}
				
				var viewId = {
					// Upravit
					edit: 0,
					
					// Náhled
					preview: 1,
					
					// HTML zdroj
					HTML: 2
				};
				
				// Bloky
				for (var i=0; i < this.views.length; i++) {
					this.views[i].block.style.display = i === viewId[viewName] ? 'block' : 'none';
				}
				
				// Tlačítka dole vlevo
				for (var i=0; i<this.views.length; i++) {
					this.views[i].control.style.display = i === viewId[viewName] ? 'none' : 'inline';
				}
				
				// Tlačítko dole vpravo
				var bar = this.Texyla.Dom.bottomRightBar;
				var btn = this.views[viewId[viewName]].btn;
				this.Texyla.Dom.setContent(bar, btn ? btn : null);
			},
			
			getPreview: function() {
				var _this = this;
				function onLoad(res) {
					return _this.onPreviewLoad(res);
				}
				var options = { onComplete: onLoad, jsonRes: true };
				var vars = { texylaContent: this.Texyla.textarea.value, texylaTexyCfg: this.Texyla.options.texyCfg};
				if (this.Texyla.options.AjaxPreProcessor) {
					this.Texyla.options.AjaxPreProcessor(options);
				}
				new Texyla.Ajax(this.Texyla.addr.ajax, options, vars);
			},
			
			onPreviewLoad: function(res) {
				if (this.Texyla.options.AjaxProcessor) {
					res = this.Texyla.options.AjaxProcessor(res);
				}
				this.previewDiv.innerHTML = res;
				
				// Zobrazí zdrojový kód (HTML)
				if (this.Texyla.options.allowHtmlPreview) {
					var pre = _('pre');
					var innerText = _t( res.replace(/\n/g, this.Texyla.Texy.lineFeed) );
					pre.appendChild(innerText);
					this.Texyla.Dom.setContent(this.htmlPreviewDiv, pre);
				}
			}
		}
	},
	
	Windows: function () {
		return {
			// otevřená okna
			open: {
				img: false,
				table: false,
				emoticon: false
			},
			
			// obrázek
			img: {
				/*window: null,
				src: null,
				alt: null,
				align: null,
				descr: null,*/
				
				open: function(btnClicked) {
					if (this.Texyla.Windows.open.img == true) {
						this.window.focus();
						return false;
					}
					this.Texyla.Windows.open.img = true;
					
					var _this = this;
					
					// IE fix
					this.Texyla.Texy.doSelect();
					
					var properties = {
						heading: Texyla.lng.img_heading,
						content: null,
						func: function() {
							_this.Texyla.View.switchView('edit');
							_this.window.close();
							_this.Texyla.Texy.img(_this.src.value, _this.alt.value, _this.align[_this.align.selectedIndex].value, _this.descr.checked);
						},
						_this: this,
						open: 'img',
						btnClicked: btnClicked
					};
					
					// Obsah
					properties.content = _('div');
					var tab = this.Texyla.Dom.table();
					var table = properties.content.appendChild(tab.table);
					
					var attr = {type: 'text', className: 'textField'};
					
					// Adresa
					var tr = this.Texyla.Dom.formInput({name: Texyla.lng.img_src, type: 'input', attributes: attr});
					tab.tbody.appendChild(tr.dom);
					this.src = tr.inp;
					
					// Alt
					tr = this.Texyla.Dom.formInput( {name: Texyla.lng.img_alt, type: 'input', attributes: attr} );
					tab.tbody.appendChild(tr.dom);
					this.alt = tr.inp;
					
					// Popisek
					tr = tab.tbody.appendChild(_('tr'));
					tr.appendChild(_('td'));
					td = tr.appendChild(_('td'));
					
					var label = td.appendChild(_('label'));
					this.descr = label.appendChild( _('input', {type: 'checkbox'}) );
					label.appendChild(_t('Zobrazit jako popisek'));
					
					// Hlavička
					tr = this.Texyla.Dom.formInput({
						name: Texyla.lng.img_align,
						type: 'select',
						options: [
							['*', Texyla.lng.img_al_none, true],
							['<', Texyla.lng.img_al_left, false],
							['>', Texyla.lng.img_al_right, false],
							['<>', Texyla.lng.img_al_center, false]
						]
					});
					tab.tbody.appendChild(tr.dom);
					this.align = tr.inp;
					
					this.window = new Texyla.Window(properties);
				}
			},
			
			// smajlík
			emoticon: {
				//window: null,
				
				open: function(btnClicked) {
					if (this.Texyla.Windows.open.emoticon == true) {
						this.window.focus();
						return false;
					}
					this.Texyla.Windows.open.emoticon = true;
					
					var _this = this;
					
					var properties = {
						heading: Texyla.lng.emoticon_heading,
						content: null,
						func: null,
						_this: this,
						open: 'emoticon',
						btnClicked: btnClicked
					};
					
					// Obsah
					var emoticons = this.Texyla.options.emoticons;
					properties.content = _('div');
					
					var emDiv = properties.content.appendChild(_('div', {className: 'emoticons'}));
					var emCt = 0;
					var img, emSpan;
					for (var i in emoticons.icons) {
						//jednou za 5 smajlíků odřádkuje
						if (emCt%5 == 0 && emCt > 0) {
							emDiv.appendChild(_('br'));
						}
						emCt++;
						
						//vloží obrázek
						emSpan = emDiv.appendChild(_('span'));
						this.Texyla.Dom.hover(emSpan);
						img = emSpan.appendChild(_('img', {
							width: emoticons.width,
							height: emoticons.height,
							alt: i,
							title: i,
							src: this.Texyla.addr.emoticons + emoticons.icons[i] + '.' + emoticons.format
						}));
						emSpan.onclick = function() {_this.Texyla.Texy.replaceSelection(this.getElementsByTagName('img')[0].title); _this.window.close()};
						this.Texyla.Dom.pngHack(img);
					}
					emDiv.appendChild(_('div', {className: 'clearDiv'}));
					
					this.window = new Texyla.Window(properties);
				}
			},
			
			// tabulka
			table: {
				/*window: null,
				
				// formulářové prvky
				cols: null,
				rows: null,
				select: null,
				
				// rychlá tabulka
				select: null,
				table: null,*/
				
				open: function(btnClicked) {
					if (this.Texyla.Windows.open.table == true) {
						this.window.focus();
						return false;
					}
					this.Texyla.Windows.open.table = true;
					
					var _this = this;
					
					// IE fix
					this.Texyla.Texy.doSelect();
					
					var properties = {
						heading: Texyla.lng.tab_heading,
						content: null,
						func: function() {
							_this.Texyla.View.switchView('edit');
							_this.window.close();
							_this.Texyla.Texy.table(_this.cols.value, _this.rows.value, _this.header[_this.header.selectedIndex].value);
						},
						_this: this,
						open: 'table',
						btnClicked: btnClicked
					};
					
					// Obsah
					properties.content = _('div');
					var tab = this.Texyla.Dom.table();
					var table = properties.content.appendChild(tab.table);
					table.className = 'table';
					
					var attr = {type: 'number', value: 2, min: 1, maxlength: 2, className: 'number'};
					
					// Sloupce
					var tr = this.Texyla.Dom.formInput( {name: Texyla.lng.tab_cols, type: 'input', attributes: attr} );
					tab.tbody.appendChild(tr.dom);
					this.cols = tr.inp;
					
					// Řádky
					tr = this.Texyla.Dom.formInput( {name: Texyla.lng.tab_rows, type: 'input', attributes: attr} );
					tab.tbody.appendChild(tr.dom);
					this.rows = tr.inp;
					
					// Hlavička
					tr = this.Texyla.Dom.formInput({
						name: Texyla.lng.tab_th,
						type: 'select',
						options: [
							['', Texyla.lng.tab_th_none, false],
							['n', Texyla.lng.tab_th_top, true],
							['l', Texyla.lng.tab_th_left, false]
						]
					});
					tab.tbody.appendChild(tr.dom);
					this.header = tr.inp;
					
					// rychlá tabulka
					this.table = properties.content.appendChild(_('div', { className: 'tabBackground' }));
					this.select = this.table.appendChild(_('div', { className: 'tabSelection' }));
					var tabControl = this.table.appendChild(_('div', { className: 'tabControl' }));
					
					// Vybírání velikosti myší
					tabControl.onmousemove = function(e) { var event = e || window.event; _this.doSelect(event); };
					tabControl.onmouseover = function() { _this.tabSelect = true };
					tabControl.onclick = function() { _this.tabSelect = !_this.tabSelect; _this.cols.focus(); };
					tabControl.ondblclick = properties.func;
					
					function setColor(el) {
						var func = function() { _this.setColor(_this.cols.value, _this.rows.value); };
						el.onkeyup = func;
						el.onchange = func;
					};
					setColor(this.cols);
					setColor(this.rows);
					
					this.window = new Texyla.Window(properties);
				},
				
				// Velikost čtverečku
				tabRectangle: 8,
				
				// Povolena změna rozměrů tabulky
				tabSelect: true,
				
				getDimensions: function(event) {
					var posEl = Texyla.getPosition(this.table);
					var mouseX = event.x + document.documentElement.scrollLeft || event.pageX;
					var mouseY = event.y + document.documentElement.scrollTop || event.pageY;
					var posX = mouseX - posEl.left;
					var posY = mouseY - posEl.top;
					
					// Rozměry
					return {
						cols: Math.max(1, Math.ceil(posX / this.tabRectangle)),
						rows: Math.max(1, Math.ceil(posY / this.tabRectangle))
					};
				},
				
				doSelect: function(event) {
					if (this.tabSelect) {
						var dimensions = this.getDimensions(event);
						this.setColor(dimensions.cols, dimensions.rows);
						this.cols.value = dimensions.cols;
						this.rows.value = dimensions.rows;
					}
				},
				
				setColor: function(cols, rows) {
					this.select.style.width = (Math.min(cols, 10) * this.tabRectangle) + 'px';
					this.select.style.height = (Math.min(rows, 10) * this.tabRectangle) + 'px';
				}
			}
		}
	}
};

Texyla.Window = function(properties) {
	var _this = this;
	this.properties = properties;
	this.Texyla = properties._this.Texyla;
	
	// okno
	this.skinCont = document.body.appendChild( _('div', {className: this.Texyla.options.theme}) );
	var tab = this.Texyla.Dom.table(1,1);
	this.skinCont.appendChild(tab.table);
	tab.table.className = 'TexylaPopup';
	this.win = tab.table;
	this.win.onmousedown = function() { _this.focus(); };
	
	this.form = tab.cells[0][0].appendChild(_('form'));
	if (properties.func) {
		this.form.onsubmit = function() {properties.func(); return false;};
	};
	var submit = this.form.appendChild( _('button', {type: 'submit'}) );
	submit.style.display = 'none';
	
	// hlavička
	this.header();
	
	// obsah
	properties.content.className = 'winForm';
	this.form.appendChild(properties.content);
	
	// spodní lišta
	if (properties.func) {
		var bottomBar = this.form.appendChild( _('div', {
			className: 'bottomBar' + (this.Texyla.options.coolButtons ? ' cool' : '')
		}) );
		bottomBar.appendChild(this.Texyla.Dom.button(Texyla.lng.win_ins, "tick", properties.func));
	}

	var leftPos = Math.min(document.body.offsetWidth - this.win.offsetWidth, Texyla.getPosition(this.properties.btnClicked).left);
	this.win.style.left = Math.max(0, leftPos) + 'px';
	this.win.style.top = Texyla.getPosition(this.Texyla.textarea).top + 5 + 'px';
	
	//focus
	var firstInput = this.win.getElementsByTagName('input')[0];
	if (firstInput) {
		firstInput.focus();
	}
};
Texyla.Window.maxZIndex = 0;
Texyla.Window.maxInput = 0;

Texyla.Window.prototype = {
	lastX: 0,
	lastY: 0,
	dragging: false,
	
	close: function() {
		this.Texyla.Windows.open[this.properties.open] = false;
		document.body.removeChild(this.skinCont);
		
		var sel = this.Texyla.Texy.selection;
		this.Texyla.Texy.select(sel.start, sel.len);
	},
	
	focus: function() {
		this.win.style.zIndex = ++Texyla.Window.maxZIndex;
	},
	
	header: function() {
		var _this = this;
		var header = this.form.appendChild(_('div', { className: 'heading' }));
		this.dragger = header.appendChild(_('div'));
		header.appendChild(this.Texyla.Dom.img(this.properties.open));
		this.dragger.appendChild(_t(this.properties.heading));
		var close = header.appendChild(_('span', { className: 'close', title: Texyla.lng.win_close }));
		close.onclick = function() { _this.close(); };
		this.Texyla.Dom.hover(close);
		
		// fce
		this.dragger.onmousedown = function(event) { _this.dragStart(event || window.event); return false; };
		this.dragger.onmouseup = function() { _this.dragEnd() };
		this.dragger.onmouseout = function(event) { _this.doDrag(event || window.event) };
	},
	
	dragStart: function(event) {
		var _this = this;
		this.dragging = true;
		this.lastX = event.x || event.pageX;
		this.lastY = event.y || event.pageY;
		document.body.onmousemove = function(event) {
			_this.doDrag(event || window.event);
			return false;
		};
	},
	
	dragEnd: function() {
		document.body.onmousemove = null;
		this.dragging = false;
	},
	
	doDrag: function(event) {
		if (!this.dragging) {
			return;
		}
		var mouseX = event.x || event.pageX;
		var mouseY = event.y || event.pageY;
		
		this.win.style.left = (parseInt(this.win.style.left) + mouseX - this.lastX) + 'px';
		this.win.style.top = (parseInt(this.win.style.top) + mouseY - this.lastY) + 'px';
		
		this.lastX = mouseX;
		this.lastY = mouseY;
	}
};

// Hover efekty, při najetí myší přiřadí nebo ubere třídu hover
Texyla.hover = function(el, hover) {
	if (hover) {
		el.className += (el.className ? ' ' : '') + 'hover';
	} else {
		el.className = el.className.replace(/ ?hover/,'');
	}
};

// Zjištění pozice elementu na stránce, počítá i s offsetParent
Texyla.getPosition = function(el) {
	var left = 0;
	var top = 0;
	while (el) {
		left += el.offsetLeft;
		top += el.offsetTop;
		el = el.offsetParent;
	}
	return {
		left: left,
		top: top
	};
};

Texyla.Ajax = function(url, options, params) {
	var _this = this;
	this.xmlhttp = Texyla.Try(
		function() { return new XMLHttpRequest() },
		function() { return new ActiveXObject('Msxml2.XMLHTTP') },
		function() { return new ActiveXObject('Microsoft.XMLHTTP') }
	);
	this.onComplete = options.onComplete;
	this.options = options;
	function onStateChange() {
		if (_this.xmlhttp.readyState == 4) {
			var res = _this.xmlhttp.responseText;
			_this.onComplete(res);
		}
	};
	this.onStateChange = this;
	this.xmlhttp.onreadystatechange = onStateChange;
	this.xmlhttp.open('post', url + '?str=' + (new Date().getTime()), true);
	this.xmlhttp.setRequestHeader(
		'Content-Type', 'application/x-www-form-urlencoded'
	);
	post = 'texylaAjax=1';
	esc = encodeURIComponent || escape;
	for (i in params) {
		if (params.hasOwnProperty(i)) {
			post += '&' + i + '=' + esc(params[i]);
		}
	}
	this.xmlhttp.send(post);
};

Texyla.Try = function() {
	var retval;
	for (i = 0; i < arguments.length; ++i) {
		try {
			retval = new arguments[i];
		} catch(e) {
			continue;
		}
		return retval;
	}
};

// Načte css soubor, pokud již není načten
Texyla.loadStylesheet = function(href) {
	var stylesheets = document.styleSheets;
	for (var i = 0; i < stylesheets.length; i++) {
		if (href == stylesheets[0].href) {
			return;
		}
	}
	//alert(stylesheets.length);
	var link = _('link');
	link.setAttribute('href', href);
	link.setAttribute('type', 'text/css');
	link.setAttribute('rel', 'stylesheet');
	document.getElementsByTagName('head')[0].appendChild(link);
};

// Helper funkce
function _(name, attr, content) {
	var el = document.createElement(name);
	
	if (attr) {
		for (var prop in attr) {
			if (attr.hasOwnProperty(prop)) {
				var val = attr[prop];
				if (prop == 'className') {
					el.className = val;
				} else {
					var Opera = navigator.userAgent.indexOf('Opera') != -1;
					if (name=="input" && prop == "type" && val == "number" && !Opera) {
						val = "text";
					}
					el.setAttribute(prop, val);
				}
			}
		}
	}
	
	return el;
};

function _t(txt) {
	return document.createTextNode(txt);
};

// zkusí přednačíst základní css v defaultním umístění
Texyla.loadStylesheet(Texyla.configurator.defaultCfg().addr.css + 'base.css');