/**
 * @fileoverview Nahled miniatury a detailu v hover boxu.
 * 
 * @author Oranges.s.r.o. & Laki <info@laki.cz>
 * @version 2.1 <28-06-2009>
 */

/**
 * Objekt hoverBox pro nacteni miniatury nahledu a detailnich informaci.
 *
 * <p>Konstruktor nastavi pracovni promenne a prednacte obrazky. Je-li zadan identifikator, projde blok a povesi udalosti na obsazene pouzitelne odkazy. Pokud odkaz ma pridelenou tridu "nohover", zaveseni udalosti se neprovede.</p>
 * <p>Pridana podpora pro pseudo staticke volani (viz priklady). Cisty staticky objekt by nemel smysl, na strance se muze vyskytovat mnoho bloku...a takto jej lze aspon postavit na objektu cfn.</p>
 * <p>Pri prochazeni bloku zavesuje udalosti hover pouze na odkazy, ktere jsou platnymi odkazy pro projekt (definice v {@link hoverBox#linkTypes}), a maji definovanou cestu k miniaturam. Tzn. ignoruje odkazy mimo web a odkazy na jine casti webu. Teoreticky lze tedy pouzit na cely dokument, ale zbytecne by se prochazely vsechny odkazy. Donacitani informaci o obsahu odkazu AJAXem se provadi, jen pokud ma tento typ odkazu definovanu obsluznou funkci.</p>    
 * 
 * <p>Struktura vstupniho objektu:</p> 
 * <pre>
 *    id     - string - volitelne
 *           - identifikator bloku, ve kterem se nachazi odkazy
 *           - neni-li identifikator definovany, pouze se nastavi pracovni promenne a navazani udalosti se musi zajistit jinak (nahrada za static volani)
 *            
 *    isAjax - boolean - volitelne
 *           - nacitat detaily odkazy AJAXem?
 *           - neni-li definovano, pak se bude nacitat     
 *                              
 *    texts  - object - volitelne
 *           - definice objektu textovych promennych - viz {@link hoverBox#texts}
 *           - nejsou-li zadany vsechny potrebne vlastnosti, doplni se objekt o tyto vlastnosti s vychozi nastavenim
 * </pre>
 * 
 * @example Zakladni pouziti, navaze hoverBox na vsechny vhodne odkazy v bloku "seznam0"
 *    var s0 = new hoverBox( {id: "seznam0"} );   
 *    
 * @example Zakladni pouziti, navaze hoverBox na vsechny vhodne odkazy v bloku "seznam0", jen miniatury bez detailu
 *    var s0 = new hoverBox( {id: "seznam0", isAjax: false} );  
 *  
 * @example Rozsirene pouziti s textovou promennou
 *    var p = {
 *      id: "seznam0",
 *      texts: {skore: "Hodnoceni"} }; 
 *    var s0 = new hoverBox(p);
 * 
 * @example "Staticke" pouziti v jinem objektu pro generovany obsah
 *  function o(element)   // kostruktor noveho objektu
 *  {
 *    this.element = element; 
 *    this.hover = new hoverBox();    // instance objektu - definuje pracovni vlastnosti
 *  }
 *  o.prototype = new cfn;  // rozsireni objektu cfn
 *  o.prototype.generate = function()
 *  {
 *    var p = {
 *      el: "a",
 *      atr: [ ["href", "http://www.cfn.com"], ["alt", "CFN"] ],
 *      txt: "Odkaz",
 *      ins: "this.element" };
 *    var a = this.ele(p);
 *     
 *    events.addEventListener(a, "mouseover", this.hover.startBox, this.hover);   // navazani udalosti
 *  }  
 *    
 * @class hoverBox - nahled miniatury a detailu
 * @extends cfn
 * @version 2.0
 * @constructor
 * @requires events Udalosti
 * @requires ajaxObject Donacitani detailu o filmech  
 * @param {object} p Objekt vstupnich parametru
 */
