/*
find actual version of this library at:
http://www.fczbkk.com/js/dom/

modded by .::]|DEAD|[::.Screamer
*/

function newElement(name)
{
	return document.createElement(name);
}

function newTextNode(text)
{
	return document.createTextNode(text);
}

function getElement(id)
{
	return document.getElementById(id);
}

if (!Array.prototype.every)
{
  Array.prototype.every = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this &&
          !fun.call(thisp, this[i], i, this))
        return false;
    }

    return true;
  };
}

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array();
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
      {
        var val = this[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }

    return res;
  };
}

if (!Array.prototype.forEach)
{
  Array.prototype.forEach = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
        fun.call(thisp, this[i], i, this);
    }
  };
}

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

if (!Array.prototype.lastIndexOf)
{
  Array.prototype.lastIndexOf = function(elt /*, from*/)
  {
    var len = this.length;

    var from = Number(arguments[1]);
    if (isNaN(from))
    {
      from = len - 1;
    }
    else
    {
      from = (from < 0)
           ? Math.ceil(from)
           : Math.floor(from);
      if (from < 0)
        from += len;
      else if (from >= len)
        from = len - 1;
    }

    for (; from > -1; from--)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

if (!Array.prototype.map)
{
  Array.prototype.map = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array(len);
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
        res[i] = fun.call(thisp, this[i], i, this);
    }

    return res;
  };
}

if (!Array.prototype.some)
{
  Array.prototype.some = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this &&
          fun.call(thisp, this[i], i, this))
        return true;
    }

    return false;
  };
}

if (!Array.prototype.find)
{
	Array.prototype.find = function(searchStr) {
	  var returnArray = false;
	  for (i=0; i<this.length; i++) {
	    if (typeof(searchStr) == 'function') {
	      if (searchStr.test(this[i])) {
	        if (!returnArray) { returnArray = [] }
	        returnArray.push(i);
	      }
	    } else {
	      if (this[i]===searchStr) {
	        if (!returnArray) { returnArray = [] }
	        returnArray.push(i);
	      }
	    }
	  }
	  return returnArray;
	};
}

if (!Array.prototype.shuffle)
{
	Array.prototype.shuffle = function (){ 
	        for(var rnd, tmp, i=this.length; i; rnd=parseInt(Math.random()*i), tmp=this[--i], this[i]=this[rnd], this[rnd]=tmp);
	};
}

if (!Array.prototype.compare)
{
	Array.prototype.compare = function(testArr) {
	    if (this.length != testArr.length) return false;
	    for (var i = 0; i < testArr.length; i++) {
	        if (this[i].compare) { 
	            if (!this[i].compare(testArr[i])) return false;
	        }
	        if (this[i] !== testArr[i]) return false;
	    }
	    return true;
	}
}

if (!Array.prototype.fill)
{
	Array.prototype.fill=function(val)
	{ 
		for(var i=this.length;i;this[--i]=val);
	};
}

if (!String.prototype.repeat)
{
	//+ Jonas Raoni Soares Silva
	//@ http://jsfromhell.com [v1.0]

	String.prototype.repeat=function(l)
	{
		return new Array(l+1).join(this);
	};
}

/*
try{HTMLElement;}catch(e){window.HTMLElement={};}
if(!HTMLElement.prototype)
	HTMLElement.prototype={};
*/
HTMLElement.prototype.getElementsByFunction=function(func, param, recursive)
{
	if(recursive==null)recursive=true;
	var arr=[];
	for(var x=0;x<this.childNodes.length;x++)
	{
		if(func(this.childNodes[x],param))arr.push(this.childNodes[x]);
		if(recursive && this.childNodes[x].getElementsByFunction)arr=arr.concat(this.childNodes[x].getElementsByFunction(func,param,recursive));
	}
	return arr;
}

HTMLElement.prototype.getElementsByClassName=function(clsName, recursive)
{
	return this.getElementsByFunction(cls.has,clsName,recursive);
}

HTMLElement.prototype.getElementsByAttributes=function(attrs, recursive)
{
	return this.getElementsByFunction(hasAttributes,attrs,recursive);
}


function hasAttributes(elmt, attrs)
{
	if(!elmt.getAttribute)
		return false;
	for(var key in attrs)
		if(elmt.getAttribute(key)!=attrs[key])
			return false;
	return true;
}

