/*************************************************************************
 *
 * Catalogin Javascript-kirjasto.
 * 
 * Rutiineita käytetään tuomalla kirjasto sivulle käyttämällä alla 
 * olevan mukaista elementtiä. (Tuossa tietenkin muuttuu toi src-attribuutin
 * sisältö sen mukaan kuinkan toi yllapito_common_2006 hakemisto on linkitetty
 * projektin sisään).
 *
 * <script type="text/javascript" src="/yllapito_common_2006/js/catalog.js">
 *
 * Sivulta voidaan tämän jälkeen viitata rutiineihin tyyliin:
 * 
 * Catalog.popupWindow(...);
 * Catalog.createCookie(...);
 *
 * Alla lueteltuna rutiinit, jotka löytyvät tästä kirjastosta.
 *
 * Ponnahdusikkunoiden rutiinit:
 * -----------------------------------------------------------------------
 * Catalog.popupWindow            - Avaa ponnahdusikkunan 
 * ESIM: onClick="Catalog.popupWindow('popupin_nimi','testi.tmpl',
 *                {'width': 370, 'height': 200}); return false;"
 * Myös muut parametrit: {'width': 100, 'height': 100, 'resizable': 0} jne.
 *
 * Catalog.closeDialog            - Sulkee ikkunan.
 *
 * Tyyleihin liittyvät rutiinit:
 * -----------------------------------------------------------------------
 * Catalog.showElement            - Tuo näkyviin elementin.
 * Catalog.hideElement            - Piilottaa elementin näkyvistä. !!!MP120107: Ei toimi ie:ssä!!!
 * Catalog.showHideElement        - Piilottaa/Tuo näkyviin elementin
 *                                  perustuen elementin nyk. näkyvyyteen.
 * Catalog.showHideElementByValue - Piilottaa/Tuo näkyviin elementin 
 *                                  arvon perusteella
 * Catalog.displayElement         - Tuo näkyviin piilotetun divin linkin alle
 *                                  esim: onclick="Catalog.displayElement(this, 'divin_id', {'offset_x': 10, 'offset_y': 20}); return false;"
 * Catalog.setDisplayStyle        - Asettaa elementille display-tyylin
 *                                  annettuun arvoon.
 * Catalog.setDisplayId           - Asettaa sivulta kaikkien id:llä löytyvien
 *                                  elementtien display-tyyliksi parametrina
 *                                  välitetyn arvon.
 *
 * Yleiskäyttöisiä rutiineita:
 * -----------------------------------------------------------------------
 * Catalog.windowWidth            - Palauttaa avoimen selainikkunan leveyden.
 * Catalog.elementsById           - Hakee sivulta kaikki id:llä löytyvät
 *                                  elementit
 * Catalog.setEvents              - Asettaa parametrina annetun luokkanimen
 *                                  mukaisien elementtien lapsille, jotka
 *                                  määritellään parametrina, parametrina
 *                                  annetut tapahtumakäsittelijät.
 *
 * Lomakkeisiin/Valintalistoihin liittyvät rutiinit:
 * -----------------------------------------------------------------------
 * Catalog.selectAllEntries       - Rutiini asettaa valintalistalta kaikki
 *                                  tietueet valituiksi.
 *
 * Kalenteri-rutiinit:
 * -----------------------------------------------------------------------
 * Catalog.jscal_setHiddenDate    - Kalenterimakron käyttämä rutiini.
 * Catalog.jscal_condDateChange   - Kalenterimakron kanssa käytettävä rutiini,
 *                                  jonka avulla voidaan toisen päiväys
 *                                  kentän arvot asettaa ehtojen perusteella.
 *
 * Cookie-rutiinit:
 * -----------------------------------------------------------------------
 * Catalog.createCookie           - Rutiini luo uuden keksin.
 * Catalog.readCookie             - Rutiini lukee keksin arvon.
 * Catalog.eraseCookie            - Rutiini poistaa keksin.
 *
 *
 * Makrojen käytössä olevat rutiinit (näitä ei _yleensä_ käytetä suoraan):
 * -----------------------------------------------------------------------
 * Catalog.updateElementContent   - Käytetään elementin_paivitys-makrosta,
 *                                  tätä ei luultavasti käytetä pahemmin
 *                                  suoraan.
 *
 *************************************************************************/

/*
 * Catalog-rakentaja
 *
 * Luo muutamia jäsenmuuttujia rutiinien käyttöön ja lukee sivulle 
 * myös scriptaculous- ja prototype-kirjastot.
 * PMA 14.6.2007
 *
 */