function hoverBox(p)
{
  /**
   * Element odkazu, ktery se prave zpracovava.
   * @type object Element
   * @private   
   */     
  this.el = null;
  
  /**
   * Objekt textovych promennych pro miniatury.
   *
   * <p>Kazda textova promenna je definovana jako samostatna vlastnost tohoto objektu typu string nebo pole stringu.</p>
   * <p>Seznam vlastnosti textovych promennych pro tento objekt:</p>
   * <pre>
   *    skore
   *    rok
   *    rezie
   *    herci
   *    narozeni
   *    misto
   *    dila
   * </pre>
   * 
   * @see Vyznam promennych je popsan ve zdrojaku.
   * @public      
   * @type object
   */
  this.texts = null;

  /**
   * Vlastnost, ktera rika, zda se budou nacitat detaily odkazu AJAXem
   *
   * @public
   * @type boolean      
   */
  this.isAjax = true;
  
  if ( (p) && (typeof(p.isAjax) == "boolean") ) this.isAjax = p.isAjax;
 
  //preklady textu
  if ((p) && (p.texts))
  {
    this.texts = p.texts;   //spravny format dat zajisti ten, kdo to predava pri inicializaci
  }
  else
  {
    var texts = new Object();
    this.texts = texts;
    this.addText(this.texts, "skore", "Skóre");
    //texty pro infobox filmu
    this.addText(this.texts, "rok",   "Rok");
    this.addText(this.texts, "rezie", "Režie");
    this.addText(this.texts, "herci", "Hrají");
    //texty pro infobox osoby
    this.addText(this.texts, "narozeni", "Narození");
    this.addText(this.texts, "misto",    "Místo");
    this.addText(this.texts, "dila",     "Díla");
  }


  //konstanty
  /**
   * Pole povolenych typu odkazu. 
   *    
   * <p>Kazdy zaznam je objekt s temito vlastnostmi:</p>
   * <pre>
   *    name  - string   - nazev typu odkazu
   *    link  - string   - hledany text v odkazu (napr. http://www.cfn.cz/film/123-nazev-filmu -> film)
   *    image - string   - zakladni url miniatur obrazku tohoto typu
   *                     - null -> obrazky neexistuji, nenacitat miniaturu
   *    ajax  - function - obsluzna funkce pro zpracovani AJAX odpovedi
   *                     - null -> nenacitat zakladni informace o obsahu pres AJAX
   *    img   - object   - objekt N/A obrazku tohoto typu
   *                     - tato vlastnost bude doplnena v kodu - prednacteni tohoto obrazku
   *                     - definovana jen pokud image != null         
   * </pre>
   * 
   * @constant
   * @private    
   * @type array of object
   */     
  this.linkTypes = new Array( 
    {name:  "film",
     link:  "film",
     image: "http://www.cfn.cz/data/film/micro/",
     ajax:  "this.addInfobox_film"},
    {name:  "osoba",
     link:  "osoba",
     image: "http://www.cfn.cz/data/osoba/micro/",
     ajax:  "this.addInfobox_osoba"},
    {name:  "kniha",
     link:  "kniha",
     image: null,
     ajax:  null},
    {name:  "disc",
     link:  "dvd_bluray",
     image: null,
     ajax:  null},
    {name:  "soundtrack",
     link:  "sountrack",
     image: null,
     ajax:  null} );
  
  /**
   * Identifikator odkazu (filmu, osoby..).
   * @type string
   * @private
   */
  this.linkID = null;     
  
  /**
   * Odsazeni infoboxu od mysitka - left.
   * @type int
   * @constant
   * @private         
   */
  this.boxOffsetLeft = 12;
  /**
   * Odsazeni infoboxu od mysitka - top.
   * @type int
   * @constant
   * @private
   */
  this.boxOffsetTop = 4;
  
  /**
   * Segment URI skriptu pro nacteni detailu odkazu AJAXem. Vola se na domene {@link hoverBox#domain}.
   *
   * @type string
   * @constant
   * @private         
   */
  this.ajaxURL = "ajaxtest/hover/test.xml";
  
  
  //nastaveni vlastnosti
  /**
   * Domena aktualniho dokumentu. 
   * Na teto domene se budou dohledavat obrazky a ajax skripty a vuci teto domene se porovnavaji odkazy.
   * Nutne pro funkcni skriptu na http://www a http:// (bezpecnostni opatreni cross-site scripting a ajax)   
   * @private      
   */
  this.domain = null;
  
  /**
   * Typ zpracovavaneho odkazu. Odpovida {@link hoverBox#linkTypes}.name.
   * @private
   * @type string      
   */     
  this.linkType = null;     //typ linku
  
  /**
   * Element vytvoreneho infoboxu.
   * @private
   * @type object element   
   */     
  this.elBox = null;
  
  /**
   * Element obrazku miniatury v infoboxu.
   * @private
   * @type object element img   
   */        
  this.elBoxImage = null;       //element obrazku v boxu
  
  /**
   * Instance objektu ajaxObject pro nacitani detailu odkazu
   * @private
   * @type object ajaxObject      
   */
  this.ajax = null;
  
  //obsluzne funkce udalosti
  /**
   * Event funkce infoboxu pro udalost mousemove na elementu odkazu.
   * @private
   * @type function   
   */
  this.eventMousemove = null;
  /**
   * Event funkce pro infobox pro udalost mouseout na elementu odkazu.
   * @private
   * @type function   
   */
  this.eventMouseout = null;  
  
  //prednacteni N/A obrazku
  for (var i=0; i<this.linkTypes.length; i++)
  {
    if (this.linkTypes[i].image != null)
    {
      this.linkTypes[i].img = new Image();
      this.linkTypes[i].img.src = this.linkTypes[i].image + "na.jpg"; 
    }
  }

  //nalezeni domeny aktualniho dokumentu
  var documentURL = document.URL.toLowerCase();   //URL zpracovavaneho fokumentu
  var reg = new RegExp("https{0,1}://([^/]*)/");  //regulerni vyraz pro nalezeni domeny odkazu
  this.domain = (reg.exec(documentURL) != null) ? reg.exec(documentURL)[0] : "http://www.cfn.cz/";  //prvni vysledek je to, co chci, jinak vychozi - hlavne pro testovani na lokale a nebo kdyz to nekdo ukradne :-)
  
  //nalezeni elementu pracovniho bloku, jinak konec
  if ((!p) || (typeof(p.id) != "string") ) return; 
  var element = document.getElementById(p.id);
  if (element == null) return;    //neni-li zadan blok, pak konec

  //projit blok, vyhledat odkazy a povesit na ne udalosti
  var a = element.getElementsByTagName("a");
  for (var i=0; i<a.length; i++)
  {
    //odkazy s tridou nohover neresit
    if (this.getClass(a.item(i)).indexOf("nohover") != -1) continue;
    
    var href = a.item(i).href;    //URI odkazu 
    
    //zkontrolovat platnost odkazu
    if (this.checkLink(href)) events.addEventListener(a.item(i), "mouseover", this.startBox, this);
  }
  this.linkType = null;   //zadny odkaz se nezpracovava
}