function cloneNode(obj, document)
{
	if(obj.nodeName=='#text')return obj.cloneNode(true);

	var newObj=document.createElement(obj.tagName);
	for(var x=0;x<obj.attributes.length;x++)
		newObj.setAttribute(obj.attributes[x].name,obj.attributes[x].value);
	for(var x=0;x<obj.childNodes.length;x++)
		newObj.appendChild(cloneNode(obj.childNodes[x],document));
	return newObj;
}

obj=
{
	fix:function(o)
	{
		if(!o.getComputedStyle)o.getComputedStyle=function()
		{
			if(window.getComputedStyle)return document.defaultView.getComputedStyle(o,null);
			if(o.currentStyle)return o.currentStyle;
			return o.style;
		}
	}
}

xml=
{
	getRequest:function()
	{
		try{if(window.XMLHttpRequest)return new XMLHttpRequest;}catch(e){}
		try{if(window.ActiveXObject)return new ActiveXObject("Microsoft.XMLHTTP");}catch(e){}
		try{if(window.createRequest)return window.createRequest();}catch(e){}
		return false;
	}
}

Array.from=function(obj)
{
	var array=[];
	for(var prop in obj)
	{
		try{array[prop]=obj[prop];}
		catch(e){}
	}
	return array;
}

// library for cross-browser event management
evt=
{
	// attach event
	add:function(obj, evType, fn, useCapture)
	{
		obj=evt.fixObj(obj);

		if(obj.addEventListener)
		{
			obj.addEventListener(evType, fn, useCapture);
			return true;
		}
		if(obj.attachEvent)
			return obj.attachEvent('on'+evType, fn);

		return false;
	},

	// remove event
	remove:function(obj, evType, fn, useCapture)
	{
		obj=evt.fixObj(obj);
		
		if(obj.removeEventListener)
		{
			obj.removeEventListener(evType,fn,useCapture);
			return true;
		}
		if(obj.detachEvent)
			return obj.detachEvent('on'+evType,fn);

		return false;
	},
	
	// fix for IE event model
	fix:function(e)
	{
		if(typeof e=='undefined')e=window.event;
		if(typeof e.target=='undefined')e.target=e.srcElement;
		if(typeof e.layerX=='undefined')e.layerX=e.offsetX;
		if(typeof e.layerY=='undefined')e.layerY=e.offsetY;
		if(typeof e.which=='undefined' && e.keyCode)e.which=e.keyCode;

		// thanx to KKL2401 for preventDefault hack
		if(!e.preventDefault)
			e.preventDefault=function(){this.returnValue=false;}

		return e;
	},
	
	fixObj:function(o)
	{
		// Opera hack
		if(window.opera && o==window)
			o=document;

		return o;
	}
}


// library for working with multiple classes
var cls=
{
	// vrati pole obsahujuce vsetky triedy daneho elementu
	get:function(elm)
	{
		if(!elm || !elm.tagName)
			return false;
		if(!elm.className)
			return [];

		// na zaklade Centiho upozornenia o divnej interpretacii v Opere
		return elm.className.replace(/\s+/g,' ').split(' ');
	},

	// vrati true, ak element obsahuje triedu
	has:function(elm, cl)
	{
		var actCl=cls.get(elm);
		if(actCl && typeof cl=='string')
		{
			for(var i=0;i<actCl.length;i++)
				if(actCl[i]==cl)return true;
		}
		return false;
	},

	// prida triedu elementu
	add:function(elm, cl)
	{
		if(typeof cl!='string')
			return false;

		if(!cls.has(elm,cl))
			elm.className+=elm.className?' '+cl:cl;
		return true;
	},

	// odstrani triedu z elementu
	remove:function(elm, cl)
	{
		var actCl=cls.get(elm);
		if(!actCl || typeof cl!='string')
			return false;

		for(var i=0;i<actCl.length;i++)if(actCl[i]==cl)
		{
			delete actCl[i];
			break; //zakomentuj, jestli mas problemy s vicenasobnym definovanim trid (napr.: <br class="first second third second" />)
		}
		elm.className=actCl.join(' ');

		return true;
	},
	
	// nahradi staru triedu elementu novou, ak stara neexistuje, prida novu
	replace:function(elm, oldCl, newCl)
	{
		if(typeof oldCl!='string' || typeof newCl!='string')
			return false;

		if(oldCl!=newCl)cls.remove(elm,oldCl);
		cls.add(elm,newCl);

		return true;
	}
}