var CreateCatalog = function()
{
    // Avoimet ponnahdusikkunat.
    this.popups = new Array();
    
    // Ponnahdusikkunoiden oletus-parametrit.
    this.popup_options = 
    {
	// Leveys ja korkeus on oletuksena 85% ruudun koosta.
	"width":  parseInt(screen.width * 0.85),
	"height": parseInt(screen.height * 0.85),

	"toolbar":    0,
	"location":   0,
	"menubar":    0,
	"scrollbars": 1,
	"status":     1,
	"resizable":  1
    };

    // Lasketaan vielä popupille oletussijainti ruudun keskelle.
    this.popup_options["left"] = 
       	parseInt((screen.width - this.popup_options["width"])/2);
    
    this.popup_options["top"] = 
       	parseInt((screen.height - this.popup_options["height"])/2 - 30);
    
    this.checked = true;

    function check_is_script(element)
    {
	if (element.src && element.src.match(/catalog\.js/))
	{
	    return element;
	}

	var children = element.childNodes;
	for (var index = 0 ; index < children.length ; index++)
	{
	    var found = check_is_script(children[index]);
	    if (found != null)
	    {
		return found;
	    }
	}

	return null;
    }

    // Luetaan prototype.js ja scriptaculous.js
    /*
    var script = check_is_script(document);
    if (script != null)
    {
	var path = script.src.replace(/http:\/\/[\w-.]+?\//, '/');
	path = path.replace(/catalog\.js(\?.*)?$/,'');

	document.write('<script type="text/javascript" src="' +
		       path + 'scriptaculous/lib/prototype.js"></script>');
	document.write('<script type="text/javascript" src="' +
		       path + 'scriptaculous/src/scriptaculous.js"></script>');
    }
    */
}

var Catalog = new CreateCatalog();

/*
 * Avaa parametrisoitavan ponnahdusikkunan. 
 *
 * Parametrit:
 *
 * name              - Ponnahdusikkunan nimi. Jos samalla nimellä löytyy avoin
 * (pakollinen)        ponnahdusikkuna, suljetaan avoin ja avataan 
 *                     uudelleen uudella urlilla.
 *
 * url               - URL-osoite, jonka ponnahdusikkuna näyttää. (pakollinen)
 * (pakollinen)
 *
 * requested_options - Ponnahdusikkunan parametrit assosiatiivisen taulukon
 * (vaihtoehtoinen)    muodossa. Optioiden nimet ovat samat kuin normaalisti
 *                     popupeille annettavat nimet. Parametri voidaan myös
 *                     jättää tyhjäksi, jolloin oletusarvot tulevat voimaan.
 *
 * Ponnahdusikkunan parametrien oletusarvot:
 * - width      - Oletusarvona 85% ruudun leveydestä.
 * - height     - Oletusarvona 85% ruudun korkeudesta.
 * - left       - Ikkuna asemoidaan ruudun keskelle leveyssuunnassa.
 * - top        - Ikkuna asemoidaan ruudun keskelle korkeussuunnassa.
 * - toolbar    - Ikkunassa ei näytetä työkaluriviä.
 * - location   - Ikkunassa ei näytetä osoitepalkkia.
 * - menubar    - Ikkunassa ei näytetä valikoita.
 * - scrollbars - Ikkunassa näytetään vierityspalkit.
 * - status     - Ikkunassa näytetään tilarivi.
 * - resizable  - Ikkunan kokoa on mahdollista muuttaa.
 *
 * Rutiinia voidaan kutsua myös ilman leveys- ja korkeus-parametreja, 
 * jolloin ponnahdusikkunan kooksi tulee 85% ruudun koosta.
 *
 * Rutiini asettaa ponnahdusikkunan aina ruudun keskelle, ellei left ja top
 * optioilla pakoteta ikkunan sijaintia toisaalle.
 *
 */
CreateCatalog.prototype.popupWindow = function(name, url, requested_options)
{
    var popup = this.popups[name];

    if (popup && !popup.closed)
    {
	popup.close();
    }

    if (typeof(requested_options) == "undefined")
    {
	requested_options = this.popup_options;
    }

    // Lasketaan ikkunan sijainti keskelle ruutua leveys- ja 
    // korkeussuunnassa.
    if (typeof(requested_options["width"]) != "undefined" && 
	typeof(requested_options["left"]) != "undefined")
    {
	requested_options["left"] = 
	    parseInt((screen.width - requested_options["width"])/2);
    }

    if (typeof(requested_options["height"]) != "undefined" && 
	typeof(requested_options["top"]) != "undefined")
    {
	requested_options["top"] = 
	    parseInt((screen.height - requested_options["height"])/2 - 30);
    }
    
    var active_options = new Array();
    for (option in this.popup_options)
    {
	if (typeof(option) == "function")// || option instanceof Object)
	    continue;

	if (typeof(requested_options[option]) != "undefined")
	{
	    active_options.push(option.toLowerCase() + "=" + 
				requested_options[option]);
	}
	else
	{
	    active_options.push(option.toLowerCase() + "=" + 
				this.popup_options[option]);
	}
    }
    
    var options_string = active_options.join(",");

    // Avataan ikkuna ja tallennetaan instanssi jäsenmuuttujaan (this.popups).
    popup = window.open(url, name, options_string);

    this.popups[name] = popup;
}