// hoverBox je rozsirenim objektu cfn
hoverBox.prototype = new cfn;


/**
 * Metoda zkontroluje URL odkazu. Pokud je platny, muze se na nej navazat udalost hoverBoxu.
 *
 * @param {string} href URL odkazu urcene ke kontrole 
 * @private
 * @return {boolean} vraci platnost odkazu (true->platny, false->neplatny) 
 */
hoverBox.prototype.checkLink = function(href)
{    
  //zkontrolovat, zda link vede na stejnou domenu - odkazy vedouci jinam neresit
  if (href.indexOf(this.domain) == -1) return false;
  
  //zkontrolovat, zda link dopovida definici vhodnych linku
  href = href.replace(this.domain, "");
  var reg = new RegExp("[^/]*");
  if (reg.exec(href) == null) return false; //jedna se o homepage nebo nejakou presne definovanou stranku
  
  this.linkType = reg.exec(href)[0];      //typ linku
  for (var j=0; j<this.linkTypes.length; j++)   //projit typy linku, jestli patri mezi povolene
  {
    if ( (this.linkType == this.linkTypes[j].link) && (this.linkTypes[j].image != null) )
    {
      //vse OK, zavesit udalost
      return true;
    }
  }
  
  return false;
}


/**
 * Metoda parsuje odkaz a hleda v nem potrebne udaje pro funkcionalitu.
 * 
 * <p>Odkaz, ktery parsujer je v promenne {@link hoverBox#el}. Nastavuje pracovni 
 * vlastnosti {@link hoverBox#linkType} a {@link hoverBox#linkID}.</p>   
 * 
 * @private
 * @return {boolean} uspesnost parsovani odkazu 
 */  
