/**
*
* JavaScript knihovna s metodami pro práci s DOM
*
* @package		sllibs3
* @subpackage	jslibs
* @version		$Id: sl.dom.js 20716 2010-11-02 15:39:45Z filip $
* @encoding		UTF-8
* @author		Michal Kouďa <michal.kouda@e4you.cz>
* @copyright	(c) e4you spol. s r.o. 2002-2010, <design@e4you.cz>
*
* Obsah tohoto souboru je majetkem e4you spol. s r.o. Jeho kopírování,
* pozměňování, šíření a jakékoli další využití je možné výhradně
* se souhlasem e4you spol. s r.o.
*
*/


/// pokud není knihovna označena jako natažená, načteme ji
if(!sl.loaded['sl.dom.js']) {

	/**
	* Vytvoření konstant pro typy uzlů pro IE, kerý nepodporuje rozhraní Node
	*/
	try {
		Node
	} catch (e) {
		Node = {
			ELEMENT_NODE : 1,
			ATTRIBUTE_NODE : 2,
			TEXT_NODE : 3,
			DOCUMENT_NODE : 9,
			DOCUMENT_TYPE_NODE : 10,
			DOCUMENT_FRAGMENT_NODE : 11
		}
	}


	/**
	* Modul pro práci s DOM elementy
	*/
	sl.dom = {


		/**
		* Přidá novou option do selectu
		*
		* @param object element_id HTML element typu select
		* @param string option_value - hodnota atributu value pro nový element option
		* @param string option_text - text nového elementu option (není-li zadán použije se hodnota)
		* @param document _document objekt dokumentu v němž id hledáme (není-li zadán použije se aktuální document)
		*
		* @returns object Vrací nově vytvořený objekt Option, nebo null, pokud se objekt nepodařilo vytvořit
		*/
		addOptionToObject: function(element, option_value, option_text, _document) {
			var option = null;
			/// přidání provedeme jen v případě že je zadána hodnota a jde o select
			if(option_value && element && element.options) {
				if(!option_text) option_text = option_value;
				try {
					/// předpokládáme funkčnost gecka
					option = element.options[element.length] = new Option(option_text, option_value);
				} catch(exception) {
					/// pokud nastala výjimka zkusíme funkčnost IE
					try {
						option = _document.createElement('option');
						option.value = option_value;
						option.text = option_text;
						element.options.add(option);
					} catch(IEexception) {}
				}
			}
			return option;
		},


		/**
		* Vrací DOM element identifikovaný předaným id nebo null pokud takový neexistuje
		*
		* @param string ID hledaného elementu
		* @param document _document objekt dokumentu v němž id hledáme (není-li zadán použije se aktuální document)
		* @return Object
		*/
		getElement: function(element_name, _document) {
			try {
				/// není-li zadán dokument bereme ho z aktuální kontextu
				if(!_document) _document = document;

				if(_document.getElementById) {
					return _document.getElementById(element_name);
				} else if(_document.all) {
					return eval("_document.all['" + element_name + "']");
				}
			} catch(exception) {}
			return null;
		},


		/**
		* Vrací seznam tříd (odělený mezerami) předaného DOM elementu
		*
		* @param Object DOM element jehož třídy chceme zjistit
		* @return string
		*/
		getClass: function(element) {
			try {
				return element.className;
			} catch(exception) {};
			return '';
		},


		/**
		* Vrací true pokud má předaný DOM element danou třídu
		*
		* @param Object DOM element u něhož chceme zjistit má-li danou třídu
		* @param string jméno třídy, kterou na elementu testujeme
		* @return boolean
		*/
		hasClass: function(element, class_name) {
			var all_classes = ' ' + sl.dom.getClass(element) + ' ';
			return (all_classes.indexOf(' ' + class_name + ' ') != -1);
		},


		/**
		* Nastaví předanému DOM elementu danou třídu (ostatní třídy budou zrušeny)
		*
		* @param Object DOM element jemuž chceme třídu nastavit
		* @param string jméno třídy
		*/
		setClass: function(element, class_name) {
			try {
				element.className = class_name;
			} catch(exception) {}
		},


		/**
		* Přidá předanému DOM elementu danou třídu (ostatní třídy budou zachovány)
		*
		* @param Object DOM element jemuž chceme třídu nastavit
		* @param string jméno třídy
		*/
		addClass: function(element, class_name) {
			if(!sl.dom.hasClass(element, class_name)) {
				var new_class_name = sl.dom.getClass(element) + ' ' + class_name;
				sl.dom.setClass(element, new_class_name);
			}
		},


		/**
		* Odebere předanému DOM elementu danou třídu (ostatní třídy budou zachovány)
		*
		* @param Object DOM element jemuž chceme třídu nastavit
		* @param string jméno třídy
		*/
		removeClass: function(element, class_name) {
			if(sl.dom.hasClass(element, class_name)) {
				var new_class_name = sl.dom.getClass(element).replace(new RegExp(class_name),'');
				sl.dom.setClass(element, new_class_name);
			}
		},

		/**
		* Nahradí v předanému DOM elementu css třídu (ostatní třídy budou zachovány)
		*
		* @param Object DOM element jemuž chceme třídu nastavit
		* @param string Jméno třídy, která bude ostraněna
		* @param string Jméno třídy, která bude nastavena
		*/
		replaceClass: function(element, class_to_remove, class_to_set) {
			sl.dom.removeClass(element,class_to_remove);
			sl.dom.addClass(element,class_to_set);
		},


		/**
		* Vrací pole DOM elementů, které mají předanou třídu nebo prázdné pole pokud takové neexistují
		*
		* @param string class_name název CSS třídy, kterou mají hledané elementy mít
		* @param string tag_name název HTML elementu na nějž omezíme vyhledávání (není-li zadán prohledáváme všechny HTML elementy)
		* @param document _document objekt dokumentu v němž elementy hledáme (není-li zadán použije se aktuální document)
		* @return Array
		*/
		getElementsByClass: function(class_name, tag_name, _document) {
			try {
				var result = [];

				/// není-li zadán název HTML tagu bereme všechny
				if(!tag_name) tag_name = '*';

				/// není-li zadán dokument bereme ho z aktuální kontextu
				if(!_document) _document = document;

				/// načteme všechny elementy daného typu
				var _elements = _document.getElementsByTagName(tag_name);
				var _elements_length = _elements.length;
				for(var i=0 ; i<_elements_length ; i++) {
					/// pokud má danou třídu
					if(sl.dom.hasClass(_elements[i], class_name)) {
						/// přidáme ho do výsledku
						result.push(_elements[i]);
					}
				}
				return result;
			} catch(exception) {}
			return null;
		},


		/**
		* Vrací následující DOM element daného typu, nebo null pokud takový neexistuje
		*
		* @param HTMLElement element v dokumentu po němž hledáme následujcí element
		* @param string tag_name název HTML elementu který hledáme
		* @return HTMLElement
		*/
		nextElementAfter: function (element, tag_name) {
			var result = element.nextSibling;
			while(result) {
				if(result.tagName && result.tagName == tag_name.toUpperCase()) {
					return result;
				}
				result = result.nextSibling;
			}
			return null;
		},


		/**
		* Vrací předchozí DOM element daného typu, nebo null pokud takový neexistuje
		*
		* @param HTMLElement element v dokumentu po němž hledáme následujcí element
		* @param string tag_name název HTML elementu který hledáme
		* @return HTMLElement
		*/
		previousElementBefore: function (element, tag_name) {
			var result = element.previousSibling;
			while(result) {
				if(result.tagName && result.tagName == tag_name.toUpperCase()) {
					return result;
				}
				result = result.previousSibling;
			}
			return null;
		},


		/**
		* Vrací první rodičovský DOM element daného typu, nebo null pokud takový neexistuje
		*
		* @param HTMLElement element v dokumentu jehož předka hledáme
		* @param string tag_name název HTML elementu který hledáme
		* @param string css_class Volitelná css třída, kterou rodič musí mít
		* @return HTMLElement
		*/
		getParentByTagName: function (element, tag_name, css_class) {
			var result = element.parentNode;
			while(result) {
				if(result.tagName && result.tagName == tag_name.toUpperCase()) {
					if (css_class && sl.dom.hasClass(result,css_class) ) {
						return result;
					} else {
						return result;
					}
				}
				result = result.parentNode;
			}
			return null;
		},


		/**
		* Vrací první vnořeny element v rámici předaného prvku s předaným tagName
		* Prochází všechny prvky rekurzivně
		*
		* @param HTMLElement element v dokumentu jehož potomka hledáme
		* @param string tag_name název HTML elementu který hledáme
		* @return HTMLElement
		*/
		getFirstChildByTagName : function(element,tag_name) {
			var result = element.childNodes;
			var subresult = null;
			while (result) {
				for (var i = 0; i<result.length; i++) {
					if (result[i].tagName && result[i].tagName == tag_name.toUpperCase() ) {
						return result[i];
					} else {
						subresult = sl.dom.getFirstChildByTagName(result[i],tag_name)
						if (subresult) {
							return (subresult);
						}
					}
				}
				result = result.childNodes;
			}
			return null;
		},

		/**
		* Vytvoří xml parser, aplikuje ho na předaná data a vrátí XML DOM objekt
		*
		* @param xml_data string text ve formátu xml
		* @returns object Objekt s xml
		*/
		getXmlDomObjectFromString: function(xml_data) {
			var xml_doc = null;
			/// pokusíme se inicializovat parser pomocí DOM modelu
			try  {
				var parser=new DOMParser();
				xml_doc=parser.parseFromString(xml_data,"text/xml");
			/// pokud se to nepodaří, zkusíme IE model
			} catch(e) {
				try {
					xml_doc=new ActiveXObject("Microsoft.XMLDOM");
					xml_doc.async="false";
					xml_doc.loadXML(xml_data);
				}catch(e) {}
			}
			return xml_doc;
		},

		/**
		* Vrátí hodnotu CSS vlastnosti daného elementu
		*
		* @param HTMLElement element - elemento jehož vlastnost zjišťujeme
		* @param string style - CSS vlastnost
		* @returns string - pokud je styl definován, tak vrátíme jeho hodnotu, pokud ne vracíme NULL
		*/
		getCSSProperty: function(element, style) {
			var _style = null;
			/// pokud existuje element
			if (element) {
				/// pokud se jedná o IE
				if (element.currentStyle) {
					/// musíme upravit název stylu tak, že odstraníme pomlčky a následující znak za pomlčkou bude velké písmeno
					var regexp = /(-[a-z])/g;
					style.replace(regexp, function(result) { return result.toUpperCase().replace('-','') } );
					var _style = element.currentStyle[style];
				} else if (window.getComputedStyle) {
					var _style = document.defaultView.getComputedStyle(element,null).getPropertyValue(style);
				}
				return _style;

			} else {
				return null;
			}
		},


		/**
		 * Posune uzel DOM o jeden prvek ve své úrovní
		 *
		 * @param Object _node Přemístovaný prvek
		 */
		moveNodeUp: function(_node) {
			var current_node = _node;
			while (current_node.previousSibling) {
				if (_node.nodeType == current_node.previousSibling.nodeType) {
					_node.parentNode.insertBefore(_node, current_node.previousSibling);
					break;
				}
				current_node = current_node.previousSibling;
			}

		},

		/**
		 * Posune uzel DOM o jeden prvek ve své úrovní
		 *
		 * @param Object _node Přemístovaný prvek
		 */
		moveNodeDown: function(_node) {
			var current_node = _node;
			while (current_node.nextSibling) {
				if (_node.nodeType == current_node.nextSibling.nodeType) {
					_node.parentNode.insertBefore(_node, current_node.nextSibling.nextSibling);
					break;
				}
				current_node = current_node.nextSibling;
			}
		},

		/**
		 * Vrací vnitřní šířku okna v px
		 */
		getWindowInnerWidth: function() {
			/// ne IE prohlížeče || IE
			return window.innerWidth || document.documentElement.clientWidth;
		},

		/**
		 * Vrací vnitřní výšku okna v px
		 */
		getWindowInnerHeight: function() {
			/// ne IE prohlížeče || IE
			return window.innerHeight || document.documentElement.clientHeight;
		},

		/**
		 * Vrací počet px o něž je stránka odrolována dolů
		 */
		getPageYOffset: function() {
			/// ne IE prohlížeče || IE
			return window.pageYOffset || document.documentElement.scrollTop;
		},

		/**
		 * Vrací počet px o něž je stránka odrolována do strany
		 */
		getPageXOffset: function() {
			/// ne IE prohlížeče || IE
			return window.pageXOffset || document.documentElement.scrollLeft;
		},

		/**
		 * Vrací true, je-li stránka zobrazena v iframu
		*/
		pageIsInFrame: function() {
			return top.location.href!=location.href;
		}

	}

	/// označíme knihovnu jako načtenou
	sl.loaded['sl.dom.js'] = true;
}