/*
 * Sulkee avoimen ikkunan, josta rutiinia kutsutaan. Parametrinä voidaan
 * antaa varmistusteksti, joka kysytään käyttäjältä ikkunaa suljettaessa.
 *
 * Parametrit:
 *
 * msg - Varmistusviesti, joka näytetään käyttäjälle. Jos tämä on tyhjä, ei
 *       kysellä varmistusta vaan suljetaan ikkuna kylmän rauhallisesti.
 *       (vaihtoehtoinen)
 *
 * ******************************************************************
 * * HUOM! Firefoxilla tämä ei tee mitään, ellei ikkunaa ole avattu *
 * *       window.open -funktiolla selaimen toimesta.               *
 * ******************************************************************
 *
 */
CreateCatalog.prototype.closeDialog = function(msg)
{
    if ((typeof(msg) == "string" && confirm(msg)) ||
	(typeof(msg) == "undefined")) 
    { 
	self.close();
    }
    
    return false;
}

/*
 * Tuo elementin näkyviin.
 *
 * Parametrit:
 *
 * elem_id       - Halutun elementin id-arvo. (pakollinen)
 * display_style - Haluttu näyttötyyli. (Oletuksena "block") (vaihtoehtoinen)
 *
 */
CreateCatalog.prototype.showElement = function(elem_id, display_style)
{
    if (typeof(display_style) == "undefined")
    {
	display_style = "block";
    }
    
    this.setDisplayStyle(elem_id, display_style);
}

/*
 * Piilottaa elementin näkyvistä
 *
 * Parametrit:
 *
 * elem_id       - Halutun elementin id-arvo. (pakollinen)
 * display_style - Haluttu näyttötyyli. (Oletuksena "none") (vaihtoehtoinen)
 *
 */ 
CreateCatalog.prototype.hideElement = function(elem_id, display_style)
{
    if (typeof(display_style) == "undefined")
    {
	display_style = "none";
    }
    
    this.setDisplayStyle(elem_id, display_style);
}

/*
 * Vaihtaa elementin näkyvyyden perustuen nykyiseen näkyvyysarvoon.
 *
 * Parametrit:
 *
 * elem_id       - Halutun elementin id-arvo. (pakollinen)
 * display_style - Haluttu näyttötyyli. (Oletuksena "none") (vaihtoehtoinen)
 *
 */
CreateCatalog.prototype.showHideElement = function(elem_id, display_style)
{
    if (typeof(display_style) == "undefined")
    {
	display_style = "block";
    }

    var style = "none";

    var element = document.getElementById(elem_id);
    if (typeof(element.style.display) == "string" && 
	!element.style.display.match(/^\s*$/))
    {
	var style = 
	    (element.style.display == display_style) ? "none" : display_style;
    }
    
    this.setDisplayStyle(elem_id, style);
}

/*
 * Piilottaa/Tuo näkyviin elementin perustuen toisen elementin arvoon.
 *
 * Parametrit:
 *
 * src_elem       - Elementti jonka arvoon verrataan. (pakollinen)
 * value          - Arvo johon src_elem-arvoa verrataan. (pakollinen)
 * target_elem_id - Muutettavan elementin id. (pakollinen)
 * display_style  - Haluttu näyttötyyli. (Oletuksena "block") (vaihtoehtoinen)
 *
 */
CreateCatalog.prototype.showHideElementByValue = 
    function(src_elem, value, target_elem_id, display_style)
{
    var style;

    if (typeof(display_style) == "undefined")
    {
	display_style = "block";
    }
    
    if (value.length == 0)
    {
	value = "\\s*";
    }
    
    var re_string = "^" + value + "$";
    var regex = new RegExp(re_string);
    if (src_elem.value.match(regex))
    {
	style = display_style;
    }
    else
    {
	style = "none";
    }

    this.setDisplayStyle(target_elem_id, style);
}

/*
 * Tuo esiin piilotetun elementin. Käytetään esim, linkin onclick-eventissä.
 * 
 * Parametrit:
 *
 * element            - Linkki, jonka mukaan näytettävä elementti asemoidaan.
 * display_element_id - Elementti, joka tuodaan esille linkin alle.
 * options            - Optiot, joilla voidaan määritellä
 *
 *                      Mahdollisia arvoja ovat:
 *                      - offset_x   näytettävän elementin siirtymä 
 *                                   vaakasuunnassa suhteessa linkkiin 
 *                      - offset_y   näytettävän elementin siirtymä 
 *                                   pystysuunnassa suhteessa linkkiin 
 *
 */