hoverBox.prototype.parseLink = function()
{
  //parsuj odkaz a zjisti IDcko odkazu a typ odkazu    
  var href = this.el.href.toLowerCase().replace(this.domain, "");   //je to vzdycky odkaz, zajisteno pri navazovani udalosti
  var reg = new RegExp("[^/]*");
  this.linkType = (reg.exec(href) != null) ? reg.exec(href)[0] : null;    //typ odkazu
 
  if (this.linkType == null) return false;    //pokud nelze zjistit typ odkazu, konci

  href = href.replace(this.linkType + "/", "");   //href ted ma jen parametry
  reg = new RegExp("[0-9]*");
  this.linkID = (reg.exec(href) != null) ? reg.exec(href)[0] : null; //ID odkazu

  if (this.linkID == null) return false;   //pokud nelze zjistit ID odkazu nebo link konci
  
  return true;
}

/**
 * Metoda priradi URL miniatury.
 * 
 * <p>Nastavi zdroj obrazku vlastnosti {@link hoverBox#elBoxImage}.</p>  
 *  
 * @private
 */  
hoverBox.prototype.addImageSrc = function()
{
  for (var i=0;i<this.linkTypes.length; i++)
  {
    if (this.linkTypes[i].name == this.linkType) break;
  }
  this.elBoxImage.src = this.linkTypes[i].image + this.linkID + ".jpg";
}

/**
 * Metoda pro zpracovani udalosti mysi pozornosti nad objektem - nacteni nahledu miniatury.
 *
 * @param {object event} e Udalostni objekt
 * @public
 */    
hoverBox.prototype.startBox = function(e)
{  
  //pro pripad, ze se nestihlo zpracovat udalost zruseni z predchoziho linku, tak vse zrusit 
  if (this.elBox != null)
  {
    this.endBox();
  }
    
  //zjistit zdroj udalosti
  this.el = events.eventSource(e);

  if (this.el.tagName.toLowerCase() != "a") return;   //jen pokud se jedna o link

  if (this.parseLink() == false) return;

  //vytvoreni hover boxu
  this.createBox(events.mousePosition(e));

  //nacteni miniatury
  this.addImageSrc();
  
  var d = new Date();
  this.elBoxImage.src += "?timestamp=" + d.getTime();

  this.elBoxImage.onload = events.getEvent(this.imageLoad, this);     //pokud obrazek existuje, zavola tuto funkci po svem stazeni
  this.elBoxImage.onerror = events.getEvent(this.imageError, this);   //pokud obrazek nenexistuje, zavalo tuto funkci
  
  this.eventMousemove = events.addEventListener(this.el, "mousemove", this.moveBox, this);
  this.eventMouseout = events.addEventListener(this.el, "mouseout", this.endBox, this);

  //zrusit dalsi probublavani udalosti
  if (!e) var e = window.event;
  e.cancelBubble = true;
  if (e.stopPropagation) e.stopPropagation();
}
 
/**
 * Metoda pro zpracovani udalosti posunu - posune infobox.
 * 
 * @param {object event} e Udalostni objekt
 * @private   
 */ 
hoverBox.prototype.moveBox = function(e)
{
  //zmena pozice
  this.elBox.style.left = (events.mousePosition(e)[0] + this.boxOffsetLeft) + "px";
  this.elBox.style.top = (events.mousePosition(e)[1] + this.boxOffsetTop) + "px";

  //zrusit dalsi probublavani udalosti
  if (!e) var e = window.event;
  e.cancelBubble = true;
  if (e.stopPropagation) e.stopPropagation();
}
  
