/**
 * prototype.js
 *
 * Version 0.3 20040406
 *
 * (c) Top 21 GmbH
 *
 * Diverse prototype-Erweiterungen von js-Objekten
 *
 * @todo: 	Vereinheitlichung der Datums-Patterns
 *				Vereinheitlichung der Funktionen unter Einbeziehung der schon vorhandenen Funktionen
 *
 */
var MONTH_NAMES = new Array("Januar", "Februar", "M\u00e4rz", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember");
var DAY_NAMES = new Array("Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag");
//Object.prototype.scrollTop = scrollTop;

function scrollTop()
{
   if(document.all)
   {
      // ie
      if(document.documentElement != 0)
      {
         // ie 6
         pyo = document.documentElement.scrollTop;
      }
      else
      {
         // ie < 6
         pyo = document.body.scrollTop;
      }
   }
   else
   {
      // moz
      pyo = this.window.pageYOffset;
      // bei Frames funktioniert dies hier nicht - pyo auf 0 setzen
      if(pyo == "undefined")
      {
         pyo = 0;
      }
   }
   return pyo;
}
/**
 * Funktion entfernt Whitespaces am Anfang und am Ende eines Strings
 *
 * @extends Object String
 *
 * @author andi r.
 * @version 20040406
 */
String.prototype.trim = function()
{
   return this.replace(/^(\s|\u00a0)+/g, '').replace(/(\s|\u00a0)+$/g, '');
}
/**
 * Funktion entfernt alle Whitespaces eines Strings
 *
 * @extends Object String
 *
 * @author andi r.
 * @version 20040406
 */
String.prototype.removeWhitespace = function()
{
   return this.replace(/(\s|\u00a0)+/g, '');
}
/**
 * Funktion wandelt den ersten Buchstaben eines Strings in Gro\u00dfbuchstaben
 *
 * @extends Object String
 *
 * @author andi r.
 * @version 20040126
 */
String.prototype.capitalize = capitalize;

function capitalize()
{
   var first = this.substring(0, 1);
   var rest = this.substring(1, this.length);
   first = first.toUpperCase();
   return first + rest;
}
/**
 * Mozilla-DefineGetter f?r Cross-Browser Kompatibilit\u00e4t
 *
 * @author andi r.
 * @version 20040126
 */
if(!document.all)
{
   /**
    * Simuliert die Eigenschaft srcElement f?r Mozilla
    *
    * @extends Event
    *
    * @author andi r.
    * @version 20040126
    */
   Event.prototype.__defineGetter__("srcElement",

   function()
   {
      return this.target;
   }
   );
   /**
    * Simuliert die Eigenschaft attachEvent f?r Mozilla
    *
    * @extends HTMLElement
    *
    * @author (Original) Erik Arvidsson erik@eae.net
    * @author andi r.
    * @version 20040126
    */
   HTMLElement.prototype.attachEvent = function(sType, fHandler)
   {
      var shortTypeName = sType.replace(/on/, "");
      switch(shortTypeName)
      {
         // Die Eventnamen von Microsoft und Mozilla sind teilweise nicht kompatibel
      case "keydown" :
         {
            shortTypeName = "keypress";
            break;
         }
      case "keyup" :
         {
            shortTypeName = "keyrelease";
            break;
         }
      }
      fHandler._ieEmuEventHandler = function(e)
      {
         window.event = e;
         return fHandler();
      };
      this.addEventListener(shortTypeName, fHandler._ieEmuEventHandler, false);
   };
   /**
    * Simuliert die Eigenschaft detachEvent f?r Mozilla
    *
    * @extends HTMLElement
    *
    * @author (Original) Erik Arvidsson erik@eae.net
    * @author andi r.
    * @version 20040126
    */
   HTMLElement.prototype.detachEvent = function(sType, fHandler)
   {
      var shortTypeName = sType.replace(/on/, "");
      switch(shortTypeName)
      {
         // Die Eventnamen von Microsoft und Mozilla sind teilweise nicht kompatibel
      case "keydown" :
         {
            shortTypeName = "keypress";
            break;
         }
      case "keyup" :
         {
            shortTypeName = "keyrelease";
            break;
         }
      }
      if( typeof fHandler._ieEmuEventHandler == "function") this.removeEventListener(shortTypeName, fHandler._ieEmuEventHandler, false);
      else // we can always try :-)
      this.removeEventListener(shortTypeName, fHandler, true);
   };
}
/**
 * Simulieren der Eigenschaften insertAdjacentHTML(), insertAdjacentText() and insertAdjacentElement f?r Mozilla
 *
 * @author Thor Larholm thor@jscript.dk
 * @version 20040126
 */
if(typeof HTMLElement != "undefined")
{
   HTMLElement.prototype.insertAdjacentElement = function(where, parsedNode)
   {
      switch(where)
      {
         case 'beforeBegin' :
            {
               this.parentNode.insertBefore(parsedNode, this);
               break;
            }
         case 'afterBegin' :
            {
               this.insertBefore(parsedNode, this.firstChild);
               break;
            }
         case 'beforeEnd' :
            {
               this.appendChild(parsedNode);
               break;
            }
         case 'afterEnd' :
            {
               if(this.nextSibling) this.parentNode.insertBefore(parsedNode, this.nextSibling);
               else this.parentNode.appendChild(parsedNode);
               break;
            }
      }
   }
   HTMLElement.prototype.insertAdjacentHTML = function(where, htmlStr)
   {
      var r = this.ownerDocument.createRange();
      r.setStartBefore(this);
      var parsedHTML = r.createContextualFragment(htmlStr);
      this.insertAdjacentElement(where, parsedHTML)
   }
   HTMLElement.prototype.insertAdjacentText = function(where, txtStr)
   {
      var parsedText = document.createTextNode(txtStr);
      this.insertAdjacentElement(where, parsedText);
   }
   	try {
	  // create span element so that HTMLElement is accessible
	  document.createElement('span');
	  HTMLElement.prototype.click = function () {
	    if (typeof this.onclick == 'function')
	      this.onclick({type: 'click'});
	  };
	}
	catch (e) {
	  alert('click method for HTMLElement couldn\'t be added')
	}
}
/**
 * Erweitert das String-Objekt um eine Funktion, die bei einzelnen Zahlen eine 0 vorne anstellt
 *
 * @extends Date
 * @return (number) kalenderwoche
 *
 * @author andi r.
 * @version 20040126
 *
 */
String.prototype.zweistellig = function()
{
   var retStr = new String();
   if(this.length < 2)
   {
      retStr = "0" + this;
   }
   else
   {
      retStr = this;
   }
   return retStr;
}
/**
 * Utility functions for parsing in getDateFromFormat()
 */

function LZ(x)
{
   return(x < 0 || x > 9 ? "" : "0") + x;
}
/**
 * Erweitert das String-Objekt
 *
 */
String.prototype._isInteger = function()
{
   var digits = "1234567890";
   for(var i = 0; i < this.length; i++)
   {
      if(digits.indexOf(this.charAt(i)) == - 1)
      {
         return false;
      }
   }
   return true;
}
/**
 * Erweitert das String-Objekt
 *
 */
String.prototype._getInt = function(i, minlength, maxlength)
{
   for(var x = maxlength; x >= minlength; x--)
   {
      var token = this.substring(i, i + x);
      if(token.length < minlength)
      {
         return null;
      }
      if(token._isInteger())
      {
         return token;
      }
   }
   return null;
}
/**
 * Erweitert das Date-Objekt um eine Datumsformatierung
 *
 * @argument format
 * @extends Date
 * @return (string) Datum
 *
 *
 * Field        | Full Form          | Short Form
 * -------------+--------------------+-----------------------
 * Year         | yyyy (4 digits)    | yy (2 digits), y (2 or 4 digits)
 * Month        | MMM (name or abbr.)| MM (2 digits), M (1 or 2 digits)
 *              | NNN (abbr.)        |
 * Day of Month | dd (2 digits)      | d (1 or 2 digits)
 * Day of Week  | EE (name)          | E (abbr)
 * Hour (1-12)  | hh (2 digits)      | h (1 or 2 digits)
 * Hour (0-23)  | HH (2 digits)      | H (1 or 2 digits)
 * Hour (0-11)  | KK (2 digits)      | K (1 or 2 digits)
 * Hour (1-24)  | kk (2 digits)      | k (1 or 2 digits)
 * Minute       | mm (2 digits)      | m (1 or 2 digits)
 * Second       | ss (2 digits)      | s (1 or 2 digits)
 * AM/PM        | a                  |
 *
 * NOTE THE DIFFERENCE BETWEEN MM and mm! Month=MM, not mm!
 * Examples:
 *  "MMM d, y" matches: January 01, 2000
 *                      Dec 1, 1900
 *                      Nov 20, 00
 *  "M/d/yy"   matches: 01/20/00
 *                      9/2/00
 *  "MMM dd, yyyy hh:mm:ssa" matches: "January 01, 2000 12:30:45AM"
 * ------------------------------------------------------------------
 *
 * @author andi r.
 * @version 20040317
 *
 * @author original Scripter: Matt Kruse <matt@mattkruse.com>
 * @author original url http:http://www.mattkruse.com
 *
 */
Date.prototype.formatDate = function(format)
{
   // Standard-Formatierung
   if(format == null && !format)
   {
      format = "dd.MM.yyyy HH:mm";
   }
   format = format + "";
   var result = "";
   var i_format = 0;
   var c = "";
   var token = "";
   var y = this.getYear() + "";
   var M = this.getMonth() + 1;
   var d = this.getDate();
   var E = this.getDay();
   var H = this.getHours();
   var m = this.getMinutes();
   var s = this.getSeconds();
   var yyyy, yy, MMM, MM, dd, hh, h, mm, ss, ampm, HH, H, KK, K, kk, k;
   // Convert real date parts into formatted versions
   var value = new Object();
   if(y.length < 4)
   {
      y = "" +(y - 0 + 1900);
   }
   value["y"] = "" + y;
   value["yyyy"] = y;
   value["yy"] = y.substring(2, 4);
   value["M"] = M;
   value["MM"] = LZ(M);
   value["MMM"] = MONTH_NAMES[M - 1];
   value["NNN"] = MONTH_NAMES[M + 11];
   value["d"] = d;
   value["dd"] = LZ(d);
   value["E"] = DAY_NAMES[E + 7];
   value["EE"] = DAY_NAMES[E];
   value["H"] = H;
   value["HH"] = LZ(H);
   if(H == 0)
   {
      value["h"] = 12;
   }
   else if(H > 12)
   {
      value["h"] = H - 12;
   }
   else
   {
      value["h"] = H;
   }
   value["hh"] = LZ(value["h"]);
   if(H > 11)
   {
      value["K"] = H - 12;
   }
   else
   {
      value["K"] = H;
   }
   value["k"] = H + 1;
   value["KK"] = LZ(value["K"]);
   value["kk"] = LZ(value["k"]);
   if(H > 11)
   {
      value["a"] = "PM";
   }
   else
   {
      value["a"] = "AM";
   }
   value["m"] = m;
   value["mm"] = LZ(m);
   value["s"] = s;
   value["ss"] = LZ(s);
   while(i_format < format.length)
   {
      c = format.charAt(i_format);
      token = "";
      while((format.charAt(i_format) == c) &&(i_format < format.length))
      {
         token += format.charAt(i_format++);
      }
      if(value[token] != null)
      {
         result = result + value[token];
      }
      else
      {
         result = result + token;
      }
   }
   return result;
}
/**
 * Erweitert das String-Objekt um die M?glichkeit, mittels eines
 * Patterns aus einem String ein Datum zu erzeugen
 *
 * @argument format
 * @extends Date
 * @return (Date) Datum
 *
 *
 * Field        | Full Form          | Short Form
 * -------------+--------------------+-----------------------
 * Year         | yyyy (4 digits)    | yy (2 digits), y (2 or 4 digits)
 * Month        | MMM (name or abbr.)| MM (2 digits), M (1 or 2 digits)
 *              | NNN (abbr.)        |
 * Day of Month | dd (2 digits)      | d (1 or 2 digits)
 * Day of Week  | EE (name)          | E (abbr)
 * Hour (1-12)  | hh (2 digits)      | h (1 or 2 digits)
 * Hour (0-23)  | HH (2 digits)      | H (1 or 2 digits)
 * Hour (0-11)  | KK (2 digits)      | K (1 or 2 digits)
 * Hour (1-24)  | kk (2 digits)      | k (1 or 2 digits)
 * Minute       | mm (2 digits)      | m (1 or 2 digits)
 * Second       | ss (2 digits)      | s (1 or 2 digits)
 * AM/PM        | a                  |
 *
 * NOTE THE DIFFERENCE BETWEEN MM and mm! Month=MM, not mm!
 * Examples:
 *  "MMM d, y" matches: January 01, 2000
 *                      Dec 1, 1900
 *                      Nov 20, 00
 *  "M/d/yy"   matches: 01/20/00
 *                      9/2/00
 *  "MMM dd, yyyy hh:mm:ssa" matches: "January 01, 2000 12:30:45AM"
 * ------------------------------------------------------------------
 *
 * @author andi r.
 * @version 20040317
 *
 * @author original Scripter: Matt Kruse <matt@mattkruse.com>
 * @author original url http:http://www.mattkruse.com
 *
 */
String.prototype.getDateFromFormat = function(format)
{
   format = format + "";
   var i_val = 0;
   var i_format = 0;
   var c = "";
   var token = "";
   var token2 = "";
   var x, y;
   var now = new Date();
   var year = now.getYear();
   var month = now.getMonth() + 1;
   var date = 1;
   var hh = 0;
   //now.getHours();
   var mm = 0;
   //now.getMinutes();
   var ss = 0;
   //now.getSeconds();
   var ampm = "";
   while(i_format < format.length)
   {
      // Get next token from format string
      c = format.charAt(i_format);
      token = "";
      while((format.charAt(i_format) == c) &&(i_format < format.length))
      {
         token += format.charAt(i_format++);
      }
      // Extract contents of value based on format token
      if(token == "yyyy" || token == "yy" || token == "y")
      {
         if(token == "yyyy")
         {
            x = 4;
            y = 4;
         }
         if(token == "yy")
         {
            x = 2;
            y = 2;
         }
         if(token == "y")
         {
            x = 2;
            y = 4;
         }
         year = this._getInt(i_val, x, y);
         if(year == null)
         {
            return 0;
         }
         i_val += year.length;
         if(year.length == 2)
         {
            if(year > 70)
            {
               year = 1900 +(year - 0);
            }
            else
            {
               year = 2000 +(year - 0);
            }
         }
      }
      else if(token == "MMM" || token == "NNN")
      {
         month = 0;
         for(var i = 0; i < MONTH_NAMES.length; i++)
         {
            var month_name = MONTH_NAMES[i];
            if(this.substring(i_val, i_val + month_name.length).toLowerCase() == month_name.toLowerCase())
            {
               if(token == "MMM" ||(token == "NNN" && i > 11))
               {
                  month = i + 1;
                  if(month > 12)
                  {
                     month -= 12;
                  }
                  i_val += month_name.length;
                  break;
               }
            }
         }
         if((month < 1) ||(month > 12))
         {
            return 0;
         }
      }
      else if(token == "EE" || token == "E")
      {
         for(var i = 0; i < DAY_NAMES.length; i++)
         {
            var day_name = DAY_NAMES[i];
            if(this.substring(i_val, i_val + day_name.length).toLowerCase() == day_name.toLowerCase())
            {
               i_val += day_name.length;
               break;
            }
         }
      }
      else if(token == "MM" || token == "M")
      {
         month = this._getInt(i_val, token.length, 2);
         if(month == null ||(month < 1) ||(month > 12))
         {
            return 0;
         }
         i_val += month.length;
      }
      else if(token == "dd" || token == "d")
      {
         date = this._getInt(i_val, token.length, 2);
         if(date == null ||(date < 1) ||(date > 31))
         {
            return 0;
         }
         i_val += date.length;
      }
      else if(token == "hh" || token == "h")
      {
         hh = this._getInt(i_val, token.length, 2);
         if(hh == null ||(hh < 1) ||(hh > 12))
         {
            return 0;
         }
         i_val += hh.length;
      }
      else if(token == "HH" || token == "H")
      {
         hh = this._getInt(i_val, token.length, 2);
         if(hh == null ||(hh < 0) ||(hh > 23))
         {
            return 0;
         }
         i_val += hh.length;
      }
      else if(token == "KK" || token == "K")
      {
         hh = this._getInt(i_val, token.length, 2);
         if(hh == null ||(hh < 0) ||(hh > 11))
         {
            return 0;
         }
         i_val += hh.length;
      }
      else if(token == "kk" || token == "k")
      {
         hh = this._getInt(i_val, token.length, 2);
         if(hh == null ||(hh < 1) ||(hh > 24))
         {
            return 0;
         }
         i_val += hh.length;
         hh--;
      }
      else if(token == "mm" || token == "m")
      {
         mm = this._getInt(i_val, token.length, 2);
         if(mm == null ||(mm < 0) ||(mm > 59))
         {
            return 0;
         }
         i_val += mm.length;
      }
      else if(token == "ss" || token == "s")
      {
         ss = this._getInt(i_val, token.length, 2);
         if(ss == null ||(ss < 0) ||(ss > 59))
         {
            return 0;
         }
         i_val += ss.length;
      }
      else if(token == "a")
      {
         if(this.substring(i_val, i_val + 2).toLowerCase() == "am")
         {
            ampm = "AM";
         }
         else if(this.substring(i_val, i_val + 2).toLowerCase() == "pm")
         {
            ampm = "PM";
         }
         else
         {
            return 0;
         }
         i_val += 2;
      }
      else
      {
         if(this.substring(i_val, i_val + token.length) != token)
         {
            return 0;
         }
         else
         {
            i_val += token.length;
         }
      }
   }
   // If there are any trailing characters left in the value, it doesn't match
   if(i_val != this.length)
   {
      return 0;
   }
   // Is date valid for month?
   if(month == 2)
   {
      // Check for leap year
      if(((year % 4 == 0) &&(year % 100 != 0)) ||(year % 400 == 0))
      {
         // leap year
         if(date > 29)
         {
            return 0;
         }
      }
      else
      {
         if(date > 28)
         {
            return 0;
         }
      }
   }
   if((month == 4) ||(month == 6) ||(month == 9) ||(month == 11))
   {
      if(date > 30)
      {
         return 0;
      }
   }
   // Correct hours value
   if(hh < 12 && ampm == "PM")
   {
      hh = hh - 0 + 12;
   }
   else if(hh > 11 && ampm == "AM")
   {
      hh -= 12;
   }
   var newdate = new Date(year, month - 1, date, hh, mm, ss);
   return newdate;
}
/**
 * Erweitert das Date-Objekt um die ISO-Kalenderwoche
 *
 * @extends Date
 * @return (number) kalenderwoche
 *
 * @author andi r.
 * @version 20040126
 *
 */
Date.prototype.getCalWeek = function()
{
   var jh = this.getYear();
   if(jh < 1900) jh += 1900;
   jh++;
   var kalwo = kaldiff(this, jh);
   while(kalwo < 1)
   {
      jh--;
      kalwo = kaldiff(this, jh);
   }
   return kalwo;
}

function kaldiff(datum, jahr)
{
   var d4j = new Date(jahr, 0, 4);
   var wt4j =(d4j.getDay() + 6) % 7;
   return Math.floor(1.05 +(datum.getTime() - d4j.getTime()) /6048e5+wt4j/ 7);
}
/**
 * date-objekt um den test nach Schaltjahr erweitern
 *
 * @Extends: Date
 * @Author: andi r.
 * @Version: 20040402
 */
Date.prototype.isLeapYear = function()
{
   if((this.getFullYear() % 4) == 0)
   {
      if((this.getFullYear() % 100 == 0) &&(this.getFullYear() % 400) != 0)
      {
         return false;
      }
      else
      {
         return true;
      }
   }
   else
   {
      return false;
   }
}
/**
 * Date-objekt mit Addierfunktionen erweitern
 *
 * @argument: z (int) Einheiten, um die addiert werden soll
 * @Extends: Date
 * @Author: andi r.
 * @Version: 20040406
 */
Date.prototype.addYear = function(z)
{
   if(z == null)
   {
      z = 1;
   }
   var z = parseInt(z, 10);
   var t = this.getFullYear();
   this.setYear(t + z);
}
Date.prototype.addMonth = function(z)
{
   if(z == null)
   {
      z = 1;
   }
   var z = parseInt(z, 10);
   var t = this.getMonth();
   var d = t + z;
   while(d > 11)
   {
      d = d - 12;
      this.addYear();
   }
   this.setMonth(d);
}
Date.prototype.addDate = function(z)
{
   if(z == null)
   {
      z = 1;
   }
   var DaysInMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
   var isLeap = new Boolean(this.isLeapYear());
   if(isLeap)
   {
      DaysInMonth[1] = 29;
   }
   var z = parseInt(z, 10);
   var t = this.getDate();
   var d = t + z;
   while(d > DaysInMonth[this.getMonth()])
   {
      d = d - DaysInMonth[this.getMonth()];
      this.addMonth();
   }
   this.setDate(d);
}
Date.prototype.addHours = function(z)
{
   if(z == null)
   {
      z = 1;
   }
   var z = parseInt(z, 10);
   var t = this.getHours();
   var d = t + z;
   while(d > 23)
   {
      d = d - 24;
      this.addDay();
   }
   this.setHours(d);
}
Date.prototype.addMinutes = function(z)
{
   if(z == null)
   {
      z = 1;
   }
   var z = parseInt(z, 10);
   var t = this.getMinutes();
   var d = t + z;
   while(d > 59)
   {
      d = d - 60;
      this.addHours();
   }
   this.setMinutes(d);
}
Date.prototype.addSeconds = function(z)
{
   if(z == null)
   {
      z = 1;
   }
   var z = parseInt(z, 10);
   var t = this.getSeconds();
   var d = t + z;
   while(d > 59)
   {
      d = d - 60;
      this.addMinutes();
   }
   this.setSeconds(d);
}
Date.prototype.addTime = function(z)
{
   if(z == null)
   {
      z = 1;
   }
   var z = parseInt(z, 10);
   var t = this.getTime();
   this.setTime(t + z);
}
/**
 * date-objekt um die funktion erweitern, ein Datum aufzuaddieren
 *
 * @Extends Date
 * @Argument a (number) anzahl der einheiten zum aufaddieren
 * @Argument f (string) k?rzel der einheit: yyyy -> Jahr, q -> Quartal, m -> Monat, ww -> Woche, d -> Tag
 *														  h -> Stunde, n -> Minute, s -> Sekunde, l -> Milisekunde
 * @Author: andi r.
 * @Version 20040405
 */
Date.prototype.DateAdd = function(a, f)
{
   var a = parseInt(a, 10);
   var f = f.toString();
   switch(f)
   {
      case "yyyy" :
         {
            this.addYear(a);
            break;
         }
      case "q" :
         {
            a = a * 3;
            this.addMonth(a);
            break;
         }
      case "m" :
         {
            this.addMonth(a);
            break;
         }
      case "ww" :
         {
            a = a * 7;
            break;
         }
      case "d" :
         {
            this.addDate(a);
            break;
         }
      case "h" :
         {
            this.addHours(a);
            break;
         }
      case "n" :
         {
            this.addMinutes(a);
            break;
         }
      case "s" :
         {
            this.addSeconds(a);
            break;
         }
      case "l" :
         {
            this.addTime(a);
            break;
         }
      default :
         {
            throw new Error('Die Einheit: ' + f + ' ist nicht erlaubt!\nErlaubt sind:"yyyy", "q", "m", "ww", "d", "h", "n", "s", "l".');
         }
   }
   return this;
}
/**
 * Erweitert das Boolean-Objekt um eine Funktion, die den Wert umkehrt
 *
 * @return new Boolean
 * @extends Boolean
 * @author andi r.
 * @version 20040326
 *
 */
Boolean.prototype.reverse = function()
{
   var thisBool = new Boolean(this);
   var returnVal = new String('true');
   if(thisBool)
   {
      returnVal = 'false';
   }
   return new Boolean(returnVal);
}
/**
 * liefert den absoluten absoluten Abstand
 * eines elements vom oberen Seitenrand
 *
 * @argument ev (event)
 * @return top (number) Abstand in Pixeln
 *
 * @author andi R.
 * @version 20040419
 */

function getEventPositionTop(ev)
{
   var myTarget = ev.srcElement;
   var top = new Number();
   while(myTarget != document.body && myTarget != document.documentElement)
   {
      try
      {
         top += myTarget.offsetTop;
         myTarget = myTarget.offsetParent;
      }
      catch(e)
      {
         break;
      }
   }
   return top;
}
/**
 * liefert den absoluten absoluten Abstand
 * eines elements vom rechten Seitenrand
 *
 * @argument ev (event)
 * @return left (number)
 *
 * @author andi R.
 * @version 20040419
 */

function getEventPositionLeft(ev)
{
   var myTarget = ev.srcElement;
   var left = new Number();
   while(myTarget != document.body && myTarget != document.documentElement)
   {
      try
      {
         left += myTarget.offsetLeft;
         myTarget = myTarget.offsetParent;
      }
      catch(e)
      {
         break;
      }
   }
   return left;
}
/**
 * Quelle: http://www.mozilla.org/docs/dom/technote/whitespace/
 * Workaround fuer seltsames Verhalten des Mozillas bei formatiertem xml
 * (interpretiert whitespace zwischen nodes als text-nodes!)
 *
 * Throughout, whitespace is defined as one of the characters
 *  "\t" TAB \u0009
 *  "\n" LF  \u000A
 *  "\r" CR  \u000D
 *  " "  SPC \u0020
 *
 * This does not use Javascript's "\s" because that includes non-breaking
 * spaces (and also some other characters).
 */
/**
 * Determine whether a node's text content is entirely whitespace.
 *
 * @param nod  A node implementing the |CharacterData| interface (i.e.,
 *             a |Text|, |Comment|, or |CDATASection| node
 * @return     True if all of the text content of |nod| is whitespace,
 *             otherwise false.
 */

function is_all_ws(nod)
{
   // Use ECMA-262 Edition 3 String and RegExp features
   return !(/[^\t\n\r ]/.test(nod.data));
}
/**
 * Determine if a node should be ignored by the iterator functions.
 *
 * @param nod  An object implementing the DOM1 |Node| interface.
 * @return     true if the node is:
 *                1) A |Text| node that is all whitespace
 *                2) A |Comment| node
 *             and otherwise false.
 */

function is_ignorable(nod)
{
   return(nod.nodeType == 8) || // A comment node
   ((nod.nodeType == 3) && is_all_ws(nod)); // a text node, all ws
}
/**
 * Version of |previousSibling| that skips nodes that are entirely
 * whitespace or comments.  (Normally |previousSibling| is a property
 * of all DOM nodes that gives the sibling node, the node that is
 * a child of the same parent, that occurs immediately before the
 * reference node.)
 *
 * @param sib  The reference node.
 * @return     Either:
 *               1) The closest previous sibling to |sib| that is not
 *                  ignorable according to |is_ignorable|, or
 *               2) null if no such node exists.
 */

function node_before(sib)
{
   while((sib = sib.previousSibling))
   {
      if(!is_ignorable(sib))
      return sib;
   }
   return null;
}
/**
 * Version of |nextSibling| that skips nodes that are entirely
 * whitespace or comments.
 *
 * @param sib  The reference node.
 * @return     Either:
 *               1) The closest next sibling to |sib| that is not
 *                  ignorable according to |is_ignorable|, or
 *               2) null if no such node exists.
 */

function node_after(sib)
{
   while((sib = sib.nextSibling))
   {
      if(!is_ignorable(sib))
      return sib;
   }
   return null;
}
/**
 * Version of |lastChild| that skips nodes that are entirely
 * whitespace or comments.  (Normally |lastChild| is a property
 * of all DOM nodes that gives the last of the nodes contained
 * directly in the reference node.)
 *
 * @param sib  The reference node.
 * @return     Either:
 *               1) The last child of |sib| that is not
 *                  ignorable according to |is_ignorable|, or
 *               2) null if no such node exists.
 */

function last_child(par)
{
   var res = par.lastChild;
   while(res)
   {
      if(!is_ignorable(res))
      return res;
      res = res.previousSibling;
   }
   return null;
}
/**
 * Version of |firstChild| that skips nodes that are entirely
 * whitespace and comments.
 *
 * @param sib  The reference node.
 * @return     Either:
 *               1) The first child of |sib| that is not
 *                  ignorable according to |is_ignorable|, or
 *               2) null if no such node exists.
 */

function first_child(par)
{
   var res = par.firstChild;
   while(res)
   {
      if(!is_ignorable(res))
      return res;
      res = res.nextSibling;
   }
   return null;
}
/**
 * Version of |data| that doesn't include whitespace at the beginning
 * and end and normalizes all whitespace to a single space.  (Normally
 * |data| is a property of text nodes that gives the text of the node.)
 *
 * @param txt  The text node whose data should be returned
 * @return     A string giving the contents of the text node with
 *             whitespace collapsed.
 */

function data_of(txt)
{
   var data = txt.data;
   // Use ECMA-262 Edition 3 String and RegExp features
   data = data.replace(/[\t\n\r ]+/g, " ");
   if(data.charAt(0) == " ") data = data.substring(1, data.length);
   if(data.charAt(data.length - 1) == " ") data = data.substring(0, data.length - 1);
   return data;
}

/**
 * Testet, ob ein String in einem Array vorhanden ist
 *
 * @argument txt (string)
 * @return (boolean)
 *
 * @author andi r.
 * @version ?
 *
 */

Array.prototype.contains = function(txt)
{
   var ret = new Boolean(false);
   for(var i=0; i<this.length; i++)
   {
      if(this[i] == txt)
      {
         ret = true;
         break;
      }
   }
   return ret;
}
/**
 * entfernt aus einem Array, sofern vorhanden, einen String
 *
 * @argument txt (string)
 * @return ret (string)
 *
 * @author andi r.
 * @version ?
 *
 */

Array.prototype.remove = function(txt)
{
   var ret = '';
   for(var i=0; i<this.length; i++)
   {
      if(this[i] == txt)
      {
         ret = this[i];
         this.splice(i,1);
         break;
      }
   }
   return ret;
}

/**
 * Entfernt leere Felder aus einem Array
 *
 * @author andi r.
 * @version ?
 *
 */
Array.prototype.removeEmpty = function()
{
   for(var i=0; i<this.length; i++)
   {
      if(this[i] == '')
      {
         this.splice(i,1);
      }
   }
   return this;
}

/**
 * simuliert die coldfusion-isDefined-methode
 *
 * @argument var (object)
 * @return (boolean)
 *
 * @author ??
 * @version 20040726
 *

function isDefined(var)
{
   if(typeof(var) != "undefined")
   {
      return true;
   }
   else
   {
      return false;
   }
} */

/**
 * Importiert eine Javascript-Datei (in externen Scripten funktioniert
 * dies jedoch nicht im IE!). Sollte bei Verwendung im Head der Seiten stehen
 *
 * @return void
 *
 * @version 0.8 20050707
 * @author Andreas Reichert
 * @author (c) Top 21 GmbH
 *
 */


function Import(url)
{
   document.write('<script src="', url, '" type="text/JavaScript"><\/script>');
}

/**
 * Erzeugt ein javascript-objekt, in dem url-variablen in
 * javascript-Variablen des Objektes umgewandelt werden
 *
 * @return Boolean - konnten Variablen erzeugt werden?
 *
 * @version 0.6 20040414
 * @author Andreas Reichert
 * @author (c) Top 21 GmbH
 *
 */

function url()
{
   this.fieldNames = new Array();
   // Array enth?lt alle erzeugten Variablennamen
   this.struct = new Array();
   // Ein Assoziatives Array, in dem alle Variablen als key/value-paar vorhanden sind
   this.length;
   // Anzahl der Variablen, die aus dem URL-String erzeugt wurden
   var search = document.location.search;
   var outer = new Array();
   var inner = new Array();
   var key = new String();
   var val = new String();
   if(search.length) // url-Variablen??
   {
      search = search.replace(/^\?/g, '');
      // Fragezeichen am Anfang entfernen
      var outer = search.split('&');
      // in einzelne key/val-paare aufsplitten
      for(var i = 0; i < outer.length; i++)
      {
         var inner = outer[i].split('=');
         // key/val auseinanderdr?seln
         try
         {
            var key = inner[0];
            var val = inner[1];
            eval("this." + key + "='" + val + "';");
            // variable erzeugen
            this.fieldNames[i] = key;
            // fieldName anh\u00e4ngen
            this.struct[key] = val;
            // struct setzen
            this.length = outer.length;
            // l\u00e4nge setzen
            //return new Boolean('true');
         }
         catch(e)
         {
         	//return new Boolean('false');
         }
      }
   }
   else
   {
   	//return new Boolean('false');
   }
   // macht aus den Variblen aus dem
   // form-scope lokale Variablen
   this.toLocalVariables = function()
   {
      for(var i = 0; i < this.fieldNames.length; i++)
      {
         eval(this.fieldNames[i] + " = '" + this.struct[this.fieldNames[i]] + "';");
      }
   }
}
url = new url();