CreateCatalog.prototype.displayElement = 
    function(element, display_element_id, options)
{
    var left = element.offsetLeft;
    var top = element.offsetTop + element.offsetHeight;
    var parent = element.offsetParent;
    
    //while(parent.tagName.toLowerCase() != "body")
    while(parent)
    {
	left += parent.offsetLeft;
	top += parent.offsetTop;

	parent = parent.offsetParent;
    }

    var elem = document.getElementById(display_element_id);

    if (typeof(options) != "undefined")
    {
	if (typeof(options["offset_x"]) != "undefined")
	{
	    left = left + (options["offset_x"]);
	}

	if (typeof(options["offset_y"]) != "undefined")
	{
	    top = top + (options["offset_y"]);
	}
    }

    elem.style.left = left + 'px';
    elem.style.top = top + 'px';

    elem.style.display = (elem.style.display == "none") ? "" : "none";

    var elem_right = left + elem.offsetWidth;
    var window_width = this.windowWidth();

    if (elem_right > window_width)
    {
        elem_right = elem_right - window_width;
	elem.style.left = left - elem_right - 20 + 'px';
    }
}

/*
 * Palauttaa avoimen selainikkunan leveyden.
 *
 */
CreateCatalog.prototype.windowWidth = function()
{
  var myWidth = 0;

  if (typeof(window.innerWidth) == "number")
  {
    //Non-IE
    myWidth = window.innerWidth;
  } 
  else if (document.documentElement &&
           (document.documentElement.clientWidth || 
            document.documentElement.clientHeight))
  {
    //IE 6+ in "standards compliant mode"
    myWidth = document.documentElement.clientWidth;
  } 
  else if (document.body && 
           (document.body.clientWidth || document.body.clientHeight))
  {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
  }

  return myWidth;
}

/*
 * Asettaa elementille parametrina annetun näyttötyylin.
 *
 * Parametrit:
 *
 * elem_id - Elementin id, johon näyttötyyli asetetaan.
 * style   - Näyttötyyliin asetettava arvo.
 *
 */
CreateCatalog.prototype.setDisplayStyle = function(elem_id, style)
{
   if (document.getElementById) {
	document.getElementById(elem_id).style.display = style;
   }
   else if (document.all) { //IS IE 4 or 5 (or 6 beta)
       eval( "document.all." + elem_id + ".style.display = style");
    }
    else if (document.layers) { //IS NETSCAPE 4 or below
	document.layers[elem_id].display = style; 
    }
 }

/*
 * Asettaa kalenterimakroon liittyvän hidden-kentän oikeaan arvoon,
 * jotta kalenterinäkymä osaa näyttää sen oikein avattaessa.
 *
 * Parametrit:
 *
 * field - Kenttä, jonka arvo tallennetaan.
 *
 */
CreateCatalog.prototype.jscal_setHiddenDate = function(field)
{
    var input_year = document.getElementById(field + "_year");
    var input_month = document.getElementById(field + "_month");
    var input_day = document.getElementById(field + "_day");
    
    var input_str = document.getElementById(field + "_hidden");
    
    input_str.value = 
        input_year.value + "-" + input_month.value + "-" + input_day.value;
    
    return false;
}

/*
 * Käytetään yhdessä toisen kalenterimakron kanssa. Alla esimerkki käytöstä.
 *
 * Parametrit:
 *
 * field        - Kenttä, jonka arvoa verrataa change_fieldin arvoon.
 * change_field - Kenttä, johon field-kentän arvoa verrataan ja jonka arvoa
 *                muutetaan change_cond ehdon perusteella.
 * change_cond  - Muutosehto, jonka perusteella päätetään pitääkö
 *                changefieldin arvoa muuttaa. 
 *                Vaihtoehdot: always, if_lower, if_higher
 *
 * Esimerkki:
 * ----------
 *
 * <wf-usemacro name="datetimeselect"
 * FIELD="julkaisu_pvm"
 * ONCHANGE="Catalog.jscal_condDateChange('julkaisu_pvm', 'arkisto_pvm', 'if_higher');"
 * >
 *
 * <wf-usemacro name="datetimeselect"
 * FIELD="arkisto_pvm"
 * ONCHANGE="Catalog.jscal_condDateChange('arkisto_pvm', 'julkaisu_pvm', 'if_lower');"
 * >
 *
 */