/**
 * Metoda pro zpracovani udalosti opusteni mysitka nad odkazem. Rusi infobox.
 * 
 * @param {object event} e Udalostni objekt
 * @private 
 */ 
hoverBox.prototype.endBox = function(e)
{ 
  if ((this.isAjax) && (this.ajax != null))
  {
    this.ajax.abort();    //ukoncit pripadne zpracovani AJAXu
  }
   
  events.removeEventListener(this.el, "mousemove", this.eventMousemove);
  events.removeEventListener(this.el, "mouseout", this.eventMouseout);
  this.eventMousemove = null;
  this.eventMouseout = null;
  
  this.removeBox();
  
  //zrusit dalsi probublavani udalosti
  if (!e) var e = window.event;
  e.cancelBubble = true;
  if (e.stopPropagation) e.stopPropagation();
}
  
/**
 * Metoda pro vytvoreni infoboxu.
 * 
 * @param {array} position Pozice [x,y]
 * @private   
 */ 
hoverBox.prototype.createBox = function(position)
{ 
  var p = {
    el: "div",
    atr: [ ["class", "hoverbox"]  ],
    ins: document.getElementsByTagName("body")[0],
    ass: "this.elBox" };
  this.ele(p);
  
  this.elBox.style.left = (position[0] + this.boxOffsetLeft) + "px";
  this.elBox.style.top = (position[1] + this.boxOffsetTop) + "px";
  
  var p = {
    el: "img",
    ins: this.elBox,
    ass: "this.elBoxImage" };
  this.ele(p);
}

/**
 * Metoda zviditelni infobox. Vola se po nacteni obrazku.
 * @private 
 */ 
hoverBox.prototype.viewBox = function()
{
  if (this.elBox != null) this.elBox.style.visibility = "visible";
}

/**
 * Metoda zrusi infobox.
 * @private 
 */ 
hoverBox.prototype.removeBox = function()
{
  document.getElementsByTagName("body")[0].removeChild(this.elBox);
  
  this.elBox = null;
}

/**
 * Metoda obsluhuje udalost nacteni obrazku miniatury. Spusti stahovani detailnich informaci a zobrazi box.
 * @private 
 */ 
hoverBox.prototype.imageLoad = function()
{
  this.elBoxImage.onload = null;   //zrusit udalost

  //prednacteni detailu
  if (this.isAjax)
  {
    for (var i=0;i<this.linkTypes.length; i++)
    {
      if (this.linkTypes[i].name == this.linkType)
      {
        if (this.linkTypes[i].ajax != null)
        { //pouzit donacitani detailu odkazu ajaxem
          this.ajax = new ajaxObject(this.domain + this.ajaxURL);
          this.ajax.callback = events.getAJAXcallback(this.processAJAX, this);
          this.ajax.update("type=" + this.linkType + "&id=" + this.linkID); //odeslat GET pozadavek
        }
      }
    }
  }
  
  this.viewBox();
}  

/**
 * Metoda obsluhuje udalost chyby pri nacitani obrazku miniatury. Nastavi obrazek n/a.
 * @private
 */  
hoverBox.prototype.imageError = function()
{
  this.elBoxImage.onerror = null;   //zrusit udalost

  for (var i=0; i<this.linkTypes.length; i++)
  {
    if (this.linkTypes[i].name == this.linkType) break;
  }
  this.elBoxImage.src = this.linkTypes[i].img.src;
  
  //po nacteni n/a miniatury bude opet spustena udalost onload
}  
  

/**
 * Metoda, ktera zpracuje vysledek nacteneho dokumentu AJAXem.
 *  
 * @private
 * @see ajaxObject#callback 
 * @param {string}     responseText   obsah nacteneho URL jako textovy retezec
 * @param {int}        responseStatus HTTP stavovy kod (200 - vse OK, 404 - nenalezeno apod.)
 * @param {object DOM} responseXML    DOM XML dokumentu, pokud byl vracen XML obsah  
 */  
hoverBox.prototype.processAJAX = function(responseText, responseStatus, responseXML)
{
  if (responseStatus == 200)
  {
    var xmldoc = responseXML;
    var root = xmldoc.getElementsByTagName("root").item(0);
    
    for (var i=0; i<this.linkTypes.length; i++)
    {
      if ( (this.linkTypes[i].name == this.linkType) && (this.linkTypes[i].ajax != null) )
      {
        eval(this.linkTypes[i].ajax + "(root);");
        break;
      }
    }

    this.viewBox(); //zobrazit, pokud jiz neni zobrazena, tj. nekde trci obrazek....
  }
  else
  {
    //chyba AJAX prenosu
  }
}

/**
 * Metoda zpracuje obsah vraceny AJAXem a rozsiri infobox o doplnujici informace o filmu.
 * 
 * Zpracovava skore filmu, rok vyroby filmu, rezisera, herce a popis filmu. 
 * Zobrazi jen ty informace, kterou jsou navraceny.
 *  
 * @private
 * @param {object DOM} r DOM XML dokumentu
 */
hoverBox.prototype.addInfobox_film = function(r)
{
  var root = r.getElementsByTagName("film").item(0);
  if (!root) return;

  var skore = root.getElementsByTagName("skore").item(0);
  var rok = root.getElementsByTagName("rok").item(0);
  var rezie = root.getElementsByTagName("rezie").item(0);
  var popis = root.getElementsByTagName("popis").item(0);
  var herci = root.getElementsByTagName("herec");

  //pokud neni zadny objekt definovan, pak skonci
  if ( (!skore) && (!rok) && (!rezie) && (!popis) && (herci.length == 0) ) return;
  
  //upravit vlastnosti obrazku
  this.elBoxImage.style.margin = "4px";
  if (typeof(this.elBoxImage.style.styleFloat) != "undefined")
  { //IE
    this.elBoxImage.style.styleFloat = "left";
  }
  else
  {
    this.elBoxImage.style.cssFloat = "left";
  }
  
  //vygenerovat tabulku vedle obrazku
  var table = this.ele({el: "table"});
  var tbody = this.ele({el: "tbody"});

  //hodnoceni
  if (skore)
  {
    skore = skore.firstChild.nodeValue;
    if ( (typeof(skore) == "string") && (skore != "") )
    {
      var tr = this.ele({el: "tr"});
      var p = {
        el: "td",
        atr: [ ["class", "desc"] ],
        txt: this.texts.skore,
        ins: tr };
      this.ele(p);
      var p = {
        el: "td",
        atr: [ ["class", "skore"] ],
        txt: skore + "%",
        ins: tr };
      this.ele(p);
      
      this.ins(tr, tbody);
    }
  }
  
  //rok
  if (rok)
  {
    rok = rok.firstChild.nodeValue;
    if ( (typeof(rok) == "string") && (rok != "") )
    {
      var tr = this.ele({el: "tr"});
      var p = {
        el: "td",
        atr: [ ["class", "desc"] ],
        txt: this.texts.rok,
        ins: tr };
      this.ele(p);
      var p = {
        el: "td",
        txt: rok,
        ins: tr };
      this.ele(p);
      
      this.ins(tr, tbody);
    }
  }
  
  //rezie
  if (rezie)
  {
    rezie = rezie.firstChild.nodeValue;
    if ( (typeof(rezie) == "string") && (rezie != "") )
    {
      var tr = this.ele({el: "tr"});
      var p = {
        el: "td",
        atr: [ ["class", "desc"] ],
        txt: this.texts.rezie,
        ins: tr };
      this.ele(p);
      var p = {
        el: "td",
        txt: rezie,
        ins: tr };
      this.ele(p);
      
      this.ins(tr, tbody);
    }
  }
  
  //herci
  for (i=0; i<herci.length; i++)
  {
    var tr = this.ele({el: "tr"});
    if (i == 0)
    {
      var p = {
      el: "td",
      atr: [ ["class", "desc"] ],
      txt: this.texts.herci,
      ins: tr };
    }
    else
    {
      var p = {el: "td", ins: tr};
    }
    this.ele(p);
    
    var p = {
      el: "td",
      txt: herci.item(i).firstChild.nodeValue,
      ins: tr };
    this.ele(p);
    
    this.ins(tr, tbody);
  }
  
  this.ins(tbody, table);
  this.ins(table, this.elBox);
  
  
  //popis filmu pod obrazkem
  if (popis)
  {
    popis = popis.firstChild.nodeValue;
    if ( (typeof(popis) == "string") && (popis != "") )
    {
      var p = {
        el: "p",
        txt: popis,
        ins: this.elBox };
      this.ele(p);
    }
  }

}
  