CreateCatalog.prototype.jscal_condDateChange = 
    function(field, change_field, change_cond)
{
    var input_year = document.getElementById(field + "_year");
    var input_month = document.getElementById(field + "_month");
    var input_day = document.getElementById(field + "_day");
    
    var date = new Date(input_year.value,
			input_month.value,
			input_day.value);
    
    var change_input_year = document.getElementById(change_field + "_year");
    var change_input_month = document.getElementById(change_field + "_month");
    var change_input_day = document.getElementById(change_field + "_day");
    
    var change_date = new Date(change_input_year.value,
			       change_input_month.value,
			       change_input_day.value);
    
    if ((change_cond == "always") || 
	(change_cond == "if_lower" && date < change_date) ||
	(change_cond == "if_higher" && date > change_date))
    {
	change_input_year.value = input_year.value;
	change_input_month.value = input_month.value;
	change_input_day.value = input_day.value;
	
	this.jscal_setHiddenDate(change_field);
    }
    
    return false;
}

/*
 * Hakee kaikki elementit dokumentista id:n perustella. Toimii siten, 
 * että hakee seuraavan elementin id-arvolla, lisää elementin listalle,
 * asettaa elementin id:n tyhjäksi ja hakee seuraavan elementin id-arvolla.
 *
 * Parametrit:
 *
 * id - haettavien elementtien id
 *
 * ***************************************************************************
 * * HUOM! Tämä ei ole kovin hyvä tapa. Parempi olisi asettaa elementeille   *
 * *       jokin tyyliluokka, ja sitten käyttää                              *
 * *       Catalog.getElementsByClassName-rutiinia. Elementtien id-arvot on  *
 * *       kuitenkin tarkoitettu W3C:n mukaan yksilöimään elementtejä.       *
 * ***************************************************************************
 *
 */
CreateCatalog.prototype.elementsById = function(id)
{
    var nodes = [];
    var tmpNode = document.getElementById(id);
    while(tmpNode){
	nodes.push(tmpNode);
	tmpNode.id = "";
	tmpNode = document.getElementById(id);
    }

    for(var x=0; x<nodes .length; x++){
	nodes[x].id = id;
    }

    return nodes;
}

/*
 * Asettaa elementtien id:n perusteella display-tyylin.
 *
 * Parametrit:
 *
 * id            - id, jonka perusteella elementit valitaan.
 * display_style - Haluttu näyttötyyli. (Oletuksena "block")
 *
 * *************************************
 * * HUOM! ks. elementsById:n varoitus *
 * *************************************
 *
 */
CreateCatalog.prototype.setDisplayId = function(id, display_style)
{
    if (typeof(display_style) == "undefined")
    {
	display_style = "block";
    }

    var nodes = this.elementsById(id);

    for(var x=0; x < nodes.length; x++)
    {
	nodes[x].style.display = display_style;
    }
}

/*
 * Päivittää popupin emoikkunasta löytyvän divin tai selectin sisällön,
 * perustuen popup-ikkunan dataan. Käytetään elementin_paivitys-makrosta, 
 * tätä ei luultavasti pahemmin kutsuta suoraan.
 *
 * Parametrit:
 *
 * element_id  - Kohde-elementin id, johon tiedot kirjoitetaan
 * items       - Lista tiedoista, jotka päivitetään elementin sisälle.
 *               * Selectin tapauksessa, items-listan (assosiatiivinen)
 *                 avaimessa on option-elementin value-arvo ja
 *                 arvossa on option-elementin tekstiarvo.
 *
 */
CreateCatalog.prototype.updateElementContent = function(element_id, items)
{
   var doc = window.opener.document;
   var element = doc.getElementById(element_id);

   if (element.tagName.toLowerCase() == "div")
   {      
     while (element.firstChild)
     {
       element.removeChild(element.firstChild);
     }

     var key;

     for (key in items)
     {
       if (typeof items[key] == "function") continue;

       var text = doc.createTextNode(items[key]);
       element.appendChild(text);

       var br = doc.createElement("br");
       element.appendChild(br);
     }
  }
  else if (element.tagName.toLowerCase() == "select")
  {

    var selected = 0;
    if (element.selectedIndex > -1)
    {
      selected = element.options[element.selectedIndex].value;
    } 

    while (element.length)
    {
      element.remove(0);
    }

    
    var key;
    for (key in items)
    {
      if (typeof items[key] == "function") continue;
   
      var option = doc.createElement("OPTION");
      option.value = key;
      option.text = items[key];

      if (selected == key) 
          option.selected = true;

      try {
        element.add(option, null); // standards compliant; doesn't work in IE
      }
      catch(ex) {
        element.add(option); // IE only
      }

    }
  }
}

/*
 * Asettaa nimetyltä lomakkeelta nimetyt input (type=checkbox) elementit
 * valituiksi.
 *
 * Parametrit:
 *
 * form_name  - Lomakkeen nimi, josta valittavat checkboxit löytyvät.  
 * input_name - Valittavien input (type=checkbox) elementtien nimi.
 *
 */
CreateCatalog.prototype.selectAllEntries = function(form_name, input_name)
{
  form_elements = document.forms[form_name].elements;

  for (i=0 ; i < form_elements.length ; i++)
  {
    if (form_elements[i].type == 'checkbox' &&
	form_elements[i].name == input_name &&
        form_elements[i].disabled == false)
    {
      form_elements[i].checked = this.checked;
    }  
  }

  if (this.checked)
  {
    this.checked = false;
  } 
  else
  {
    this.checked = true;
  }
}

/*
 * Written by Jonathan Snook, http://www.snook.ca/jonathan
 * Add-ons by Robert Nyman, http://www.robertnyman.com
 *
 * Some ways to call it
 *
 * To get all a elements in the document with a -Y´info-links¡ class.
 *
 * getElementsByClassName(document, "a", "info-links");
 *
 *
 * To get all div elements within the element named ´container¡, 
 * with a ´col¡ class.
 *
 * getElementsByClassName(document.getElementById("container"), "div", "col");
 *
 *
 * To get all elements within in the document with a ´click-me¡ class.
 *
 * getElementsByClassName(document, "*", "click-me") ;
 *
 */
CreateCatalog.prototype.getElementsByClassName = 
    function(oElm, strTagName, strClassName)
{
    var arrElements = (strTagName == "*" && oElm.all) ? oElm.all : oElm.getElementsByTagName(strTagName);

    strClassName = strClassName.replace(/\-/g, "\\-");
    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");

    var arrReturnElements = new Array();
    for(var i=0; i<arrElements.length; i++)
    {
        var oElement = arrElements[i];      
        if(oRegExp.test(oElement.className))
	{
	    arrReturnElements.push(oElement);
	}   
    }

    return (arrReturnElements)
}

/*
 * Luo uuden keksin.
 *
 * Parametrit:
 *
 * name            - Luotavan keksin nimi. (pakollinen)
 * value           - Luotavan keksin arvo. (pakollinen)
 * days            - Aika johon asti luotava keksi on voimassa.(vaihtoehtoinen)
 *
 * Rutiinia voidaan kutsua myös ilman days parametria, jolloin
 * keksi poistetaan kun käyttäjä sulkee selainikkunan tai sivulta
 * kutsutaan erikseen Catalog.eraseCookie-rutiinia.
 *
 */
CreateCatalog.prototype.createCookie = function(name, value, days)
{
    if (days)
    {
	var date = new Date();
	date.setTime(date.getTime()+(days*24*60*60*1000));
	var expires = "; expires="+date.toGMTString();
    }
    else var expires = "";
    document.cookie = name+"="+value+expires+"; path=/";
}

/*
 * Lukee keksin arvon.
 *
 * Parametrit:
 *
 * name - Luettavan keksin nimi. (pakollinen)
 *
 * Rutiini palauttaa keksin arvon jos keksi löytyy ja jos ei löydy, niin
 * rutiini palauttaa null-arvon.
 *
 */
CreateCatalog.prototype.readCookie = function(name)
{
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
	var c = ca[i];
	while (c.charAt(0)==' ') c = c.substring(1,c.length);
	if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}

/*
 * Poistaa keksin.
 *
 * Parametrit:
 *
 * name - Poistettavan keksin nimi. (pakollinen)
 *
 * Rutiini poistaa keksin.
 *
 */
CreateCatalog.prototype.eraseCookie = function(name)
{
    this.createCookie(name, "", -1);
}

/*
 * Liittää container_class-parametrissa määritellyn tyyliluokan mukaisten
 * elementtien child_elements_tag-tagisiin lapsiin
 * events-parametrissa määritetyt tapahtumat.
 *
 * Parametrit:
 *
 * container_class    - Elementin luokkanimi, jonka alta lapsielementtejä 
 *                      haetaan. (vaihtoehtoinen)
 * child_elements_tag - Haettavien lapsielementtien tagin nimi.
 *                      (vaihtoehtoinen)
 * events             - Eventit, jotka sidotaan lapsielementteihin.
 *                      * Oletuksena asetetaan onmouseover ja onmouseout
 *                        eventit, joissa asetetaan elementille luokka
 *                        data-highlight.
 *                      (vaihtoehtoinen)
 *
 */