/**
 * Metoda zpracuje obsah vraceny AJAXem a rozsiri infobox o doplnujici informace o osobe.
 * 
 * Zpracovava skore, datum a misto narozeni, dila a biografii. 
 * Zobrazi jen ty informace, kterou jsou navraceny.
 *  
 * @private
 * @param {object DOM} r DOM XML dokumentu
 */
hoverBox.prototype.addInfobox_osoba = function(r)
{
  var root = r.getElementsByTagName("osoba").item(0);
  if (!root) return;

  var skore = root.getElementsByTagName("skore").item(0);
  var narozeni = root.getElementsByTagName("narozeni").item(0);
  var misto = root.getElementsByTagName("misto").item(0);
  var bio = root.getElementsByTagName("bio").item(0);
  var dila = root.getElementsByTagName("dilo");

  //pokud neni zadny objekt definovan, pak skonci
  if ( (!skore) && (!narozeni) && (!misto) && (!bio) && (dila.length == 0) ) return;
    
  //upravit vlastnosti obrazku
  this.elBoxImage.style.margin = "4px";
  if (typeof(this.elBoxImage.style.styleFloat) != "undefined")
  { //IE
    this.elBoxImage.style.styleFloat = "left";
  }
  else
  {
    this.elBoxImage.style.cssFloat = "left";
  }
  
  //vygenerovat tabulku vedle obrazku
  var table = this.ele({el: "table"});
  var tbody = this.ele({el: "tbody"});

  //hodnoceni
  if (skore)
  {
    skore = skore.firstChild.nodeValue;
    if ( (typeof(skore) == "string") && (skore != "") )
    {
      var tr = this.ele({el: "tr"});
      var p = {
        el: "td",
        atr: [ ["class", "desc"] ],
        txt: this.texts.skore,
        ins: tr };
      this.ele(p);
      var p = {
        el: "td",
        atr: [ ["class", "skore"] ],
        txt: skore + "%",
        ins: tr };
      this.ele(p);
      
      this.ins(tr, tbody);
    }
  }

  //narozeni
  if (narozeni)
  {
    narozeni = narozeni.firstChild.nodeValue;
    if ( (typeof(narozeni) == "string") && (narozeni != "") )
    {
      var tr = this.ele({el: "tr"});
      var p = {
        el: "td",
        atr: [ ["class", "desc"] ],
        txt: this.texts.narozeni,
        ins: tr };
      this.ele(p);
      var p = {
        el: "td",
        txt: narozeni,
        ins: tr };
      this.ele(p);
      
      this.ins(tr, tbody);
    }
  }
  
  //misto
  if (misto)
  {
    misto = misto.firstChild.nodeValue;
    if ( (typeof(misto) == "string") && (misto != "") )
    {
      var tr = this.ele({el: "tr"});
      var p = {
        el: "td",
        atr: [ ["class", "desc"] ],
        txt: this.texts.misto,
        ins: tr };
      this.ele(p);
      var p = {
        el: "td",
        txt: misto,
        ins: tr };
      this.ele(p);
      
      this.ins(tr, tbody);
    }
  }
 
  //dila
  for (i=0; i<dila.length; i++)
  {    
    var tr = this.ele({el: "tr"});
    if (i == 0)
    {
      var p = {
      el: "td",
      atr: [ ["class", "desc"] ],
      txt: this.texts.dila,
      ins: tr };
    }
    else
    {
      var p = {el: "td", ins: tr};
    }
    this.ele(p);
    
    var p = {
      el: "td",
      txt: dila.item(i).firstChild.nodeValue,
      ins: tr };
    this.ele(p);
    
    this.ins(tr, tbody);
  }
  
  this.ins(tbody, table);
  this.ins(table, this.elBox);
  
  
  //popis filmu pod obrazkem
  if (bio)
  {
    bio = bio.firstChild.nodeValue;
    if ( (typeof(bio) == "string") && (bio != "") )
    {
      var p = {
        el: "p",
        txt: bio,
        ins: this.elBox };
      this.ele(p);
    }
  }

} 