CreateCatalog.prototype.setEvents =
    function(container_class, child_elements_tag, events)
{
    if (typeof(container_class) == "undefined")
    {
	container_class = "dataemo";
    }

    if (typeof(child_elements_tag) == "undefined")
    {
	child_elements_tag = "tr";
    }

    if (typeof(events) == "undefined")
    {
	events = {
	    "mouseover": 
	       	function (e) {this.className = "data-highlight";},
	    "mouseout" :
	       	function (e) {this.className = "";}
// 	    "mouseover": 
// 	       	function (e) {$(this).addClassName("data-highlight");},
// 	    "mouseout" :
// 	       	function (e) {$(this).removeClassName("data-highlight");}
	};
    }

    var tables = 
    	Catalog.getElementsByClassName(document, '*', container_class);

    for (var element_index = 0; element_index < tables.length; element_index++)
    {
        var rows = 
	    tables[element_index].getElementsByTagName(child_elements_tag);

	for (var row_index = 0 ; row_index < rows.length ; row_index++)
	{
	    rows[row_index].onmouseover = 
		function (e) {this.className = "data-highlight"};
	    rows[row_index].onmouseout = 
		function (e) {this.className = ""};
	    // Jostain syystä IE ei tykkää tästä tavasta?!?!
//  	    for (event in events)
//  	    {
//  		Event.observe(rows[row_index], event, events[event]);
//  	    }
	}
    }
}


/*
 * Asettaa (hidden) input-kentät arvon ja sitä vastaavan
 * tekstielemtin, yleensä divin arvon. Käytetään popup-valinlistasivuilla,
 * jossa valinnan perusteella asetetaan emosivulle valinta.
 *
 *
 * Parametrit:
 */
CreateCatalog.prototype.setSelection =
    function(id, value, text)
{
    var input = document.getElementById(id+"_input");
    input.value = value;
    
    var disp = document.getElementById(id+"_text");
    disp.innerHTML = text;
    
    return false;

}

/*	
 * Sorttaa valintalistan	
 *	
 */
CreateCatalog.prototype.sortSelect = 
    function(sortselect)
{
   var copyOption = new Array();
   for (var copy_index = 0 ; 
   	copy_index < sortselect.options.length ; 
	copy_index++)
   {
      var value = sortselect.options[copy_index].value;
      var text = sortselect.options[copy_index].text;

      copyOption[copy_index] = new Array(value, text);
   }

   copyOption.sort(this.sortFunc);

   sortselect.options.length = 0;

   for (var option_index = 0 ; 
   	option_index < copyOption.length ; 
	option_index++)
   {
      var value = copyOption[option_index][0];
      var text = copyOption[option_index][1];

      var option = new Option(text, value);
      sortselect.options[sortselect.length] = option;
   }
}

CreateCatalog.prototype.sortFunc = 
    function (a, b)
{
    var al = a[1].toLowerCase();
    var bl = b[1].toLowerCase();
    
    if (al < bl) return -1;
    
    if (al > bl) return 1;
    
    return 0;   
}



/*
 * Asettaa select multiple-tyyppiseen elementtiin nimi/arvoparin
 *
 * Parametrit:
 */
CreateCatalog.prototype.addSelection =
    function(id, value, text)
{
    var select = document.getElementById(id+"_input");
    
    // tarkistaan, onko valittu arvo jo listassa. Jos on,
    // ei tehdä mitään
    for (index = 0; index < select.options.length; index++)
    {
	if (select.options[index].value == value) {
	    return false;
	}
    }
    
    var option = new Option(text, value);    
    select.options[select.length] = option;
    sortSelect(select);
    return false;
}


CreateCatalog.prototype.deleteSelection =
    function(select)
{
    
    for (index = 0; index < select.options.length; index++)
    {
	if (select.options[index].selected) {
	    select.options[index] = null;
	    index --;
	}
    }
    
    return false;
}


/* ************************************************************************
 * 
 * Rutiineja valitus/ei valitut-tyyppisten valintalistojen käsittelyyn
 *
 * ************************************************************************ */

CreateCatalog.prototype.multilistSelectItems = 
function(field)
{
   var unselect = document.getElementById(field + '_unselected');
   var select = document.getElementById(field);

   this.multilistTransferSelectedOptions(unselect, select);

   this.sortSelect(select);
}

CreateCatalog.prototype.multilistUnselectItems = 
function(field)
{
   var unselect = document.getElementById(field + '_unselected');
   var select = document.getElementById(field);

   this.multilistTransferSelectedOptions(select, unselect);

   this.sortSelect(unselect);
}

CreateCatalog.prototype.multilistTransferSelectedOptions =
function(source_select, target_select)
{
   for (var source_index = 0 ;
   	source_index < source_select.options.length ; 
	source_index++)
   {
      if (source_select.options[source_index].selected)
      {
      	 var value = source_select.options[source_index].value;
	 var text = source_select.options[source_index].text;

         var option = new Option(text, value);

	 target_select.options[target_select.length] = option;

	 source_select.options[source_index] = null;

	 // Pienennetään indeksiä, koska remove-rutiini 
	 // lyhentää listaa yhdellä
	 source_index--;
      }
   }
}

/*
 * Asetetaan valituiksi sellaiset multiple select-elementit, joita
 * vastaava elemetti löytyy id-arvolla id + "_unselected"
 */
CreateCatalog.prototype.multilistSelectAllSelects =
function(form)
{
   var selects = form.getElementsByTagName('select');
   for (var select_index = 0 ; select_index < selects.length ; select_index++)
   {
      var select = selects[select_index];

      if (!select.multiple || select.id.match(/_unselected$/))
      {
         continue;
      }
      
      //
      // Tarkistetaan vielä, että löytyy vastaava _unselected-elementti.
      // Muuten kyseessä ei ole multilist-tyyppinen systeemi, ja voisi tulla
      // asetettu valituiksi myös vääriä select-elementtejä
      //
      /*
      var unselected = document.getElementById(select.id + "_unselected");
      if (!(unselected && (unselected.tagName == "SELECT"))) {
	  continue;
      }
      */
	  

      for (var option_index = 0 ; 
      	   option_index < select.options.length ; 
	   option_index++)
      {
         select.options[option_index].selected = true;
      }
   }
}



/*
 *  Käytetään multilistUpdateSelections-rutiinista
 */
CreateCatalog.prototype._checkOptions = 
    function(options, updated_selections)
{

    for (var i = options.length-1; i >= 0;  i--) {
	// poistetaan valinta
	if (updated_selections[options[i].value] == null) {
	    options[i] = null;
	}
	// poistetaan listalta, koska ei tarvitse enää käsitellä
	else {
	    updated_selections[options[i].value] = null;
	}
    }
   
}
/*
 *  Påivitetään valintalistojen sisältä. Tätä kutstutaan sivulta, yleensä
 *  erillisestä popup-ikkunasta, jolla valintoja pidetään yllä. 
 */
CreateCatalog.prototype.multilistUpdateSelections = 
    function (field, updated_selections)
{
    // tarkistetaan, onko valintalistalta poistettu elementtejä

    // TODO: Alla tehdään kahteen kertaan lähes täsmällee sama
    // homma, eli olisi siistimpää siirtä se omaan alirutiiniin

    var selected = document.getElementById(field);
    var options = selected.options;
    this._checkOptions(options, updated_selections);

    var unselected = document.getElementById(field+"_unselected");
    var options = unselected.options;
    this._checkOptions(options, updated_selections);

    // loput jäljelle jääneet elementit lisätään unselected-listalle
    for (value in updated_selections) {
	var text = updated_selections[value];
	if (!text) continue;


	var option = new Option(text, value);
	//var option = document.createElement("OPTION");
	//option.value = value;
	//option.text = text;
	
	try {
	    unselected.add(option, null); 
	    // standards compliant; doesn't work in IE
	}
	catch(ex) {
	    unselected.add(option); // IE only
	}
    }

    this.sortSelect(selected);
    this.sortSelect(unselected);
}

/*	
 *
 * Lisätään selectAllSelects, jotta vanhat templaatit eivät menisi rikki
 *	
 */

function selectAllSelects(formObj)
{
    Catalog.multilistSelectAllSelects(formObj);
}


// /*
//  * Muuttaa avatun ponnahdusikkunan kooksi ikkunan sisällön koon, paitsi
//  * jos sisältö menee yli ruudun koon.
//  *
//  */
// CreateCatalog.prototype.resizePopupToContent = function(element, width, height)
// {
//     var offsetWidth = 0; var offsetHeight = 0;

//     if (typeof(width) != "undefined")
//     {
// 	offsetWidth = width;
//     }

//     if (typeof(height) != "undefined")
//     {
// 	offsetHeight = height;
//     }

//     if (typeof(element) == "undefined")
//     {
// 	element = window.document.body;
//     }

//     while (element.childNodes)
//     {
// 	offsetHeight += element.offsetHeight;
// 	offsetWidth += element.offsetWidth;

	
//  	this.resizePopupToContent(element.firstChild, 
//  				  offsetWidth, offsetHeight);
//     }
    
//      window.resizeTo(offsetWidth, offsetHeight);
//  }

// /*
//  * Näyttää tooltip-tekstin.
//  *
//  * Parametrit:
//  *
//  * elem_id - Elementin id, jonka sisällä tooltip näytetään.
//  * tooltip - Tooltip-teksti.
//  *
//  */
// CreateCatalog.prototype.showToolTip = function(elem_id, tooltip)
// {
//     var element = document.getElementById(elem_id);

//     while (element.firstChild)
//     {
// 	element.removeChild(element.firstChild);
//     }

//     var textNode = document.createTextNode(tooltip);
//     element.appendChild(textNode);
// }