/******************************************************************************
 *   Objekt HOVERBOXO2
 ******************************************************************************/ 

/**
 * Objekt hoverBoxO2 pro nacteni miniatury nahledu odkazu na O2TV. Vola puvodni konstruktor.
 *
 * <p>Objekt je predefinovany potomek objektu hoverBox. Negeneruje AJAX dotazy, jinak stejne funkcni.</p>
 * <p>Pro odkazy bez pouziti hover miniatury pouzit tridu "nohover". Dalsi priklady v objektu {@link hoverBox}.</p> 
 * 
 * <p>Struktura vstupniho objektu:</p> 
 * <pre>
 *    id     - string - volitelne
 *           - identifikator bloku, ve kterem se nachazi odkazy
 *           - neni-li identifikator definovany, pouze se nastavi pracovni promenne a navazani udalosti se musi zajistit jinak (nahrada za static volani)     
 *                              
 *    texts  - object - volitelne
 *           - definice objektu textovych promennych - viz {@link hoverBox#texts}
 *           - nejsou-li zadany vsechny potrebne vlastnosti, doplni se objekt o tyto vlastnosti s vychozi nastavenim
 * </pre>
 * 
 * @example Zakladni pouziti, navaze hoverBox na vsechny vhodne odkazy v bloku "seznam100"
 *    var s100 = new hoverBoxO2( {id: "seznam100"} );  
 *    
 * @class hoverBoxO2 - nahled miniatury pro odkazy na O2TV
 * @extends hoverBox
 * @version 1.0
 * @constructor
 * @see hoverBox 
 * @requires events Udalosti
 * @requires ajaxObject Donacitani detailu o filmech  
 * @param {object} p Objekt vstupnich parametru
 */
function hoverBoxO2(p)
{
  p.isAjax = false; //zadne AJAX donacitani detailu
  
  //zavolani konstruktoru predka
  hoverBox.call(this, p);
  
  //redefinice vlastnosti
  this.domain = "http://www.o2-tv.cz/o2tv/cz/videoteka/index.html?movie_id=";
  
  this.linkTypes = [{
    name:  "o2",
    link:  "o2tv",
    image: "http://www.cfn.cz/data/o2tv/micro/",
    img:   new Image(),
    ajax:  null} ];
  this.linkTypes[0].img.src = this.linkTypes[0].image + "na.jpg"    //vychozi obrazek n/a
}

//redefinice objektu
hoverBoxO2.prototype = new hoverBox();
hoverBoxO2.prototype.constructor = hoverBoxO2;

//prepsani metod predka

/**
 * Metoda zkontroluje URL odkazu. Kompletne redefinuje metodu predka. 
 *
 * @param {string} href URL odkazu urcene ke kontrole 
 * @private
 * @see hoverBox#checkLink 
 * @return {boolean} vraci platnost odkazu (true->platny, false->neplatny) 
 */
hoverBoxO2.prototype.checkLink = function(href)
{
  href = href.replace(this.domain, "");
  var reg = new RegExp("[0-9]*");
  if (reg.exec(href) == null) return false; //jedna se o divny link
  
  this.linkID = reg.exec(href)[0];
  this.linkType = "o2";
  
  return true;
}

/**
 * Metoda parsuje odkaz a hleda v nem potrebne udaje pro funkcionalitu. Kompletne redefinuje metodu predka.    
 * 
 * @private
 * @see hoverBox#parseLink 
 * @return {boolean} uspesnost parsovani odkazu 
 */
hoverBoxO2.prototype.parseLink = function()
{
  var href = this.el.href.toLowerCase().replace(this.domain, "");
  var reg = new RegExp("[0-9]*");
  this.linkID = reg.exec(href)[0];
  
  this.linkType = "o2";
}

