/**
 * @fileoverview  Contains all JavaScript code needed
 * for the WikiTimeLine extension of MediaWiki.
 * @author Markus Szumovski
 * @version 1.0
 */

/*
WikiTimeLine, a MediaWiki extension for graphical
illustration of historic events in MediaWiki.
Copyright (C) 2008  Markus Szumovski

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

Contact author by e-mail: webmaster@wikitimescale.com
Contact author by mail:
Markus Szumovski
Hirtenbergerstrasse 33
2551 Enzesfeld
Austria
*/

  /** Saves the script path of the file which
      deletes or adds events on the server (server side script).
      Needed for deletion or adding of events.
      @type String
  */
  var wtl_scriptpath='';
  /** Stores references to all yellow info balloon div elements that pop up with information 
      about the event after clicking on the bar or name of the event. The index in this
      array is the HTML-id of the element which was clicked on (the parent element).
      @type Array (HTML-Elements (div))
  */
  var wtl_alldivs=new Array();
  /** Stores references to all yellow balloon div elements that pop up with information 
      about the event after clicking on the bar or name of the event. The index here is
      a variety of three integer-index dimensions. The first is the container number, the
      second is the event number and the third is the number of the balloon in the event
      (depending on whether its the bar or the name...).
      @type Array (HTML-Elements (div))
  */
  var wtl_alldivsnr=new Array();
  /** Defines if a yellow info balloon is shown.
      @type Boolean
  */
  var wtl_showdiv=false;
  /** Temporary value for calculation if yellow info balloon is shown.
      @type Boolean
  */
  var wtl_tmpshowdiv=false;

  /** Continuous number for the HTML-id of HTML-Elements of an event, used as index in the wtl_alldivs 
      Array for the unique yellow info balloon divs. 
      @type Integer
  */
  var wtl_dividnr=0;

  /** References to all container objects with their HTML-id as index.
      @type Array (wtl_container)
  */
  var wtl_alllocs=new Array();
  /** References to all container objects with their container number as index.
      @type Array (wtl_container)
  */
  var wtl_alllocsnr=new Array();

  /** References to the div element for output/print out of error messages.
      Can be set in {@link wtl_setError}.
      @type HTML-Element (div)
  */
  var wtl_errorloc=null;
  /** Error message for 'no more levels free'
      Can be set in {@link wtl_setError}.
      @type String
  */
  var wtl_errormaxlevel='';
  /** Error message for 'reached max. number of events'
      Can be set in {@link wtl_setError}.
      @type String
  */
  var wtl_errormaxevent='';
  /** Error message for 'event too large'
      Can be set in {@link wtl_setError}.
      @type String
  */
  var wtl_errortoolarge='';
  /** Error message for 'cannot zoom out'
      Can be set in {@link wtl_setError}.
      @type String
  */
  var wtl_errorcantzoomout='';
  /** Error message for 'cannot move timeline'
      Can be set in {@link wtl_setError}.
      @type String
  */
  var wtl_errorcantmove='';
  /** Error message for 'endless loop created'
      Can be set in {@link wtl_setError}.
      @type String
  */
  var wtl_errorendlessloop='';
  /** Error message for 'no space to shuffle events'.
      Can be set in {@link wtl_setError}.
      @type String
  */
  var wtl_errornospaceforshuffle='';
  /** Error message for an unknown error.
      Can be set in {@link wtl_setError}.
      @type String
  */
  var wtl_errorunknown='';
  /** Link name for hiding the last error message again.
      @type String
  */
  var wtl_hidemsg='';

/**
 * @class This class is the main javascript part of WikiTimeLine.
 * One object of this class represents one timeline. If there is
 * one main timeline as well as a zoomed out overview Timeline
 * each of the two timelines is represented by one wtl_container
 * object.
 * @constructor
 * @param {String} container_id HTML-ID of the container div. This means: The placeholder div element for the timeline.
 * @param {String} parent_id HTML-ID of the parent div. This means: The placeholder div element which surrounds the container div(s).
 * @param {String} show_id The id of the html-element that will be shown if the containers are hidden
 * @param {String} zoomobj Name of the object where the event will be zoomed in if whished so.
 * @param {String} scriptpath The full path of the scripts to work with in AJAX
 * @param {String} showcontainertoloc URL to call if containers are made visible (AJAX)
 * @param {String} removelasttoloc URL to call if all events are removed (AJAX)
 * @param {Integer} pixel The width of the Container is the whole browser-window-width minux these pixels.
 * @param {Boolean} dynamic Specifies if it is possible that two or more events are in one and the same level 
 *                  (Otherwise, every event has his own level).
 * @param {Integer} maxlevels The number of maximal levels in the timeline. -1 for unlimited.
 * @param {Integer} maxevents The number of maximal events in the timeline. -1 for unlimited.
 * @param {String} fonttype Specifies the font family. Usage exectly like in CSS. For example: 'arial'.
 * @param {Integer} fontsize Specifies the font size. Usage exectly like in CSS.
 * @param {Integer} inzoom Specifies if every day is shown in the timeline (0) if the zoom is high enough,
 *                  or if only the 10th and 20th of each month is shown (1) if the zoom is high enough,
 *                  of if no days are shown (2) no matter how high the zoom is.
 * @param {String} jan Name of first month (the shorter, the better).
 * @param {String} feb Name of second month (the shorter, the better).
 * @param {String} mar Name of third month (the shorter, the better).
 * @param {String} apr Name of fourth month (the shorter, the better).
 * @param {String} may Name of fifth month (the shorter, the better).
 * @param {String} jun Name of sixth month (the shorter, the better).
 * @param {String} jul Name of seventh month (the shorter, the better).
 * @param {String} aug Name of eighth month (the shorter, the better).
 * @param {String} sep Name of ninth month (the shorter, the better).
 * @param {String} oct Name of tenth month (the shorter, the better).
 * @param {String} nov Name of eleventh month (the shorter, the better).
 * @param {String} dec Name of twelfth month (the shorter, the better).
 * @param {String} text_ongoing Text for ongoing event.
 * @param {String} text_zoomevent Text for zooming in on event.
 * @param {String} text_from Text for 'From:' in event-date displaying
 * @param {String} text_to Text for 'To:' in event-date displaying
 * @param {String} text_or Text for 'or' in event-date displaying
 * @param {String} text_remove Text for removing event.
 */
function wtl_container(container_id, parent_id, show_id, zoomobj, scriptpath, showcontainertoloc, removelasttoloc, pixel, dynamic, maxlevels, maxevents, fonttype, fontsize, inzoom, jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec,
                       text_ongoing, text_zoomevent, text_from, text_to, text_or, text_remove)
{
  /** Saves the script path of the file which
      deletes or adds events on the server (server side script).
      Needed for deletion or adding of events.
      @type String
  */
  wtl_scriptpath=scriptpath;
  /** Saves the script name which will be called via AJAX
      if containers are made visible
      @type String
  */
  this.wtl_showcontainertoloc=showcontainertoloc;
  /** Saves the script name which will be called via AJAX
      if the last event should be removed;
      @type String
  */
  this.wtl_removelasttoloc=removelasttoloc;
  /** Name of the object where the event will be
      zoomed in if whished so.
      @type String
  */
  this.wtl_zoomobj=zoomobj;

  /** Text for ongoing events
      @type String
  */
   this.text_ongoing=text_ongoing;
  /** Text for zooming in on event.
      @type String
  */
  this.text_zoomevent=text_zoomevent;
  /** Text for 'From:' in event-date displaying
      @type String
  */
  this.text_from=text_from;
  /** Text for 'To:' in event-date displaying
      @type String
  */
  this.text_to=text_to;
  /** Text for 'or' in event-date displaying
      @type String
  */
  this.text_or=text_or;
  /** Text for removing event.
      @type String
  */
  this.text_remove=text_remove;

  /** True if left mouse button is clicked and down and
      every mousemove should be considered as moving
      the timeline.
      @type Boolean
  */
  this.mousemove=false;
  /** Last horizontal mouse cursor position. Needed for calculating
      mouse movement.
      @type Integer
  */
  this.sourcex=0;
  /** Reference to the div placeholder element for the timeline container.
      @type HTML-Element (Div)
  */
  this.loc=null;
  /** Reference to the div placeholder element which surrounds the 
      timeline container(s).
      @type HTML-Element (Div)
  */
  this.locparent=null;
  /** Reference to the div element which displays the start date in the
      upper left corner of the container/timeline. The div element
      is created at runtime.
      @type HTML-Element (Div)
  */
  this.startdiv=null;
  /** Reference to the div element which displays the start date in the
      lower left corner of the container/timeline. The div element
      is created at runtime.
      @type HTML-Element (Div)
  */
  this.startdiv2=null;
  /** Reference to the div element which displays the end date in the
      upper right corner of the container/timeline. The div element
      is created at runtime.
      @type HTML-Element (Div)
  */
  this.enddiv=null;
  /** Reference to the div element which displays the end date in the
      lower right corner of the container/timeline. The div element
      is created at runtime.
      @type HTML-Element (Div)
  */
  this.enddiv2=null;
  /** Reference to the div element which displays the lower horizontal line
      on which the dates are displayed. The div element is created at runtime.
      @type HTML-Element (Div)
  */
  this.wtl_divdown=null;
  /** Reference to the div element which displays the upper horizontal line
      on which the dates are displayed. The div element is created at runtime.
      @type HTML-Element (Div)
  */
  this.wtl_divup=null;
  /** This array stores which events are displayed at which level. Therefore it
      is two dimensional: The first dimension is the level (starts with 0) and in
      the second dimension the numbers of the elements in this level are stored.
      @type Array
  */
  this.levelarray=new Array();

  /** Stores the year of the lowest starting date (or alternative starting date) of all events.
      @type Integer
  */
   this.wtl_minfromyear=0;
  /** Stores the month of the lowest starting date (or alternative starting date) of all events.
      @type Integer
  */
   this.wtl_minfrommonth=1;
  /** Stores the day of the lowest starting date (or alternative starting date) of all events.
      @type Integer
  */
   this.wtl_minfromday=1;
  /** Stores the year of the highest ending date (or alternative ending date) of all events.
      @type Integer
  */
   this.wtl_maxtoyear=0;
  /** Stores the month of the highest ending date (or alternative ending date) of all events.
      @type Integer
  */
   this.wtl_maxtomonth=1;
  /** Stores the day of the highest ending date (or alternative ending date) of all events.
      @type Integer
  */
   this.wtl_maxtoday=1;

  /** Stores the year of the exact starting date of the timeline (meaning the displayed range).
      @type Integer
  */
   this.wtl_exactfromyear=0;
  /** Stores the month of the exact starting date of the timeline (meaning the displayed range).
      @type Integer
  */
   this.wtl_exactfrommonth=1;
  /** Stores the day of the exact starting date of the timeline (meaning the displayed range).
      This can be a float number because a day is possibly shown only partially.
      @type Float
  */
   this.wtl_exactfromday=1;
  /** Stores the year of the exact ending date of the timeline (meaning the displayed range).
      @type Integer
  */
   this.wtl_exacttoyear=0;
  /** Stores the month of the exact ending date of the timeline (meaning the displayed range).
      @type Integer
  */
   this.wtl_exacttomonth=1;
  /** Stores the day of the exact ending date of the timeline (meaning the displayed range).
      This can be a float number because a day is possibly shown only partially.
      @type Float
  */
   this.wtl_exacttoday=2;

  /** Stores the year of the first starting date of the timeline (meaning the displayed range) which
      is shown fully (meaning the starting date with the day not partially but fully shown).
      @type Integer
  */
   this.wtl_fullfromyear=0;
  /** Stores the month of the first starting date of the timeline (meaning the displayed range) which
      is shown fully (meaning the starting date with the day not partially but fully shown).
      @type Integer
  */
   this.wtl_fullfrommonth=1;
  /** Stores the day of the first starting date of the timeline (meaning the displayed range) which
      is shown fully (meaning the starting date with the day not partially but fully shown).
      @type Integer
  */
   this.wtl_fullfromday=1;
  /** Stores the year of the last ending date of the timeline (meaning the displayed range) which
      is shown fully (meaning the ending date with the day not partially but fully shown).
      @type Integer
  */
   this.wtl_fulltoyear=0;
  /** Stores the month of the last ending date of the timeline (meaning the displayed range) which
      is shown fully (meaning the ending date with the day not partially but fully shown).
      @type Integer
  */
   this.wtl_fulltomonth=1;
  /** Stores the day of the last ending date of the timeline (meaning the displayed range) which
      is shown fully (meaning the ending date with the day not partially but fully shown).
      @type Integer
  */
   this.wtl_fulltoday=2;

  /** Stores the year of the exact starting date of the timeline (meaning the displayed range).
      @type Integer
  */
   this.wtl_partfromyear=0;
  /** Stores the month of the exact starting date of the timeline (meaning the displayed range).
      @type Integer
  */
   this.wtl_partfrommonth=1;
  /** Stores the day of the exact starting date of the timeline (meaning the displayed range).
      Difference to wtl_exactfrommonth: The day is not stored as float but rounded down. Needed
      for displaying.
      @type Integer
  */
   this.wtl_partfromday=1;
  /** Stores the year of the exact ending date of the timeline (meaning the displayed range).
      @type Integer
  */
   this.wtl_parttoyear=0;
  /** Stores the month of the exact ending date of the timeline (meaning the displayed range).
      @type Integer
  */
   this.wtl_parttomonth=1;
  /** Stores the day of the exact ending date of the timeline (meaning the displayed range).
      Difference to wtl_exacttomonth: The day is not stored as float but rounded down. Needed
      for displaying.
      @type Integer
  */
   this.wtl_parttoday=2;

  /** The width of the timeline (meaning the displayed range) in days.
      @type Float
  */
   this.wtl_days=0;
  /** The height of the container/timeline in pixel.
      @type Integer
  */
   this.wtl_height=0;

  /** Date format: The first date part to show in a date. Can be 'D' for day,
      'M' for Month or 'Y' for year. Standard is day. Can be set with {@link wtl_container#setDateFormat}.
      @type String
  */
   this.wtl_firstYMD='D';
  /** Date format: The second date part to show in a date. Can be 'D' for day,
      'M' for Month or 'Y' for year. Standard is month. Can be set with {@link wtl_container#setDateFormat}.
      @type String
  */
   this.wtl_secondYMD='M';
  /** Date format: The third date part to show in a date. Can be 'D' for day,
      'M' for Month or 'Y' for year. Standard is year. Can be set with {@link wtl_container#setDateFormat}.
      @type String
  */
   this.wtl_thirdYMD='Y';
  /** Date format: Defines if the month are written down with their names or numbers,
      True for names, false for numbers. Standard is true (names). Can be set with {@link wtl_container#setDateFormat}.
      @type Boolean
  */
   this.wtl_nameMonth=true;
  /** Date format: The sign that is shown after the first date part.
      Standard is point ('.'). Can be set with {@link wtl_container#setDateFormat}.
      @type String
  */
   this.wtl_signAfterFirstYMD='.';
  /** Date format: The sign that is shown after the second date part.
      Standard is point ('.'). Can be set with {@link wtl_container#setDateFormat}.
      @type String
  */
   this.wtl_signAfterSecondYMD='.';
  /** Date format: The sign that is shown after the third date part.
      Standard is nothing (''). Can be set with {@link wtl_container#setDateFormat}.
      @type String
  */
   this.wtl_signAfterThirdYMD='';
  /** Date format: The sign that is used as thousand separator in the year number.
      Standard is comma (','). Can be set with {@link wtl_container#setDateFormat}.
      @type String
  */
   this.wtl_thousandSign=',';
  /** Date format: The sign that is printed out before the date (and the first date part).
      Standard is nothing (''). Can be set with {@link wtl_container#setDateFormat}.
      @type String
  */
   this.wtl_signBeforeDate='';
  /** Date format: The sign that is printed out after the date.
      Standard is nothing (''). Can be set with {@link wtl_container#setDateFormat}.
      @type String
  */
   this.wtl_signAfterDate='';

  /** The width of the letter M (the widest letter).
      Needed to calculate text-width.
      @type Integer
  */
   this.wtl_textwidth=0;
  /** The width of the digit 0 (the widest digit).
      Needed to calculate number-width.
      @type Integer
  */
   this.wtl_digitwidth=0;

   if(window.innerWidth)
   {
     /** The width of the container/timeline in pixel.
         @type Integer
     */
      this.wtl_pixel=window.innerWidth-pixel;
   }
   else if(document.body.clientWidth)
      this.wtl_pixel=document.body.clientWidth-pixel;
   else
      this.wtl_pixel=pixel;

  /** The length of all month in days. Starting with 0 (first month)
      and ending with 11 (last month).
      @type Array (Integer)
  */
   this.wtl_marr=new Array();
  /** The name of all month. Starting with 0 (first month)
      and ending with 11 (last month).
      @type Array (String)
  */
   this.wtl_marrname=new Array();
  /**  The width of a day in pixel. Or differently expressed: How many pixels is a day.
       This can be much larger than 1 or much smaller than 1 and depends on the zoom.
      @type Float
  */
   this.wtl_abs=0;
  /**  The width of a pixel in days. Or differently expressed: How many days is a pixel.
       This can be much larger than 1 or much smaller than 1 and depends on the zoom.
      @type Float
  */
   this.wtl_pixdays=0;

  /**  The type of connection this container has.
       0 Means no connection.
       1 Means connected to another container, but this container is the primary container/main timeline (and the other the secondary container/overview timeline).
       2 Means connected to another container, and this container is the secondary container/overview timeline (and the other the primary container/main timeline).
      @type Integer
  */
   this.wtl_connection=0; /* 0 if no con., 1 if primary, 2 if secondary */
  /**  The zoom-out percentage of the secondary container/overview timeline.
      @type Integer
  */
   this.wtl_adaptpercent=0;
  /**  The reference to the other container if connection is established.
      @type wtl_container
  */
   this.wtl_connobj=null;

  /**  If the current displayed start year (that is the first year
       displayed on the horizontal date lines) is odd, meaning it
       is a five at the front with any zeros behind (the only possible
       years have a one or a five in front). 
       So: True means it is a five at the front, False means it is a
       one at the front.
      @type Boolean
  */
   this.wtl_isodd=true;
  /** Which months are displayed each year on the horizontal date line. Stores the number
      of months which have to be added to come to the next month.
      0 means no month are displayed, 6 means only two Month are displayed,
      4 means 3 months are displayed, 3 means 4 months are displayed, 2 will
      display 6 months (every second month) and 1 means every month is displayed.
      @type Integer
  */
   this.wtl_stepmonths=0;
  /** Stores the number of years which have to be added to the last year displayed on the
      horizontal date line to come to the next year which is displayed on the horizontal date line.
      @type Integer
  */
   this.wtl_stepyears=1;
  /** Which days are displayed each month on the horizontal date line.
      0 means no days are displayed, 10 means day 10 and 20 are displayed and
      1 means all days are displayed. This can be overrided with the parameter
      inzoom at the {@link wtl_container constructor}.
      @type Integer
  */
   this.wtl_stepdays=0;
  /** The current first year which is displayed on the horizontal date line. This doesn't
      mean it is the first year realy visible since it will only be visible if the first day
      of the first month of this year is shown. But it will already be displayed (without beeing noticed
      by the user) if it will be the next year visible on the horizontal date line if the timeline
      is moved back in time.
      @type Integer
  */
   this.wtl_startdlyear=0;

  /** The global number of the container. No matter how many containers are used, every one has his own
      container number (created automatically).
      @type Integer
  */
   this.wtl_contnr=wtl_alllocsnr.length;

  /** Stores if there can be more than one event in one level (true) or if every event needs its own level (false).
      @type Boolean
  */
   this.wtl_dynamic=dynamic;

  /** Stores all displayed events and their data. See {@link wtl_container#createEvent} for more information on how this array is put together.
      @type Array
  */
   this.wtl_events=new Array();

  /** Stores all years which are displayed on the horizontal date lines, along with their data. Some entries may be
      null (the array may not be filled completly), but not for long since such empty places are filled with new entries
      as they come along.
      @type Array
  */
   this.wtl_dlyears=new Array();
  /** Stores the index of the years in the wtl_dlyears array in the correct order (meaning earlier years are stored earlier in the array).
      This is needed since the wtl_dlyears array is neither ordered nor complete (it is possible that entries in wtl_dlyears are null)
      @type Array (Integer)
  */
   this.wtl_dlyearsorder=new Array();

  /** Left position of the container's div element in pixel.
      @type Integer
  */
   this.locleft=0;
  /** Left position of the ending date div elements inside the container in pixel.
      @type Integer
  */
   this.wtl_enddivleft=0;
  /** Next index number of a possible new event in the array wtl_events
      @type Integer
  */
   this.wtl_neweventnr=0;

  /** Height of one event-bar in pixel
      @type Integer
  */
   this.wtl_barheight=12;
  /** Height of the space between two event-bars in pixel
      @type Integer
  */
   this.wtl_barspace=4;

  /** Maximal number of levels in the container/timeline. -1 for unlimited number of levels.
      @type Integer
  */
   this.wtl_maxlevels=maxlevels;
  /** Maximal number of events in the container/timeline. -1 for unlimited number of events.
      @type Integer
  */
   this.wtl_maxevents=maxevents;

  /** The space in pixel between that is used over the first und under the last event to gain space
      from the top and the bottom of the container/timeline.
      @type Integer
  */
   this.wtl_margespace=20;
  /** The space in pixel that must be free between the end of the displayedname of one bar and the
      beginning of the next bar to the right. If it is possible that the space will be smaller, the
      name of the bar will no longer be displayed.
      @type Integer
  */
   this.wtl_pixbetween=5;
  /** Defines if days are displayed and how many are displayed on the horizontal date line.
      0 for no days are displayed (no matter how high the zoom is), 1 for only day 10 and
      20 of a month are displayed if the zoom is high enough, and 2 for all days are displayed
      if the zoom is high enough.
      @type Integer
  */
   this.wtl_inzoom=inzoom;

  /** The name of the fonttype/fontfamily. Same as the CSS attribute font-family
      @type String
  */
   this.wtl_fontfamily=fonttype;
  /** The size of the font. Same as the CSS attribute font-size
      @type Integer
  */
   this.wtl_fontsize=fontsize;

  /** Value of the red level in the background of the timeline/container.
      Value can be between 0 and 255.
      @type Integer
  */
   this.wtl_bgred=235;
  /** Value of the green level in the background of the timeline/container.
      Value can be between 0 and 255.
      @type Integer
  */
   this.wtl_bggreen=235;
  /** Value of the blue level in the background of the timeline/container.
      Value can be between 0 and 255.
      @type Integer
  */
   this.wtl_bgblue=235;

  /** CSS value of the background color. The CSS function 'rgb' is used here.
      @type Integer
  */
   this.wtl_bgrgb='rgb(' + this.wtl_bgred + ',' + this.wtl_bggreen + ',' + this.wtl_bgblue + ')';

   this.wtl_marr[0]=31;
   this.wtl_marr[1]=29;
   this.wtl_marr[2]=31;
   this.wtl_marr[3]=30;
   this.wtl_marr[4]=31;
   this.wtl_marr[5]=30;
   this.wtl_marr[6]=31;
   this.wtl_marr[7]=31;
   this.wtl_marr[8]=30;
   this.wtl_marr[9]=31;
   this.wtl_marr[10]=30;
   this.wtl_marr[11]=31;

   this.wtl_marrname[0]=jan;
   this.wtl_marrname[1]=feb;
   this.wtl_marrname[2]=mar;
   this.wtl_marrname[3]=apr;
   this.wtl_marrname[4]=may;
   this.wtl_marrname[5]=jun;
   this.wtl_marrname[6]=jul;
   this.wtl_marrname[7]=aug;
   this.wtl_marrname[8]=sep;
   this.wtl_marrname[9]=oct;
   this.wtl_marrname[10]=nov;
   this.wtl_marrname[11]=dec;

  /** Stores which event is lying in which level. First dimension is the level, second dimension lists
      the index numbers (in the wtl_events Array) of all events in this level.
      @type Array (Integer)
  */
   this.wtl_levels=new Array();

  /** Stores a reference to the div element which should contain the container.
      @type HTML-Element (div)
  */
   this.loc=document.getElementById(container_id);
  /** Stores a reference to the div element which surrounds the container div element
      (stored in loc) of this container as well as the div element of a possible connected
      container.
      @type HTML-Element (div)
  */
   this.locparent=document.getElementById(parent_id);

   if(this.locparent!=null)
      this.locparent.style.width=this.wtl_pixel + 'px';

   /** HTML-id of the div element where the show-again Message is placed.
       @type String
   */
   this.wtl_showid=show_id;

   this.loc.style.fontSize=this.wtl_fontsize + 'px';
   this.loc.style.fontFamily=this.wtl_fontfamily;
/*
   this.startdiv = document.createElement("div");
   this.startdiv.appendChild(document.createTextNode(""));
   this.startdiv2 = document.createElement("div");
   this.startdiv2.appendChild(document.createTextNode(""));
   this.enddiv = document.createElement("div");
   this.enddiv.appendChild(document.createTextNode(""));
   this.enddiv2 = document.createElement("div");
   this.enddiv2.appendChild(document.createTextNode(""));
*/
   wtl_alldivsnr[this.wtl_contnr]=new Array();
   wtl_alllocs[container_id]=this;
   wtl_alllocsnr[this.wtl_contnr]=this;

  /** We need that to know if the container is currently visible or not.
      @type Boolean
  */
   this.wtl_visible=false;

   /* now we make the container visible (if there are no events, we'll
      hide him again in startContainer). That's because we'll need some
      width information we'll only get if it's visible */
/*
     if(this.locparent!=null)
     {
        this.locparent.style.lineHeight=(this.wtl_fontsize + 3) + 'px';
        this.locparent.style.display='block';
     }
     else
     {
        this.loc.style.lineHeight=(this.wtl_fontsize + 3) + 'px';
        this.loc.style.display='block';
     }
*/
}

/**
 * If the user clicked on one of the events (exactly: on the
 * bar or the name of an event), then this function is called and
 * will open a yellow info balloon. See {@link #wtl_mouseoutclickdiv}.
 */
function wtl_mouseclickdiv(ev)
{
   var divobj=wtl_alldivs[this.id];

   divobj.style.display='block';
   divobj.style.position='absolute';

   if(wtl_showdiv==false)
      wtl_tmpshowdiv=true;
}

/**
 * If the user clicked outside of all events, then this
 * function is called and will close all open yellow info
 * balloons. See {@link #wtl_mouseclickdiv}.
 */
function wtl_mouseoutclickdiv(ev)
{
   var divobj; //=wtl_alldivs[this.id];
   var i;
   var o;
   var u;

   if(wtl_showdiv==true)
   {
      for(u=0;u<wtl_alldivsnr.length;u++)
      {
         for(i=0;i<wtl_alldivsnr[u].length;i++)
         {
            for(o=0;o<wtl_alldivsnr[u][i].length;o++)
            {
               divobj=wtl_alldivsnr[u][i][o];
               divobj.style.display='none';
            }
         }
      }

      wtl_showdiv=false;
   }
   else if(wtl_tmpshowdiv==true)
   {
      wtl_showdiv=true;
      wtl_tmpshowdiv=false;
   }
}

/**
 * If the user moves the mouse over one of the containers,
 * then this function is called. If has clicked with a
 * mousebutton and holds this button, then the timeline will move.
 * See {@link #wtl_mousedowncontainer} and {@link #wtl_mouseupcontainer}.
 */
function wtl_mousemovecontainer(ev)
{
   var x;
   var pixel;
   var locobj=wtl_alllocs[this.id];

   if(!ev)
      ev=window.event;
   if(locobj.mousemove)
   {
      x=ev.screenX-locobj.sourcex;
      locobj.sourcex=ev.screenX;

      pixel=x*-1;

      locobj.moveStartDate(pixel,x);

      locobj.drawAllYearLines();

      locobj.drawAllBars(x);

    //  locobj.showStartEndDate();
   }
}

/**
 * If the user clicks a mousebutton,
 * then this function is called. It will enable the moving
 * of the timeline. See {@link #wtl_mousemovecontainer}.
 */
function wtl_mousedowncontainer(ev)
{
   var locobj=wtl_alllocs[this.id];

   if(!ev)
      ev=window.event;

   locobj.mousemove=true;
   locobj.sourcex=ev.screenX;
}

/**
 * If the user releases a mousebutton,
 * then this function is called. It will disable the moving
 * of the timeline again. See {@link #wtl_mousedowncontainer}
   and {@link #wtl_mousemovecontainer}.
 */
function wtl_mouseupcontainer(ev)
{
   var i;

   for(i=0;i<wtl_alllocsnr.length;i++)
      wtl_alllocsnr[i].mousemove=false;
}

/**
 * Creates a XMLHttpRequest object for AJAX if possible.
 * This object will be used to add or remove an event 
 * without reloading the page (instead, the information of
 * adding or removing is sent asynchronus to the server 
 * with this object). If AJAX (to be exact: the XMLHttpRequest
 * object) is not supported by the browser, null will be returned
 * See {@link wtl_container#addEventLink} and {@link #wtl_removeEventLink}.
 * @return The XMLHttpRequest object if AJAX is supported, or null if AJAX is not supported
 * @type XMLHttpRequest object
 */
function wtl_getXHR()
{
    if (window.XMLHttpRequest) // Mozilla, Safari, ...
    { 
       return new XMLHttpRequest();
    }
    else if (window.ActiveXObject)  // IE
    {
       try { return new ActiveXObject("Msxml2.XMLHTTP.6.0") } catch(e) {}
       try { return new ActiveXObject("Msxml2.XMLHTTP.3.0") } catch(e) {}
       try { return new ActiveXObject("Msxml2.XMLHTTP") }     catch(e) {}
       try { return new ActiveXObject("Microsoft.XMLHTTP") }  catch(e) {}
    }

    return null;
}

/**
 * Checks if AJAX is possible, and if so, makes all AJAX
 * elements visible.
 * @param {String} elements_block_name Name of the elements which should be made visible as blocks. Or empty string for none.
 * @param {String} elements_inline_name Name of the elements which should be made visible, but inlinne. Or empty string for none.
 * @param {String} elements_hide_name Name of the elements which should be hidden. Or empty string for none.
 */
function wtl_checkAJAX(elements_block_name, elements_inline_name, elements_hide_name)
{
    var xhr;
    var elements;
    var i;
    var attr;

    xhr=wtl_getXHR();

    if(xhr!=null)
    {
       if(elements_block_name!='')
       {
          elements=document.getElementsByTagName('div');
          for(i=0;i<elements.length;i++)
          {
             attr=elements[i].getAttribute('name');
             if(attr==elements_block_name)
                elements[i].style.display='block';
          }
          elements=document.getElementsByTagName('span');
          for(i=0;i<elements.length;i++)
          {
             attr=elements[i].getAttribute('name');
             if(attr==elements_block_name)
                elements[i].style.display='block';
          }
       }
       if(elements_inline_name!='')
       {
          elements=document.getElementsByTagName('div');
          for(i=0;i<elements.length;i++)
          {
             attr=elements[i].getAttribute('name');
             if(attr==elements_inline_name)
                elements[i].style.display='inline';
          }
          elements=document.getElementsByTagName('span');
          for(i=0;i<elements.length;i++)
          {
             attr=elements[i].getAttribute('name');
             if(attr==elements_inline_name)
                elements[i].style.display='inline';
          }
       }
       if(elements_hide_name!='')
       {
          elements=document.getElementsByName(elements_hide_name);
          for(i=0;i<elements.length;i++)
          {
             elements[i].style.display='none';
          }
       }
    }
}

/**
 * Sets the date format.
 * @param {String} firstYMD The first date part to show in a date. Can be 'D' for day, 'M' for Month or 'Y' for year.
 * @param {String} secondYMD The second date part to show in a date. Can be 'D' for day, 'M' for Month or 'Y' for year.
 * @param {String} thirdYMD The third date part to show in a date. Can be 'D' for day, 'M' for Month or 'Y' for year.
 * @param {Boolean} nameMonth Defines if the month are written down with their names or numbers. True for names, false for numbers.
 * @param {String} signAfterFirstYMD The sign that is shown after the first date part.
 * @param {String} signAfterSecondYMD The sign that is shown after the second date part.
 * @param {String} signAfterThirdYMD The sign that is shown after the third date part.
 * @param {String} thousandSign The sign that is used as thousand separator in the year number.
 * @param {String} signBeforeDate The sign that is printed out before the date (and the first date part).
 * @param {String} signBeforeDate The sign that is printed out after the date.
 */
wtl_container.prototype.setDateFormat = function (firstYMD, secondYMD, thirdYMD, nameMonth, signAfterFirstYMD, signAfterSecondYMD, signAfterThirdYMD, thousandSign, signBeforeDate, signAfterDate)
{
   this.wtl_firstYMD=firstYMD;
   this.wtl_secondYMD=secondYMD;
   this.wtl_thirdYMD=thirdYMD;
   this.wtl_nameMonth=nameMonth;
   this.wtl_signAfterFirstYMD=signAfterFirstYMD;
   this.wtl_signAfterSecondYMD=signAfterSecondYMD;
   this.wtl_signAfterThirdYMD=signAfterThirdYMD;
   this.wtl_thousandSign=thousandSign;
   this.wtl_signBeforeDate=signBeforeDate;
   this.wtl_signAfterDate=signAfterDate;
}

/**
 * Expects year, month and day as parameters and will return the
 * date in the set date-format as string.
 * See {@link wtl_container#setDateFormat}
 * @param {Integer} year Year of the date.
 * @param {Integer} month Month of the date.
 * @param {Integer} day Day of the date.
 * @return The date as string, in the format defined with {@link wtl_container#setDateFormat}
 * @type String
 */
wtl_container.prototype.getDateStr = function (year, month, day)
{
   var datestr;

   return this.wtl_signBeforeDate + this.getYMD(year,month,day,this.wtl_firstYMD) + this.wtl_signAfterFirstYMD + 
                                    this.getYMD(year,month,day,this.wtl_secondYMD) + this.wtl_signAfterSecondYMD + 
                                    this.getYMD(year,month,day,this.wtl_thirdYMD) + this.wtl_signAfterThirdYMD + 
          this.wtl_signAfterDate;
}

/**
 * Adds the thousand-separator to a number.
 * @param {String} numb number
 * @return The number with thousand-separators
 * @type String
 */
wtl_container.prototype.addSeparator = function (numb)
{
   var minus='';

   if(numb.substr(0,1)=='-')
   {
      minus='-';
      numb=numb.substr(1);
   }
   while (numb.match(/^\d\d{3}/))
   {
      numb= numb.replace(/(\d)(\d{3}([^\d]|$))/, '$1' + this.wtl_thousandSign + '$2');
   }
   return minus + numb;
}

/**
 * Gets the correct date part, formatted in the right way, for the current part of the date.
 * @param {Integer} year Year of the date
 * @param {Integer} month Month of the date
 * @param {Integer} day Day of the date
 * @param {String} sign Defines the current part. Can be 'Y' for year, 'M' for month or 'D' for day.
 * @return The year, month or day of the date part, depending on which of those are wished for the current
 *         date part according to the setting with {@link wtl_container#setDateFormat}.
 * @type String
 */
wtl_container.prototype.getYMD = function (year, month, day, sign)
{
   if(sign=='Y' || sign=='y')
   {
      return this.addSeparator(year.toString());
   }
   else if(sign=='M' || sign=='m')
   {
      if(this.wtl_nameMonth==false)
         return (month<10?'0'+month:month);
      else
         return this.wtl_marrname[month-1];
   }
   else if(sign=='D' || sign=='d')
   {
      return (day<10?'0'+day:day);
   }
   else
      return '';
}

/**
 * Displays the current start and end date of the timeline in the corners
 * Because of speed problems, it is currently not used.
 */
wtl_container.prototype.showStartEndDate = function ()
{
   var todate;
   var fromdate;
   var edl;

   fromdate=this.getDateStr(this.wtl_partfromyear,this.wtl_partfrommonth,this.wtl_partfromday);
   todate=this.getDateStr(this.wtl_parttoyear,this.wtl_parttomonth,this.wtl_parttoday);

   this.startdiv.firstChild.nodeValue= fromdate;

   this.startdiv2.firstChild.nodeValue= fromdate;

   this.enddiv.firstChild.nodeValue= todate;

   edl=(this.wtl_pixel-this.enddiv.offsetWidth-5);
   this.wtl_enddivleft=edl;

   this.enddiv.style.left=edl + 'px';

   this.enddiv2.firstChild.nodeValue= todate;

   this.enddiv2.style.left=edl + 'px';
}

/**
 * Calculates which year, month and day captions are currently
 * visible on the horizontal date lines (so that they don't interfere
 * with each other) and displays those. Also removes 
 * no longer visible captions.
 * Uses the arrays {@link wtl_container#wtl_dlyears} and
 * {@link wtl_container#wtl_dlyearsorder} heavily.
 */
wtl_container.prototype.setYearsVisible = function ()
{
   var i;
   var nr;
   var nextfree=0;
   var nextfreedown=0;
   var maxfree=this.wtl_pixel;
   var maxfreedown=this.wtl_pixel;
   var u;

   for(i=0;i<this.wtl_dlyearsorder.length;i++)
   {
      nr=this.wtl_dlyearsorder[i];

/*
      if(this.wtl_dlyears[nr]['appended'] &&
         this.wtl_dlyears[nr]['left']>(this.startdiv.offsetWidth+5) &&
        (this.wtl_dlyears[nr]['left']+this.wtl_dlyears[nr]['textwidth'])<(this.wtl_enddivleft-5))
*/
      if(this.wtl_dlyears[nr]['appended'])
      {
         if(this.wtl_dlyears[nr]['upvisible']!=true && this.wtl_dlyears[nr]['downvisible']!=true)
         {

            for(u=i+1;u<this.wtl_dlyearsorder.length && this.wtl_dlyears[this.wtl_dlyearsorder[u]]['upvisible']==false;u++);
 
            if(u<this.wtl_dlyearsorder.length)
               maxfree=this.wtl_dlyears[this.wtl_dlyearsorder[u]]['left'];
            else
               maxfree=this.wtl_pixel;

            for(u=i+1;u<this.wtl_dlyearsorder.length && this.wtl_dlyears[this.wtl_dlyearsorder[u]]['downvisible']==false;u++);
 
            if(u<this.wtl_dlyearsorder.length)
               maxfreedown=this.wtl_dlyears[this.wtl_dlyearsorder[u]]['left'];
            else
               maxfreedown=this.wtl_pixel;

            if(this.wtl_dlyears[nr]['left']>3 && this.wtl_dlyears[nr]['left']>nextfree && (this.wtl_dlyears[nr]['left']+this.wtl_dlyears[nr]['textwidth'])<maxfree)
            {
               nextfree=this.wtl_dlyears[nr]['left']+this.wtl_dlyears[nr]['textwidth']+5;
               this.wtl_dlyears[nr]['upvisible']=true;
               this.wtl_dlyears[nr]['downvisible']=false;
               this.wtl_dlyears[nr]['divtext'].style.display='inline';
               this.wtl_dlyears[nr]['divtext'].style.top='1px';
            }
            else if(this.wtl_dlyears[nr]['left']>3 && this.wtl_dlyears[nr]['left']>nextfreedown && (this.wtl_dlyears[nr]['left']+this.wtl_dlyears[nr]['textwidth'])<maxfreedown)
            {
               nextfreedown=this.wtl_dlyears[nr]['left']+this.wtl_dlyears[nr]['textwidth']+5;
               this.wtl_dlyears[nr]['upvisible']=false;
               this.wtl_dlyears[nr]['downvisible']=true;
               this.wtl_dlyears[nr]['divtext'].style.display='inline';
               this.wtl_dlyears[nr]['divtext'].style.top= (this.wtl_height-13) + 'px';
            }
            else
            {
               this.wtl_dlyears[nr]['upvisible']=false;
               this.wtl_dlyears[nr]['downvisible']=false;
               this.wtl_dlyears[nr]['divtext'].style.display='none';
            }
 
         }
         else if(this.wtl_dlyears[nr]['left']<3 || (this.wtl_dlyears[nr]['left']+this.wtl_dlyears[nr]['textwidth'])>this.wtl_pixel)
         {
            this.wtl_dlyears[nr]['upvisible']=false;
            this.wtl_dlyears[nr]['downvisible']=false;
            this.wtl_dlyears[nr]['divtext'].style.display='none';
         }
      }
      else
      {
         this.wtl_dlyears[nr]['upvisible']=false;
         this.wtl_dlyears[nr]['downvisible']=false;
         this.wtl_dlyears[nr]['divtext'].style.display='none';

      }

      if(this.wtl_dlyears[nr]['upvisible']==true)
      {
         nextfree=this.wtl_dlyears[nr]['left']+this.wtl_dlyears[nr]['textwidth']+5;
      }
      if(this.wtl_dlyears[nr]['downvisible']==true)
      {
         nextfreedown=this.wtl_dlyears[nr]['left']+this.wtl_dlyears[nr]['textwidth']+5;
      }

      for(u=0;u<this.wtl_dlyears[nr]['months'].length;u++)
      {
         if(this.wtl_dlyears[nr]['months'][u]['upvisible']==true)
         {
            this.wtl_dlyears[nr]['months'][u]['textwidth']=this.getTextWidth(this.wtl_dlyears[nr]['months'][u]['divtext'].firstChild.nodeValue);
         }

/*
         if(this.wtl_dlyears[nr]['months'][u]['appended'] &&
            this.wtl_dlyears[nr]['months'][u]['left']>(this.startdiv.offsetWidth+5) &&
           (this.wtl_dlyears[nr]['months'][u]['left']+this.wtl_dlyears[nr]['months'][u]['textwidth'])<(this.wtl_enddivleft-5))
*/
         if(this.wtl_dlyears[nr]['months'][u]['appended'])
         {
            if(this.wtl_dlyears[nr]['months'][u]['left']>3 && this.wtl_dlyears[nr]['months'][u]['left']>nextfree && (this.wtl_dlyears[nr]['months'][u]['left']+this.wtl_dlyears[nr]['months'][u]['textwidth'])<this.wtl_pixel)
            {
               this.wtl_dlyears[nr]['months'][u]['upvisible']=true;
               this.wtl_dlyears[nr]['months'][u]['downvisible']=false;
               this.wtl_dlyears[nr]['months'][u]['divtext'].style.display='inline';
               this.wtl_dlyears[nr]['months'][u]['divtext'].style.top='3px';
            }
            else if(this.wtl_dlyears[nr]['months'][u]['left']>3 && this.wtl_dlyears[nr]['months'][u]['left']>nextfreedown && (this.wtl_dlyears[nr]['months'][u]['left']+this.wtl_dlyears[nr]['months'][u]['textwidth'])<this.wtl_pixel)
            {
               this.wtl_dlyears[nr]['months'][u]['upvisible']=false;
               this.wtl_dlyears[nr]['months'][u]['downvisible']=true;
               this.wtl_dlyears[nr]['months'][u]['divtext'].style.display='inline';
               this.wtl_dlyears[nr]['months'][u]['divtext'].style.top= (this.wtl_height-14) + 'px';
            }
            else
            {
               this.wtl_dlyears[nr]['months'][u]['upvisible']=false;
               this.wtl_dlyears[nr]['months'][u]['downvisible']=false;
               this.wtl_dlyears[nr]['months'][u]['divtext'].style.display='none';
            }
         }
         else
         {
            this.wtl_dlyears[nr]['months'][u]['upvisible']=false;
            this.wtl_dlyears[nr]['months'][u]['downvisible']=false;
            this.wtl_dlyears[nr]['months'][u]['divtext'].style.display='none';
         }

         if(this.wtl_dlyears[nr]['months'][u]['upvisible']==true)
         {
            nextfree=this.wtl_dlyears[nr]['months'][u]['left']+this.wtl_dlyears[nr]['months'][u]['textwidth']+5;
         }
         if(this.wtl_dlyears[nr]['months'][u]['downvisible']==true)
         {
            nextfreedown=this.wtl_dlyears[nr]['months'][u]['left']+this.wtl_dlyears[nr]['months'][u]['textwidth']+5;
         }

         for(o=0;o<this.wtl_dlyears[nr]['months'][u]['days'].length;o++)
         {
            if(this.wtl_dlyears[nr]['months'][u]['days'][o]['upvisible']==true)
            {
               this.wtl_dlyears[nr]['months'][u]['days'][o]['textwidth']=this.getNumberWidth(this.wtl_dlyears[nr]['months'][u]['days'][o]['divtext'].firstChild.nodeValue);
            }

/*
            if(this.wtl_dlyears[nr]['months'][u]['days'][o]['appended'] &&
               this.wtl_dlyears[nr]['months'][u]['days'][o]['left']>(this.startdiv.offsetWidth+5) &&
              (this.wtl_dlyears[nr]['months'][u]['days'][o]['left']+this.wtl_dlyears[nr]['months'][u]['days'][o]['textwidth'])<(this.wtl_enddivleft-5))
*/ 
            if(this.wtl_dlyears[nr]['months'][u]['days'][o]['appended'])
           {
               if(this.wtl_dlyears[nr]['months'][u]['days'][o]['left']>3 && this.wtl_dlyears[nr]['months'][u]['days'][o]['left']>nextfree && (this.wtl_dlyears[nr]['months'][u]['days'][o]['left']+this.wtl_dlyears[nr]['months'][u]['days'][o]['textwidth'])<this.wtl_pixel)
               {
                  this.wtl_dlyears[nr]['months'][u]['days'][o]['upvisible']=true;
                  this.wtl_dlyears[nr]['months'][u]['days'][o]['downvisible']=false;
                  this.wtl_dlyears[nr]['months'][u]['days'][o]['divtext'].style.display='inline';
                  this.wtl_dlyears[nr]['months'][u]['days'][o]['divtext'].style.top='3px';
               }
               else if(this.wtl_dlyears[nr]['months'][u]['days'][o]['left']>3 && this.wtl_dlyears[nr]['months'][u]['days'][o]['left']>nextfreedown && (this.wtl_dlyears[nr]['months'][u]['days'][o]['left']+this.wtl_dlyears[nr]['months'][u]['days'][o]['textwidth'])<this.wtl_pixel)
               { 
                  this.wtl_dlyears[nr]['months'][u]['days'][o]['upvisible']=false;
                  this.wtl_dlyears[nr]['months'][u]['days'][o]['downvisible']=true;
                  this.wtl_dlyears[nr]['months'][u]['days'][o]['divtext'].style.display='inline';
                  this.wtl_dlyears[nr]['months'][u]['days'][o]['divtext'].style.top= (this.wtl_height-15) + 'px';
               }
               else
               {
                  this.wtl_dlyears[nr]['months'][u]['days'][o]['upvisible']=false;
                  this.wtl_dlyears[nr]['months'][u]['days'][o]['downvisible']=false;
                  this.wtl_dlyears[nr]['months'][u]['days'][o]['divtext'].style.display='none';
               }
            }
            else
            {
               this.wtl_dlyears[nr]['months'][u]['days'][o]['upvisible']=false;
               this.wtl_dlyears[nr]['months'][u]['days'][o]['downvisible']=false;
               this.wtl_dlyears[nr]['months'][u]['days'][o]['divtext'].style.display='none';
            }
         }

      }
   }
}

/**
 * Sets the new from-to (start and end) date of the timeline after its connected
 * containers timeline has been moved. Also redraws the horizontal datelines and event bars.
 * @param {Float} days Number of days that has changed from former to current start date (by moving)
 * @param {Float} pixel movement in connected container in pixels. Not used currently.
 */
wtl_container.prototype.adaptStartDate = function (days, pixel)
{
   var datearr;

   datearr=this.getDatePlusDays(this.wtl_exactfromyear,this.wtl_exactfrommonth,this.wtl_exactfromday,days);

   this.wtl_exactfromyear=datearr['year'];
   this.wtl_exactfrommonth=datearr['month'];
   this.wtl_exactfromday=datearr['day'];

   daystoend=this.wtl_pixdays*this.wtl_pixel;

   datearr=this.getDatePlusDays(this.wtl_exactfromyear,this.wtl_exactfrommonth,this.wtl_exactfromday,daystoend);

   this.wtl_exacttoyear=datearr['year'];
   this.wtl_exacttomonth=datearr['month'];
   this.wtl_exacttoday=datearr['day'];

   this.setFullAndPartDates();

   this.drawAllYearLines();

   this.drawAllBars(0);
}

/**
 * Sets the new from-to (start and end) date of the timeline after it
 * has been moved. Also redraws the horizontal datelines and event bars
 * and passes the movement on to a possible connected container.
 * @param {Float} pixel movement in pixel.
 * @param {Float} xpixel movement in pixel (*-1). If pixel is positiv, this is negativ. If pixel is negativ, this is positiv.
 */
wtl_container.prototype.moveStartDate = function (pixel,xpixel)
{
   var days;
   var fromdatearr;
   var todatearr;
   var daystoend;
   var fromyearstr;
   var toyearstr;
   var fromyear;
   var frommonth;
   var fromday;

   days=this.wtl_pixdays*pixel;
   fromdatearr=this.getDatePlusDays(this.wtl_exactfromyear,this.wtl_exactfrommonth,this.wtl_exactfromday,days);

   fromyear=fromdatearr['year'];
   frommonth=fromdatearr['month'];
   fromday=fromdatearr['day'];

   daystoend=this.wtl_pixdays*this.wtl_pixel;
   todatearr=this.getDatePlusDays(fromyear,frommonth,fromday,daystoend);

   fromyearstr=new String(fromdatearr['year']);
   toyearstr=new String(todatearr['year']);

   if(fromyearstr.length<14 && toyearstr.length<14)
   {
      this.wtl_exactfromyear=fromdatearr['year'];
      this.wtl_exactfrommonth=fromdatearr['month'];
      this.wtl_exactfromday=fromdatearr['day'];

      this.wtl_exacttoyear=todatearr['year'];
      this.wtl_exacttomonth=todatearr['month'];
      this.wtl_exacttoday=todatearr['day'];

      this.setFullAndPartDates();

      if(this.wtl_connection!=0)
      {
         this.wtl_connobj.adaptStartDate(days,xpixel);
       //  this.wtl_connobj.showStartEndDate();
      }
   }
   else
   {
      wtl_showError(wtl_errorcantmove);
   }
}

/**
 * Calculates the fully and partial visible start and end dates
 * and saves them. See {@link wtl_container#wtl_fullfromday} and
 * {@link wtl_container#wtl_partfromday}.
 */
wtl_container.prototype.setFullAndPartDates = function()
{
   this.wtl_fullfromday=Math.ceil(this.wtl_exactfromday);
   this.wtl_fullfrommonth=this.wtl_exactfrommonth;
   this.wtl_fullfromyear=this.wtl_exactfromyear;
   if(this.wtl_marr[this.wtl_fullfrommonth-1]<this.wtl_fullfromday)
   {
      this.wtl_fullfromday=1;
      this.wtl_fullfrommonth++;
      if(this.wtl_fullfrommonth==13)
      {
         this.wtl_fullfrommonth=1;
         this.wtl_fullfromyear++;
      }
   }

   this.wtl_fulltoday=Math.floor(this.wtl_exacttoday);
   this.wtl_fulltomonth=this.wtl_exacttomonth;
   this.wtl_fulltoyear=this.wtl_exacttoyear;

   this.wtl_parttoday=Math.floor(this.wtl_exacttoday);
   this.wtl_parttomonth=this.wtl_exacttomonth;
   this.wtl_parttoyear=this.wtl_exacttoyear;
   if(this.wtl_marr[this.wtl_parttomonth-1]<this.wtl_parttoday)
   {
      this.wtl_parttoday=1;
      this.wtl_parttomonth++;
      if(this.wtl_parttomonth==13)
      {
         this.wtl_parttomonth=1;
         this.wtl_parttoyear++;
      }
   }

   this.wtl_partfromday=Math.floor(this.wtl_exactfromday);
   this.wtl_partfrommonth=this.wtl_exactfrommonth;
   this.wtl_partfromyear=this.wtl_exactfromyear;
}

/**
 * Only for Testing of {@link wtl_container#getDatePlusDays}.
 */
wtl_container.prototype.testdpd = function ()
 /* only for testing of getDatePlusDays */
{
   var dates;
   var strarr;
   var datearr;
   
   do
   {
      dates=window.prompt('Datumsangabe + Tage:','');
      if(dates!='')
      {
         strarr=dates.split(' ');
         if(strarr.length==4)
         {
            datearr=this.getDatePlusDays(parseInt(strarr[0]),parseInt(strarr[1]),parseFloat(strarr[2]),parseFloat(strarr[3]));
            alert('year: ' + datearr['year'] + ', month: ' + datearr['month'] + ', day: ' + datearr['day']);
         }
      }
   }
   while(dates!='');
}

/**
 * Only for Testing of {@link wtl_container#getDaysBetweenDates}.
 */
wtl_container.prototype.testdbd = function ()
 /* only for testing of getDaysBetweenDates */
{
   var dates;
   var strarr;
   var days;

   do
   {
      dates=window.prompt('Datumsangaben:','');
      if(dates!='')
      {
         strarr=dates.split(' ');
         if(strarr.length==6)
         {
            days=this.getDaysBetweenDates(parseInt(strarr[0]),parseInt(strarr[1]),parseFloat(strarr[2]),parseInt(strarr[3]),parseInt(strarr[4]),parseFloat(strarr[5]));
            alert('days1: ' + days);
         }
      }
   }
   while(dates!='');
}

/**
 * Redraws all Bars. Uses {@link wtl_container#drawBar}.
 */
wtl_container.prototype.drawAllBars = function(pixel)
{
   var i;
   var len=this.wtl_events.length;

   for(i=0;i<len;i++)
   {
      this.drawBar(i,pixel);
   }
}

/**
 * Redraws all Years for the horizontal date lines. Uses {@link wtl_container#drawYearLine},
   and {@link wtl_container#setYearsVisible}.
 */
wtl_container.prototype.drawAllYearLines = function()
{
   var i;
   var len=this.wtl_dlyears.length;

   for(i=0;i<len;i++)
   {
      this.drawYearLine(i);
   }

   if(this.wtl_dlyearsorder.length==0)
   {
      this.setStartDLYear();

      this.createStartYearLines();

      this.drawAllYearLines();
   }

   this.setYearsVisible();
}

/**
 * Redraws all Month for the horizontal date lines. Uses {@link wtl_container#drawMonthLine}.
 */
wtl_container.prototype.drawAllMonthLines = function(nr)
{
   var i;
   var len=this.wtl_dlyears[nr]['months'].length;

   for(i=0;i<len;i++)
   {
      this.drawMonthLine(this.wtl_dlyears[nr]['months'][i]);
   }
}

/**
 * Redraws all Days for the horizontal date lines. Uses {@link wtl_container#drawDayLine}.
 */
wtl_container.prototype.drawAllDayLines = function(days)
{
   var i;
   var len=days.length;

   for(i=0;i<len;i++)
   {
     this.drawDayLine(days[i]);
   }
}

/**
 * Creates the div elements for an event. This includes the bar(s) and
 * the name. Does also create the yellow info balloon for the event.
 * @param {Integer} divtype Which type of div element is this: 0 for the main bar, 1 for the bar of the alternative
 *                   from (start) date, 2 for the bar of the alternative to (end) date and 3 for the name.
 * @param {String} color The background color for the div elements (except the name, this div has no background) and
 *                  therefore the color of the event bar. Must be a hexadecimal color code with two digits (0-f)
 *                  representing each red, green and blue. For example: 'a5f049'. It can also have the # in front, like
 *                  in CSS format, for example: '#a5f049'.
 * @return The created div element.
 * @type HTML-Element (div)
 */
wtl_container.prototype.createEventDiv = function (divtype, color)
{
   var div;
   var divballoon;
   var nr=this.wtl_neweventnr;
   var height=this.wtl_barheight+this.wtl_barspace;

   div=document.createElement('div');

   divballoon=document.createElement('div');
   divballoon.style.top='100px';
   divballoon.style.left='100px';
   divballoon.style.display='block';
   divballoon.style.fontSize = this.wtl_fontsize + 'px';
   divballoon.style.fontFamily = this.wtl_fontfamily;
   divballoon.style.zIndex='20';
   divballoon.style.borderStyle='solid';
   divballoon.style.borderColor='black';
   divballoon.style.borderWidth='1px';
   divballoon.style.backgroundColor='rgb(255,255,170)';
   this.locparent.appendChild(divballoon);

   if(wtl_alldivsnr[this.wtl_contnr].length<=nr)
      wtl_alldivsnr[this.wtl_contnr][nr]=new Array();
   div.id='wtl_event_div_' + wtl_dividnr; 
   wtl_dividnr++;
   div.onclick=wtl_mouseclickdiv;
   wtl_alldivsnr[this.wtl_contnr][nr][wtl_alldivsnr[this.wtl_contnr][nr].length]=divballoon;
   wtl_alldivs[div.id]=divballoon;

   div.style.position='absolute';
   if(divtype==3)
   {
      div.style.zIndex='12';
      div.style.whiteSpace='nowrap';
      div.style.overflow='hidden';
      div.appendChild(document.createTextNode(''));
   }
   else
   {
      div.style.height= this.wtl_barheight + 'px';
      div.style.fontSize= '0px';
      if(color.substr(0,1)=='#')
         div.style.backgroundColor=color;
      else
         div.style.backgroundColor='#' + color;
      div.style.borderColor='black';
      div.style.borderStyle='solid';
   }
   if(divtype==0)
   {
      div.style.zIndex='11';
      div.style.borderWidth='1px';
      div.style.filter='alpha(opacity=75)';
      div.style.opacity='0.75';
   }
   else if(divtype==1)
   {
      div.style.zIndex='10';
      div.style.borderBottomWidth='1px';
      div.style.borderTopWidth='1px';
      div.style.borderLeftWidth='1px';
      div.style.borderRightWidth='0px';
      div.style.filter='alpha(opacity=25)';
      div.style.opacity='0.25';
   }
   else if(divtype==2)
   {
      div.style.zIndex='10';
      div.style.borderBottomWidth='1px';
      div.style.borderTopWidth='1px';
      div.style.borderRightWidth='1px';
      div.style.borderLeftWidth='0px';
      div.style.filter='alpha(opacity=25)';
      div.style.opacity='0.25';
   }

   return div;
}

/**
 * Get a new level for an event and stick the event to the new level.
 * @param {Integer} nr Number of the event
 * @param {Integer} textwidth Width of the caption of the event
 * @param {Integer} fromyear Earliest start year of the event (normal or alternative start year)
 * @param {Integer} frommonth Earliest start month of the event (normal or alternative start month)
 * @param {Integer} fromday Earliest start day of the event (normal or alternative start day)
 * @param {Integer} toyear Latest end year of the event (normal or alternative end year)
 * @param {Integer} tomonth Latest end month of the event (normal or alternative end month)
 * @param {Integer} today Latest end day of the event (normal or alternative end day)
 * @nonew {Boolean} nonew If a new level can be created or the event needs to find a place in the existing level (or stay where it is if it does not)
 *                        Is true if no new level can be created and false if new levels can be created.
 */
wtl_container.prototype.getLevel = function (nr, textwidth, fromyear, frommonth, fromday, toyear, tomonth, today, nonew)
{
   var i;
   var u;
   var free=false;
   var checknr;
   var days;

   i=0;
   while(i<this.wtl_levels.length && free==false)
   {
      free=true;
      for(u=0;u<this.wtl_levels[i].length;u++)
      {
        checknr=this.wtl_levels[i][u];
        if(checknr!=nr)
        {
         if((this.wtl_events[checknr]['altfromyear']<toyear ||
            (this.wtl_events[checknr]['altfromyear']==toyear && this.wtl_events[checknr]['altfrommonth']<tomonth) ||
            (this.wtl_events[checknr]['altfromyear']==toyear && this.wtl_events[checknr]['altfrommonth']==tomonth && this.wtl_events[checknr]['altfromday']<=today)) &&
            (this.wtl_events[checknr]['alttoyear']>fromyear ||
            (this.wtl_events[checknr]['alttoyear']==fromyear && this.wtl_events[checknr]['alttomonth']>frommonth) ||
            (this.wtl_events[checknr]['alttoyear']==fromyear && this.wtl_events[checknr]['alttomonth']==frommonth && this.wtl_events[checknr]['alttoday']>=fromday)))
         {
            free=false;
         }
         else
         {
            if(this.wtl_events[checknr]['alttoyear']<fromyear ||
               (this.wtl_events[checknr]['alttoyear']==fromyear && this.wtl_events[checknr]['alttomonth']<frommonth) ||
               (this.wtl_events[checknr]['alttoyear']==fromyear && this.wtl_events[checknr]['alttomonth']==frommonth && this.wtl_events[checknr]['alttoday']<fromday))
            {
               days=this.getDaysBetweenDates(this.wtl_events[checknr]['alttoyear'],this.wtl_events[checknr]['alttomonth'],this.wtl_events[checknr]['alttoday'], fromyear, frommonth, fromday);
               if((this.wtl_abs * days)<this.wtl_pixbetween+this.wtl_events[checknr]['textwidth'])
                  free = false;
            }
            else if(this.wtl_events[checknr]['altfromyear']>toyear ||
               (this.wtl_events[checknr]['altfromyear']==toyear && this.wtl_events[checknr]['altfrommonth']>tomonth) ||
               (this.wtl_events[checknr]['altfromyear']==toyear && this.wtl_events[checknr]['altfrommonth']==tomonth && this.wtl_events[checknr]['altfromday']>today))
            {
               days=this.getDaysBetweenDates(toyear, tomonth, today, this.wtl_events[checknr]['altfromyear'],this.wtl_events[checknr]['altfrommonth'],this.wtl_events[checknr]['altfromday']);
               if((this.wtl_abs * days)<this.wtl_pixbetween+textwidth)
                  free = false;
            }
            else
               free = false;
         }
        }
      }
      i++;
   }

   if(free==true)
   {
      i--;
      this.wtl_events[nr]['level']=i;
      this.removeFromLevels(nr);
      this.wtl_levels[i][this.wtl_levels[i].length]=nr;
   }
   else if(nonew==false)
   {
      this.wtl_events[nr]['level']=i;
      this.wtl_levels[i]=new Array();
      this.wtl_levels[i][0]=nr;
   }
}

/**
 * Remove an event from its level (it will not be in any level afterwards, so it will have to be stuck to one again)
 * @param {Integer} nr Number of the event
 */
wtl_container.prototype.removeFromLevels = function(nr)
{
   var i;
   var u;
   var o;
   var foundinlevel=false;

   for(i=0;i<this.wtl_levels.length && foundinlevel==false;i++)
   {
      foundinlevel=false;
      for(u=0;u<this.wtl_levels[i].length;u++)
      {
         if(this.wtl_levels[i][u]==nr)
            foundinlevel=true;
         if(foundinlevel==true && u<this.wtl_levels[i].length-1)
         {
            this.wtl_levels[i][u]=this.wtl_levels[i][u+1];
         }
      }
      if(foundinlevel==true)
      {
         this.wtl_levels[i].length--;
      }
   }
}

/**
 * Adds an event in realtime to the timeline (and its connected timeline) and
 * send the information of the adding to the server or change to a new page for
 * adding the event if AJAX is not supported.
 * @param {String} toloc the URL that will be called (with AJAX or by changing the page).
 * @param {String} name Caption of the event.
 * @param {Integer} fromyear Start year of the event
 * @param {Integer} frommonth Start month of the event
 * @param {Integer} fromday Start day of the event
 * @param {Integer} toyear End year of the event
 * @param {Integer} tomonth End month of the event
 * @param {Integer} today End day of the event
 * @param {Integer} altfromyear Alternative Start year of the event (must be eralier than the 'normal' start date)
 * @param {Integer} altfrommonth Alternative Start month of the event
 * @param {Integer} altfromday Alternative Start day of the event
 * @param {Integer} alttoyear Alternative End year of the event (must be later than the 'normal' end date)
 * @param {Integer} alttomonth Alternative End month of the event
 * @param {Integer} alttoday Alternative End day of the event
 * @param {String} longname The name of the event, only visible in the yellow info balloon box
 * @param {String} eventtype Type of the event. For example: 'Person' or 'War'
 * @param {String} color The color of the event bar. Must be a hexadecimal color code with two digits (0-f)
 *                  representing each red, green and blue. For example: 'a5f049'. It can also have the # in front, like
 *                  in CSS format, for example: '#a5f049'.
 * @param {String} link The link to the article name
 * @param {String} eventtext Short text for description of the event
 * @param {Boolean} ongoingdate True if the end date of the event is ongoing
 * @param {Boolean} ongoingaltdate True if the alternative end date of the event is ongoing
 * @param {String} removelink URL that will be used to delete the event (with AJAX or by changing the page).
 */
wtl_container.prototype.addEventLink = function (toloc, name, fromyear, frommonth, fromday, toyear, tomonth, today,
                                                 altfromyear, altfrommonth, altfromday, alttoyear, alttomonth, alttoday, longname, eventtype, color, link, eventtext, ongoingdate, ongoingaltdate, removelink)
{
   if(toloc!='')
   {
      var xhr=wtl_getXHR();
      if(xhr!=null)
      {
         xhr.open('GET',encodeURI(wtl_scriptpath + toloc).replace('#','%23'),false);
         xhr.send(null);

         /* send information that the containers are visible again */
         xhr.open('GET',encodeURI(wtl_scriptpath + this.wtl_showcontainertoloc),false);
         xhr.send(null);
      }
      this.addEvent(name, fromyear, frommonth, fromday, toyear, tomonth, today,
                                                 altfromyear, altfrommonth, altfromday, alttoyear, alttomonth, alttoday, longname, eventtype, color, link, eventtext, ongoingdate, ongoingaltdate, removelink);
   }
   else
   {
      this.addEvent(name, fromyear, frommonth, fromday, toyear, tomonth, today,
                                                 altfromyear, altfrommonth, altfromday, alttoyear, alttomonth, alttoday, longname, eventtype, color, link, eventtext, ongoingdate, ongoingaltdate, removelink);
   }
}

/**
 * Adds an event in realtime to the timeline (and its connected timeline)
 * @param {String} name Caption of the event.
 * @param {Integer} fromyear Start year of the event
 * @param {Integer} frommonth Start month of the event
 * @param {Integer} fromday Start day of the event
 * @param {Integer} toyear End year of the event
 * @param {Integer} tomonth End month of the event
 * @param {Integer} today End day of the event
 * @param {Integer} altfromyear Alternative Start year of the event (must be eralier than the 'normal' start date)
 * @param {Integer} altfrommonth Alternative Start month of the event
 * @param {Integer} altfromday Alternative Start day of the event
 * @param {Integer} alttoyear Alternative End year of the event (must be later than the 'normal' end date)
 * @param {Integer} alttomonth Alternative End month of the event
 * @param {Integer} alttoday Alternative End day of the event
 * @param {String} longname The name of the event, only visible in the yellow info balloon box
 * @param {String} eventtype Type of the event. For example: 'Person' or 'War'
 * @param {String} color The color of the event bar. Must be a hexadecimal color code with two digits (0-f)
 *                  representing each red, green and blue. For example: 'a5f049'. It can also have the # in front, like
 *                  in CSS format, for example: '#a5f049'.
 * @param {String} link The link to the article name
 * @param {String} eventtext Short text for description of the event
 * @param {Boolean} ongoingdate True if the end date of the event is ongoing
 * @param {Boolean} ongoingaltdate True if the alternative end date of the event is ongoing
 * @param {String} removelink URL that will be used to delete the event (with AJAX or by changing the page).
 */
wtl_container.prototype.addEvent = function (name, fromyear, frommonth, fromday, toyear, tomonth, today,
                                             altfromyear, altfrommonth, altfromday, alttoyear, alttomonth, alttoday, longname, eventtype, color, link, eventtext, ongoingdate, ongoingaltdate, removelink)
{
   var level;
   var parent;
   var lastevent;

   var height;
   var oneheight;
   var basespace;
   var parent;

   var fromyearstr;
   var toyearstr;

   var fromyearshow=this.wtl_exactfromyear;
   var frommonthshow=this.wtl_exactfrommonth;
   var fromdayshow=this.wtl_exactfromday;
   var toyearshow=this.wtl_exacttoyear;
   var tomonthshow=this.wtl_exacttomonth;
   var todayshow=this.wtl_exacttoday;

   var shownew=false;
   var datearr;

   if(ongoingdate)
   {
      var todaydate=new Date();
      toyear=todaydate.getFullYear();
      tomonth=todaydate.getMonth()+1;
      today=todaydate.getDate();
   }

   if(ongoingdate || ongoingaltdate)
   {
      var alttodaydate=new Date();
      alttoyear=alttodaydate.getFullYear();
      alttomonth=alttodaydate.getMonth()+1;
      alttoday=alttodaydate.getDate();
   }

   if(altfromyear==alttoyear && altfrommonth==alttomonth && altfromday==alttoday)
   {
      datearr=this.getDatePlusDays(altfromyear,altfrommonth,altfromday,1);
      alttoyear=datearr['year'];
      alttomonth=datearr['month'];
      alttoday=datearr['day'];
   }

   fromyearstr=new String(altfromyear);
   toyearstr=new String(alttoyear);
   if(fromyearstr.length<14 && toyearstr.length<14)
   {
     if(this.wtl_maxevents==-1 || this.wtl_neweventnr<this.wtl_maxevents)
     {
      if(this.wtl_dynamic==true)
      {
         level=-1;
         level=this.adaptEvent(name, fromyear, frommonth, fromday, toyear, tomonth, today, altfromyear, altfrommonth, altfromday, alttoyear, alttomonth, alttoday, longname, eventtype, color, link, eventtext, ongoingdate, ongoingaltdate, removelink, level);
      }
      else
      {
         level=-2;
         level=this.adaptEvent(name, fromyear, frommonth, fromday, toyear, tomonth, today, altfromyear, altfrommonth, altfromday, alttoyear, alttomonth, alttoday, longname, eventtype, color, link, eventtext, ongoingdate, ongoingaltdate, removelink, level);
      }

      if(this.wtl_maxlevels!=-1 && this.wtl_levels.length>this.wtl_maxlevels)
      {
         this.removeLastEvent();

         wtl_showError(wtl_errormaxlevel);
      }
      else
      {
         if(this.wtl_connection==1)
         {
            this.wtl_connobj.adaptEvent(name, fromyear, frommonth, fromday, toyear, tomonth, today, altfromyear, altfrommonth, altfromday, alttoyear, alttomonth, alttoday, longname, eventtype, color, link, eventtext, ongoingdate, ongoingaltdate, removelink, level);
         }

         this.removeAll();

         oneheight=this.wtl_barheight+this.wtl_barspace;
         basespace=this.wtl_margespace*2-this.wtl_barspace;
         height=this.wtl_levels.length*oneheight+basespace;
         this.loc.style.height=(height) +  'px';
         this.wtl_height=height;

         parent=this.wtl_divdown.parentNode;
         parent.removeChild(this.wtl_divdown);
         parent=this.wtl_divup.parentNode;
         parent.removeChild(this.wtl_divup);
/*
         this.startdiv2.style.top= (this.wtl_levels.length*oneheight+basespace-15)+ 'px';
         this.enddiv2.style.top= (this.wtl_levels.length*oneheight+basespace-15)+ 'px';
*/
         this.drawHDL();

         if(this.wtl_neweventnr==1 || altfromyear<this.wtl_exactfromyear || 
            (altfromyear==this.wtl_exactfromyear && altfrommonth<this.wtl_exactfrommonth) || 
            (altfromyear==this.wtl_exactfromyear && altfrommonth==this.wtl_exactfrommonth && altfromday<this.wtl_exactfromday))
         {
	      fromyearshow=altfromyear;
	      frommonthshow=altfrommonth;
	      fromdayshow=altfromday;
            shownew=true;
         }
         if(this.wtl_neweventnr==1 || alttoyear>this.wtl_exacttoyear || 
            (alttoyear==this.wtl_exacttoyear && alttomonth>this.wtl_exacttomonth) || 
            (alttoyear==this.wtl_exacttoyear && alttomonth==this.wtl_exacttomonth && alttoday>this.wtl_exacttoday))
         {
	      toyearshow=alttoyear;
	      tomonthshow=alttomonth;
	      todayshow=alttoday;
            shownew=true;
         }

         if(shownew==true)
         {
    	      this.removeAll();

	      this.setFromTo(fromyearshow, frommonthshow, fromdayshow, toyearshow, tomonthshow, todayshow);

            this.checkText();
/*
	      if(this.wtl_connection==1)
	      {
    	         this.wtl_connobj.removeAll();
  
	         this.wtl_connobj.setFromTo(fromyearshow, frommonthshow, fromdayshow, toyearshow, tomonthshow, todayshow);

               this.wtl_connobj.checkText();
	      }
*/
         }

         this.startContainer();

         if(this.wtl_connection==1)
         {
            this.wtl_connobj.removeAll();
/*
            if(shownew==true)
            {
	         this.wtl_connobj.setFromTo(fromyearshow, frommonthshow, fromdayshow, toyearshow, tomonthshow, todayshow);

               this.wtl_connobj.checkText();
            }
*/
            oneheight=this.wtl_connobj.wtl_barheight+this.wtl_connobj.wtl_barspace;
            basespace=this.wtl_connobj.wtl_margespace*2-this.wtl_connobj.wtl_barspace;
            height=this.wtl_connobj.wtl_levels.length*oneheight+basespace;
            this.wtl_connobj.loc.style.height=(height) +  'px';
            this.wtl_connobj.wtl_height=height;

            parent=this.wtl_connobj.wtl_divdown.parentNode;
            parent.removeChild(this.wtl_connobj.wtl_divdown);
            parent=this.wtl_connobj.wtl_divup.parentNode;
            parent.removeChild(this.wtl_connobj.wtl_divup);
/*
            this.wtl_connobj.startdiv2.style.top= (this.wtl_connobj.wtl_levels.length*oneheight+basespace-15)+ 'px';
            this.wtl_connobj.enddiv2.style.top= (this.wtl_connobj.wtl_levels.length*oneheight+basespace-15)+ 'px';
 */
            this.wtl_connobj.drawHDL();
   

            if(shownew==true)
            {
               this.wtl_connobj.adapt(fromyearshow, frommonthshow, fromdayshow, toyearshow, tomonthshow, todayshow); 
            }
            else
            {
               this.wtl_connobj.startContainer();
            }              
         }
/*
         if(altfromyear<this.wtl_exactfromyear || 
            (altfromyear==this.wtl_exactfromyear && altfrommonth<this.wtl_exactfrommonth) || 
            (altfromyear==this.wtl_exactfromyear && altfrommonth==this.wtl_exactfrommonth && altfromday<this.wtl_exactfromday))
         {
	      fromyearshow=altfromyear;
	      frommonthshow=altfrommonth;
	      fromdayshow=altfromday;
            shownew=true;
         }
         if(alttoyear>this.wtl_exacttoyear || 
            (alttoyear==this.wtl_exacttoyear && alttomonth>this.wtl_exacttomonth) || 
            (alttoyear==this.wtl_exacttoyear && alttomonth==this.wtl_exacttomonth && alttoday>this.wtl_exacttoday))
         {
	      toyearshow=alttoyear;
	      tomonthshow=alttomonth;
	      todayshow=alttoday;
            shownew=true;
         }

         if(shownew==true)
         {
    	      this.removeAll();

	      this.setFromTo(fromyearshow, frommonthshow, fromdayshow, toyearshow, tomonthshow, todayshow);

            this.checkText();

	      this.startContainer();

	      if(this.wtl_connection==1)
	      {
	         this.wtl_connobj.adapt(fromyearshow, frommonthshow, fromdayshow, toyearshow, tomonthshow, todayshow);
	      }
         }
*/
      }
     }
     else
        wtl_showError(wtl_errormaxevent);
   }
   else
   {
      wtl_showError(wtl_errortoolarge);
   }
}


/**
 * Creates an event before the container is created (on the beginning).
 * @param {String} name Caption of the event.
 * @param {Integer} fromyear Start year of the event
 * @param {Integer} frommonth Start month of the event
 * @param {Integer} fromday Start day of the event
 * @param {Integer} toyear End year of the event
 * @param {Integer} tomonth End month of the event
 * @param {Integer} today End day of the event
 * @param {Integer} altfromyear Alternative Start year of the event (must be eralier than the 'normal' start date)
 * @param {Integer} altfrommonth Alternative Start month of the event
 * @param {Integer} altfromday Alternative Start day of the event
 * @param {Integer} alttoyear Alternative End year of the event (must be later than the 'normal' end date)
 * @param {Integer} alttomonth Alternative End month of the event
 * @param {Integer} alttoday Alternative End day of the event
 * @param {String} longname The name of the event, only visible in the yellow info balloon box
 * @param {String} eventtype Type of the event. For example: 'Person' or 'War'
 * @param {String} color The color of the event bar. Must be a hexadecimal color code with two digits (0-f)
 *                  representing each red, green and blue. For example: 'a5f049'. It can also have the # in front, like
 *                  in CSS format, for example: '#a5f049'.
 * @param {String} link The link to the article name
 * @param {String} eventtext Short text for description of the event
 * @param {Boolean} ongoingdate True if the end date of the event is ongoing
 * @param {Boolean} ongoingaltdate True if the alternative end date of the event is ongoing
 * @param {String} removelink URL that will be used to delete the event (with AJAX or by changing the page).
 */
wtl_container.prototype.createEvent = function (name, fromyear, frommonth, fromday, toyear, tomonth, today,
                                                      altfromyear, altfrommonth, altfromday, alttoyear, alttomonth, alttoday,
                                                longname, eventtype, color, link, eventtext, ongoingdate, ongoingaltdate, removelink)
{
   var level;
   var fromyearstr;
   var toyearstr;

   if(ongoingdate)
   {
      var todaydate=new Date();
      toyear=todaydate.getFullYear();
      tomonth=todaydate.getMonth()+1;
      today=todaydate.getDate();
   }

   if(ongoingdate || ongoingaltdate)
   {
      var alttodaydate=new Date();
      alttoyear=alttodaydate.getFullYear();
      alttomonth=alttodaydate.getMonth()+1;
      alttoday=alttodaydate.getDate();
   }

   if(altfromyear==alttoyear && altfrommonth==alttomonth && altfromday==alttoday)
   {
      datearr=this.getDatePlusDays(altfromyear,altfrommonth,altfromday,1);
      alttoyear=datearr['year'];
      alttomonth=datearr['month'];
      alttoday=datearr['day'];
   }

   fromyearstr=new String(altfromyear);
   toyearstr=new String(alttoyear);
   if(fromyearstr.length<14 && toyearstr.length<14)
   {
     if(this.wtl_maxevents==-1 || this.wtl_neweventnr<this.wtl_maxevents)
     {
      if(this.wtl_dynamic==true)
      {
         level=-1;
         level=this.adaptEvent(name, fromyear, frommonth, fromday, toyear, tomonth, today, altfromyear, altfrommonth, altfromday, alttoyear, alttomonth, alttoday, longname, eventtype, color, link, eventtext, ongoingdate, ongoingaltdate, removelink, level);
      }
      else
      {
         level=-2;
         level=this.adaptEvent(name, fromyear, frommonth, fromday, toyear, tomonth, today, altfromyear, altfrommonth, altfromday, alttoyear, alttomonth, alttoday, longname, eventtype, color, link, eventtext, ongoingdate, ongoingaltdate, removelink, level);
      }

      if(this.wtl_maxlevels!=-1 && this.wtl_levels.length>this.wtl_maxlevels)
      {
         this.removeLastEvent();
 
         wtl_showError(wtl_errormaxlevel);
      }
      else if(this.wtl_connection==1)
      {
         this.wtl_connobj.adaptEvent(name, fromyear, frommonth, fromday, toyear, tomonth, today, altfromyear, altfrommonth, altfromday, alttoyear, alttomonth, alttoday, longname, eventtype, color, link, eventtext, ongoingdate, ongoingaltdate, removelink, level);
      }

      return 0;
     }
     else
     {
        return 1;
        wtl_showError(wtl_errormaxevent);
     }
   }
   else
   {
      return 2;
      wtl_showError(wtl_errortoolarge);
   }
}

/**
 * Removes the last added event.
 */
wtl_container.prototype.removeLastEvent = function ()
{
   var parent;
   var lastevent;
   var i;

      lastevent=this.wtl_events[this.wtl_events.length-1];
      this.wtl_levels.length--;

      parent=wtl_alldivs[lastevent['div'].id].parentNode;
      parent.removeChild(wtl_alldivs[lastevent['div'].id]);
      wtl_alldivs[lastevent['div'].id]=null;
      parent=wtl_alldivs[lastevent['divtext'].id].parentNode;
      parent.removeChild(wtl_alldivs[lastevent['divtext'].id]);
      wtl_alldivs[lastevent['divtext'].id]=null;

      if(lastevent['divaltfrom']!=null)
      {
         parent=wtl_alldivs[lastevent['divaltfrom'].id].parentNode;
         parent.removeChild(wtl_alldivs[lastevent['divaltfrom'].id]);
         wtl_alldivs[lastevent['divaltfrom'].id]=null;
      }
      if(lastevent['divaltto']!=null)
      {
         parent=wtl_alldivs[lastevent['divaltto'].id].parentNode;
         parent.removeChild(wtl_alldivs[lastevent['divaltto'].id]);
         wtl_alldivs[lastevent['divaltto'].id]=null;
      }
      wtl_alldivsnr[this.wtl_contnr].length--;

      if(lastevent['appended']==true)
      {
         parent=lastevent['div'].parentNode;
         parent.removeChild(lastevent['div']);
         lastevent['appended']=false;
         lastevent['fullvisible']=false;
      }
      if(lastevent['altfrom_appended']==true)
      {
         parent=lastevent['divaltfrom'].parentNode;
         parent.removeChild(lastevent['divaltfrom']);
         lastevent['altfrom_appended']=false;
         lastevent['altfrom_fullvisible']=false;
      }
      if(lastevent['altto_appended']==true)
      {
         parent=lastevent['divaltto'].parentNode;
         parent.removeChild(lastevent['divaltto']);
         lastevent['altto_appended']=false;
         lastevent['altto_fullvisible']=false;
      }
      if(lastevent['text_appended']==true)
      {
         parent=lastevent['divtext'].parentNode;
         parent.removeChild(lastevent['divtext']);
         lastevent['text_appended']=false;
      }
      this.wtl_events.length--;

      this.wtl_neweventnr--;

   for(i=0;i<this.wtl_events.length;i++)
   {
      if(i==0 || this.wtl_minfromyear>this.wtl_events[i]['altfromyear'] ||
         (this.wtl_minfromyear==this.wtl_events[i]['altfromyear'] && this.wtl_minfrommonth>this.wtl_events[i]['altfrommonth']) ||
         (this.wtl_minfromyear==this.wtl_events[i]['altfromyear'] && this.wtl_minfrommonth==this.wtl_events[i]['altfrommonth'] && this.wtl_minfromday>this.wtl_events[i]['altfromday']))
      {
         this.wtl_minfromyear=this.wtl_events[i]['altfromyear'];
         this.wtl_minfrommonth=this.wtl_events[i]['altfrommonth'];
         this.wtl_minfromday=this.wtl_events[i]['altfromday'];
      }
      if(i==0 || this.wtl_maxtoyear<this.wtl_events[i]['alttoyear'] ||
         (this.wtl_maxtoyear==this.wtl_events[i]['alttoyear'] && this.wtl_maxtomonth<this.wtl_events[i]['alttomonth']) ||
         (this.wtl_maxtoyear==this.wtl_events[i]['alttoyear'] && this.wtl_maxtomonth==this.wtl_events[i]['alttomonth'] && this.wtl_maxtoday<this.wtl_events[i]['alttoday']))
      {
         this.wtl_maxtoyear=this.wtl_events[i]['alttoyear'];
         this.wtl_maxtomonth=this.wtl_events[i]['alttomonth'];
         this.wtl_maxtoday=this.wtl_events[i]['alttoday'];
      }
   }
   if(this.wtl_removelasttoloc!='')
   {
      xhr=wtl_getXHR();
      if(xhr!=null)
      {
         xhr.open('GET',encodeURI(wtl_scriptpath + this.wtl_removelasttoloc),false);
         xhr.send(null);
      }
   }
}

/**
 * Calculates the width of the event divs (event bars) and saves them.
 */
wtl_container.prototype.calculateBars = function()
{
   var nr;

   for(nr=0;nr<this.wtl_events.length;nr++)
   {
      this.wtl_events[nr]['div_width']=this.wtl_abs*this.getDaysBetweenDates(this.wtl_events[nr]['fromyear'], this.wtl_events[nr]['frommonth'], this.wtl_events[nr]['fromday'], this.wtl_events[nr]['toyear'], this.wtl_events[nr]['tomonth'], this.wtl_events[nr]['today']);
      this.wtl_events[nr]['divaltfrom_width']=this.wtl_abs*this.getDaysBetweenDates(this.wtl_events[nr]['altfromyear'], this.wtl_events[nr]['altfrommonth'], this.wtl_events[nr]['altfromday'], this.wtl_events[nr]['fromyear'], this.wtl_events[nr]['frommonth'], this.wtl_events[nr]['fromday']);
      this.wtl_events[nr]['divaltto_width']=this.wtl_abs*this.getDaysBetweenDates(this.wtl_events[nr]['toyear'], this.wtl_events[nr]['tomonth'], this.wtl_events[nr]['today'], this.wtl_events[nr]['alttoyear'], this.wtl_events[nr]['alttomonth'], this.wtl_events[nr]['alttoday']);
   }
}

/**
 * Fills the yellow info balloons of the events with their data.
 * @param {Integer} nr Index of the event.
 * @param {String} id HTML-id of the balloon div
 * @param {Integer} balloontop Top position of the balloon div in pixel
 * @param {String} name Name (Long name) of the event.
 * @param {Integer} fromyear Start year of the event
 * @param {Integer} frommonth Start month of the event
 * @param {Integer} fromday Start day of the event
 * @param {Integer} toyear End year of the event
 * @param {Integer} tomonth End month of the event
 * @param {Integer} today End day of the event
 * @param {Integer} altfromyear Alternative Start year of the event (must be eralier than the 'normal' start date)
 * @param {Integer} altfrommonth Alternative Start month of the event
 * @param {Integer} altfromday Alternative Start day of the event
 * @param {Integer} alttoyear Alternative End year of the event (must be later than the 'normal' end date)
 * @param {Integer} alttomonth Alternative End month of the event
 * @param {Integer} alttoday Alternative End day of the event
 * @param {String} eventtype Type of the event. For example: 'Person' or 'War'
 * @param {String} color The color of the event bar. Must be a hexadecimal color code with two digits (0-f)
 *                  representing each red, green and blue. For example: 'a5f049'. It can also have the # in front, like
 *                  in CSS format, for example: '#a5f049'.
 * @param {String} articlelink The link to the article name
 * @param {String} eventtext Short text for description of the event
 * @param {String} removelink URL that will be used to delete the event (with AJAX or by changing the page).
 */
wtl_container.prototype.makeBalloon = function (nr, id, balloontop, name, fromyear, frommonth, fromday, toyear, tomonth, today,
                                                      altfromyear, altfrommonth, altfromday, alttoyear, alttomonth, alttoday,
                                                eventtype, eventtext, articlelink, ongoingdate, ongoingaltdate, removelink)
{
   var divballoonlink;
   var href;
   var textdiv;

   if(articlelink=='')
      wtl_alldivs[id].appendChild(document.createTextNode(name));
   else
   {
      href=document.createAttribute('href');
      href.nodeValue=articlelink;
      divballoonlink=document.createElement('a');
      divballoonlink.setAttributeNode(href);
      divballoonlink.appendChild(document.createTextNode(name));
      wtl_alldivs[id].appendChild(divballoonlink);
   }
   if(eventtype!='')
      wtl_alldivs[id].appendChild(document.createTextNode(' (' + eventtype + ')'));

   wtl_alldivs[id].appendChild(document.createElement('br'));
   wtl_alldivs[id].appendChild(document.createElement('br'));

   wtl_alldivs[id].appendChild(document.createTextNode(this.text_from));

   if(this.wtl_events[nr]['fromday']!=this.wtl_events[nr]['altfromday'] ||
      this.wtl_events[nr]['frommonth']!=this.wtl_events[nr]['altfrommonth'] ||
      this.wtl_events[nr]['fromyear']!=this.wtl_events[nr]['altfromyear'])
   {
      wtl_alldivs[id].appendChild(document.createTextNode(this.getDateStr(this.wtl_events[nr]['altfromyear'],this.wtl_events[nr]['altfrommonth'],this.wtl_events[nr]['altfromday']) + ' ' + this.text_or + ' '));
   }

   wtl_alldivs[id].appendChild(document.createTextNode(this.getDateStr(this.wtl_events[nr]['fromyear'],this.wtl_events[nr]['frommonth'],this.wtl_events[nr]['fromday'])));

   wtl_alldivs[id].appendChild(document.createElement('br'));

   wtl_alldivs[id].appendChild(document.createTextNode(this.text_to));
   wtl_alldivs[id].appendChild(document.createTextNode(this.getDateStr(this.wtl_events[nr]['toyear'],this.wtl_events[nr]['tomonth'],this.wtl_events[nr]['today'])));

   if(this.wtl_events[nr]['today']!=this.wtl_events[nr]['alttoday'] ||
      this.wtl_events[nr]['tomonth']!=this.wtl_events[nr]['alttomonth'] ||
      this.wtl_events[nr]['toyear']!=this.wtl_events[nr]['alttoyear'])
   {
      wtl_alldivs[id].appendChild(document.createTextNode(' ' + this.text_or + ' ' + this.getDateStr(this.wtl_events[nr]['alttoyear'],this.wtl_events[nr]['alttomonth'],this.wtl_events[nr]['alttoday'])));
   }

   if(ongoingdate || ongoingaltdate)
   {
      wtl_alldivs[id].appendChild(document.createElement('br'));
      wtl_alldivs[id].appendChild(document.createTextNode('(' + this.text_ongoing + ')'));   
   }

   wtl_alldivs[id].appendChild(document.createElement('br'));

   if(eventtext!='')
   {
      wtl_alldivs[id].appendChild(document.createElement('br'));
      textdiv=document.createElement('div');
      textdiv.appendChild(document.createTextNode(eventtext));
      textdiv.style.width='200px';
      wtl_alldivs[id].appendChild(textdiv);
   }

   wtl_alldivs[id].appendChild(document.createElement('br'));

   href=document.createAttribute('href');
   href.nodeValue='javascript:' + this.wtl_zoomobj + '.zoomEvent(' + altfromyear + ', ' + altfrommonth + ', ' + altfromday + ', ' + alttoyear + ', ' + alttomonth + ', ' + alttoday + ');';
   divballoonlink=document.createElement('a');
   divballoonlink.setAttributeNode(href);
   divballoonlink.appendChild(document.createTextNode(this.text_zoomevent));
   wtl_alldivs[id].appendChild(divballoonlink);

   wtl_alldivs[id].appendChild(document.createTextNode(', '));

   href=document.createAttribute('href');
   href.nodeValue='javascript:wtl_removeEventLink("' + removelink + '", ' + nr + ');';
   divballoonlink=document.createElement('a');
   divballoonlink.setAttributeNode(href);
   divballoonlink.appendChild(document.createTextNode(this.text_remove));
   wtl_alldivs[id].appendChild(divballoonlink);

   wtl_alldivs[id].style.top=balloontop;
   wtl_alldivs[id].style.display='none';
}


/**
 * Erase all Events
 * @param {String} toloc URL to call (AJAX)
 */
wtl_container.prototype.emptyContainerLink = function (toloc)
{
   var i;
   var len;

   if(toloc!='')
   {
      xhr=wtl_getXHR();
      if(xhr!=null)
      {
         xhr.open('GET',encodeURI(wtl_scriptpath + toloc),true);
         xhr.send(null);
      }
   }

   this.emptyContainer();
}

/**
 * Erase all Events
 */
wtl_container.prototype.emptyContainer = function ()
{
   var i;
   var len;
   var u;
   var parent;

   for(u=0;u<wtl_alldivsnr[this.wtl_contnr].length;u++)
   {
      for(i=0;i<wtl_alldivsnr[this.wtl_contnr][u].length;i++)
      {
         parent=wtl_alldivsnr[this.wtl_contnr][u][i].parentNode;
         parent.removeChild(wtl_alldivsnr[this.wtl_contnr][u][i]);
      }
   }

   wtl_alldivsnr[this.wtl_contnr]=new Array();

   wtl_alldivs=new Array();

   for(u=0;u<this.wtl_events.length;u++)
   {
      if(this.wtl_events[u]['appended']==true)
      {
         parent=this.wtl_events[u]['div'].parentNode;
         parent.removeChild(this.wtl_events[u]['div']);
      }
      if(this.wtl_events[u]['altfrom_appended']==true)
      {
         parent=this.wtl_events[u]['divaltfrom'].parentNode;
         parent.removeChild(this.wtl_events[u]['divaltfrom']);
      }
      if(this.wtl_events[u]['altto_appended']==true)
      {
         parent=this.wtl_events[u]['divaltto'].parentNode;
         parent.removeChild(this.wtl_events[u]['divaltto']);
      }
      if(this.wtl_events[u]['text_appended']==true)
      {
         parent=this.wtl_events[u]['divtext'].parentNode;
         parent.removeChild(this.wtl_events[u]['divtext']);
      }
   }

   this.wtl_levels=new Array();
   this.wtl_events=new Array();
   this.levelarray=new Array();

   this.wtl_neweventnr=0;

   if(this.wtl_connection==1)
   {
      this.wtl_connobj.emptyContainer();
   }

   this.startContainer();
}

/**
 * Just hide the container.
 * @param {String} toloc URL to call (AJAX)
 */
wtl_container.prototype.hideContainerLink = function (toloc)
{
   xhr=wtl_getXHR();
   if(xhr!=null)
   {
      xhr.open('GET',encodeURI(wtl_scriptpath + toloc),false);
      xhr.send(null);
   }

   this.hideContainer();
}

/**
 * Just hide the container.
 */
wtl_container.prototype.hideContainer = function ()
{
   var showdiv=null;
   var xhr;

   if(this.wtl_visible==true)
   {
   /* now we make the container invisible. */
     if(this.locparent!=null)
     {
        this.locparent.style.display='none';
     }
     else
     {
        this.loc.style.display='none';
     }
     this.wtl_visible=false;

     if(this.wtl_connection!=0)
        this.wtl_connobj.wtl_visible=false;

     if(this.wtl_showid!='')
     {
        showdiv=document.getElementById(this.wtl_showid);
        showdiv.style.display='block';
     }
   }
}

/**
 * Reads in the data from a webpage per AJAX at the beginning and
 * checks if the containers are hidden or visible.
 * @param {String} toloc URL to get information from (AJAX)
 */
wtl_container.prototype.setVisible = function (toloc)
{
   var xhr;
   var datatext;

   if(this.wtl_events.length>0)
   {
      xhr=wtl_getXHR();
      if(xhr!=null)
      {
         xhr.open('GET',encodeURI(wtl_scriptpath + toloc),false);
         xhr.send(null);
         if (xhr.readyState == 4)
         {
            if (xhr.status == 200)
            {
               datatext=xhr.responseText;
               if(datatext=='show')
               {
                  this.showContainer();
               }
               else if(datatext=='hide')
               {
                  this.hideContainer();
               }
            }
         }
      }
   }
}

/**
 * Just show a hidden container again.
 */
wtl_container.prototype.showContainerLink = function ()
{
   xhr=wtl_getXHR();
   if(xhr!=null)
   {
      xhr.open('GET',encodeURI(wtl_scriptpath + this.wtl_showcontainertoloc),false);
      xhr.send(null);
   }

   this.showContainer();
}

/**
 * Just show a hidden container again.
 */
wtl_container.prototype.showContainer = function ()
{
   if(this.wtl_visible==false)
   {
   /* now we make the container visible. */
     if(this.locparent!=null)
     {
        this.locparent.style.display='block';
     }
     else
     {
        this.loc.style.display='block';
     }
     this.wtl_visible=true;

     if(this.wtl_connection!=0)
        this.wtl_connobj.wtl_visible=true;

     if(this.wtl_showid!='')
     {
        showdiv=document.getElementById(this.wtl_showid);
        showdiv.style.display='none';
     }
   }
}

/**
 * Calculates the average width of a letter and a digit
 */
wtl_container.prototype.calcWidth = function ()
{
     var textletter=null;
     var textletterdiv=null;

   textletterdiv=document.createElement('div');
   textletterdiv.style.position='absolute';
   textletterdiv.style.fontFamily=this.wtl_fontfamily;
   textletterdiv.style.fontSize=this.wtl_fontsize;
   textletter=document.createTextNode('M');
   textletterdiv.appendChild(textletter);
   this.loc.appendChild(textletterdiv);
   this.wtl_textwidth=textletterdiv.offsetWidth;
   this.loc.removeChild(textletterdiv);
   textletterdiv=null;
   textletter=null;

   textletterdiv=document.createElement('div');
   textletterdiv.style.position='absolute';
   textletterdiv.style.fontFamily=this.wtl_fontfamily;
   textletterdiv.style.fontSize=this.wtl_fontsize;
   textletter=document.createTextNode('0');
   textletterdiv.appendChild(textletter);
   this.loc.appendChild(textletterdiv);
   this.wtl_digitwidth=textletterdiv.offsetWidth;
   this.loc.removeChild(textletterdiv);
   textletterdiv=null;
   textletter=null;
}

/**
 * Creates an event before the container is created (on the beginning).
 * @param {String} name Caption of the event.
 * @param {Integer} fromyear Start year of the event
 * @param {Integer} frommonth Start month of the event
 * @param {Integer} fromday Start day of the event
 * @param {Integer} toyear End year of the event
 * @param {Integer} tomonth End month of the event
 * @param {Integer} today End day of the event
 * @param {Integer} altfromyear Alternative Start year of the event (must be eralier than the 'normal' start date)
 * @param {Integer} altfrommonth Alternative Start month of the event
 * @param {Integer} altfromday Alternative Start day of the event
 * @param {Integer} alttoyear Alternative End year of the event (must be later than the 'normal' end date)
 * @param {Integer} alttomonth Alternative End month of the event
 * @param {Integer} alttoday Alternative End day of the event
 * @param {String} longname The name of the event, only visible in the yellow info balloon box
 * @param {String} eventtype Type of the event. For example: 'Person' or 'War'
 * @param {String} color The color of the event bar. Must be a hexadecimal color code with two digits (0-f)
 *                  representing each red, green and blue. For example: 'a5f049'. It can also have the # in front, like
 *                  in CSS format, for example: '#a5f049'.
 * @param {String} link The link to the article name
 * @param {String} eventtext Short text for description of the event
 * @param {Boolean} ongoingdate True if the end date of the event is ongoing
 * @param {Boolean} ongoingaltdate True if the alternative end date of the event is ongoing
 * @param {String} removelink URL that will be used to delete the event (with AJAX or by changing the page).
 * @param {Integer} level Defines the level of the event (>=0) or defines if event should find a free level (=-1)
 *                   or if the event should create a new level even if there would be a free level (=-2).
 * @return Returns the level of the newly created Event
 * @type Integer
 */
wtl_container.prototype.adaptEvent = function (name, fromyear, frommonth, fromday, toyear, tomonth, today,
                                                      altfromyear, altfrommonth, altfromday, alttoyear, alttomonth, alttoday, 
                                               longname, eventtype, color, link, eventtext, ongoingdate, ongoingaltdate, removelink, level)
{
   var height=this.wtl_barheight+this.wtl_barspace;
   var nr=this.wtl_neweventnr;
   var balloontop;
   var levelarrayexists=false;
   var i;
   var xhr;

   if(this.wtl_visible==false)
   {
   /* now we make the container visible. If we add an event
      to a hidden container, we'll get him visible again. */
     if(this.locparent!=null)
     {
        this.locparent.style.display='block';
     }
     else
     {
        this.loc.style.display='block';
     }
     this.calcWidth();
     this.wtl_visible=true;

     if(this.wtl_showid!='')
     {
        showdiv=document.getElementById(this.wtl_showid);
        showdiv.style.display='none';
     }
   }

   if(this.wtl_neweventnr==0 || this.wtl_minfromyear>altfromyear ||
      (this.wtl_minfromyear==altfromyear && this.wtl_minfrommonth>altfrommonth) ||
      (this.wtl_minfromyear==altfromyear && this.wtl_minfrommonth==altfrommonth && this.wtl_minfromday>altfromday))
   {
      this.wtl_minfromyear=altfromyear;
      this.wtl_minfrommonth=altfrommonth;
      this.wtl_minfromday=altfromday;
   }
   if(this.wtl_neweventnr==0 || this.wtl_maxtoyear<alttoyear ||
      (this.wtl_maxtoyear==alttoyear && this.wtl_maxtomonth<alttomonth) ||
      (this.wtl_maxtoyear==alttoyear && this.wtl_maxtomonth==alttomonth && this.wtl_maxtoday<alttoday))
   {
      this.wtl_maxtoyear=alttoyear;
      this.wtl_maxtomonth=alttomonth;
      this.wtl_maxtoday=alttoday;
   }

   this.wtl_events[nr]=new Array();

   this.wtl_events[nr]['lastinval']=-1;
   this.wtl_events[nr]['oldstartpix']=0;
   this.wtl_events[nr]['oldendpix']=0;
   this.wtl_events[nr]['lastinvalaltfrom']=-1;
   this.wtl_events[nr]['oldstartpixaltfrom']=0;
   this.wtl_events[nr]['oldendpixaltfrom']=0;
   this.wtl_events[nr]['lastinvalaltto']=-1;
   this.wtl_events[nr]['oldstartpixaltto']=0;
   this.wtl_events[nr]['oldendpixaltto']=0;

   if(longname!='')
      this.wtl_events[nr]['eventlongname']=longname;
   else
      this.wtl_events[nr]['eventlongname']=name;

   this.wtl_events[nr]['eventtype']=eventtype;
   this.wtl_events[nr]['eventcolor']=color;
   this.wtl_events[nr]['articlelink']=link;
   this.wtl_events[nr]['eventtext']=eventtext;   
   this.wtl_events[nr]['removelink']=removelink;

   this.wtl_events[nr]['ongoingdate']=ongoingdate;   
   this.wtl_events[nr]['ongoingaltdate']=ongoingaltdate;

   this.wtl_events[nr]['div']=this.createEventDiv(0,this.wtl_events[nr]['eventcolor']);
   if(fromyear!=altfromyear || frommonth!=altfrommonth || fromday!=altfromday)
   {
      this.wtl_events[nr]['divaltfrom']=this.createEventDiv(1,this.wtl_events[nr]['eventcolor']);
   }
   else
   {
      this.wtl_events[nr]['divaltfrom']=null;
   }
   if(toyear!=alttoyear || tomonth!=alttomonth || today!=alttoday)
      this.wtl_events[nr]['divaltto']=this.createEventDiv(2,this.wtl_events[nr]['eventcolor']);
   else
      this.wtl_events[nr]['divaltto']=null;
   this.wtl_events[nr]['divtext']=this.createEventDiv(3,this.wtl_events[nr]['eventcolor']);
   this.wtl_events[nr]['divtext'].firstChild.nodeValue=name;
   this.wtl_events[nr]['showtext']=true;

   this.loc.appendChild(this.wtl_events[nr]['divtext']);
   this.wtl_events[nr]['textwidth']=this.wtl_events[nr]['divtext'].offsetWidth;
   this.loc.removeChild(this.wtl_events[nr]['divtext']);

   if(level>=0)
   {
      for(i=0;i<this.levelarray.length;i++)
      {
         if(this.levelarray[i]==level)
            levelarrayexists=true;
      }
      if(levelarrayexists==false)
      {
         this.levelarray[this.levelarray.length]=level;
         this.wtl_levels[level]=new Array();
      }
      this.wtl_levels[level][this.wtl_levels[level].length]=nr;
      this.wtl_events[nr]['level']=level;
   }
   else if(level==-1)
   {
      this.getLevel(nr,this.wtl_events[nr]['textwidth'],altfromyear, altfrommonth, altfromday, alttoyear, alttomonth, alttoday, false);
   }
   else if(level==-2)
   {
      level=nr;
      this.wtl_levels[level]=new Array();
      this.wtl_levels[level][0]=nr;
      this.wtl_events[nr]['level']=level;
   }

   this.wtl_events[nr]['div'].style.top=((this.wtl_events[nr]['level'] * height) + this.wtl_margespace) + 'px';
   if(this.wtl_events[nr]['divaltfrom']!=null)
      this.wtl_events[nr]['divaltfrom'].style.top=((this.wtl_events[nr]['level'] * height) + this.wtl_margespace) + 'px';
   if(this.wtl_events[nr]['divaltto']!=null)
      this.wtl_events[nr]['divaltto'].style.top=((this.wtl_events[nr]['level'] * height) + this.wtl_margespace) + 'px';
   this.wtl_events[nr]['divtext'].style.top=((this.wtl_events[nr]['level'] * height) + this.wtl_margespace) + 'px';

   this.wtl_events[nr]['fromyear']=fromyear;
   this.wtl_events[nr]['frommonth']=frommonth;
   this.wtl_events[nr]['fromday']=fromday;
   this.wtl_events[nr]['toyear']=toyear;
   this.wtl_events[nr]['tomonth']=tomonth;
   this.wtl_events[nr]['today']=today;

   this.wtl_events[nr]['altfromyear']=altfromyear;
   this.wtl_events[nr]['altfrommonth']=altfrommonth;
   this.wtl_events[nr]['altfromday']=altfromday;
   this.wtl_events[nr]['alttoyear']=alttoyear;
   this.wtl_events[nr]['alttomonth']=alttomonth;
   this.wtl_events[nr]['alttoday']=alttoday;

   this.wtl_events[nr]['appended']=false;
   this.wtl_events[nr]['fullvisible']=false;

   this.wtl_events[nr]['altfrom_appended']=false;
   this.wtl_events[nr]['altfrom_fullvisible']=false;

   this.wtl_events[nr]['altto_appended']=false;
   this.wtl_events[nr]['altto_fullvisible']=false;

   this.wtl_events[nr]['text_appended']=false;

   balloontop=(((this.wtl_events[nr]['level'] * height) + this.wtl_margespace) - wtl_alldivs[this.wtl_events[nr]['div'].id].offsetHeight/2 + this.loc.offsetTop) + 'px';
   this.makeBalloon(nr, this.wtl_events[nr]['div'].id, balloontop, this.wtl_events[nr]['eventlongname'], this.wtl_events[nr]['fromyear'], this.wtl_events[nr]['frommonth'], this.wtl_events[nr]['fromday'], this.wtl_events[nr]['toyear'], this.wtl_events[nr]['tomonth'], this.wtl_events[nr]['today'],
                    this.wtl_events[nr]['altfromyear'], this.wtl_events[nr]['altfrommonth'], this.wtl_events[nr]['altfromday'], this.wtl_events[nr]['alttoyear'], this.wtl_events[nr]['alttomonth'], this.wtl_events[nr]['alttoday'],
                    this.wtl_events[nr]['eventtype'], this.wtl_events[nr]['eventtext'], this.wtl_events[nr]['articlelink'],this.wtl_events[nr]['ongoingdate'],this.wtl_events[nr]['ongoingaltdate'],this.wtl_events[nr]['removelink']);

   this.makeBalloon(nr, this.wtl_events[nr]['divtext'].id, balloontop, this.wtl_events[nr]['eventlongname'], this.wtl_events[nr]['fromyear'], this.wtl_events[nr]['frommonth'], this.wtl_events[nr]['fromday'], this.wtl_events[nr]['toyear'], this.wtl_events[nr]['tomonth'], this.wtl_events[nr]['today'],
                    this.wtl_events[nr]['altfromyear'], this.wtl_events[nr]['altfrommonth'], this.wtl_events[nr]['altfromday'], this.wtl_events[nr]['alttoyear'], this.wtl_events[nr]['alttomonth'], this.wtl_events[nr]['alttoday'],
                    this.wtl_events[nr]['eventtype'], this.wtl_events[nr]['eventtext'], this.wtl_events[nr]['articlelink'],this.wtl_events[nr]['ongoingdate'],this.wtl_events[nr]['ongoingaltdate'],this.wtl_events[nr]['removelink']);
   if(this.wtl_events[nr]['divaltfrom']!=null)
   {
      this.makeBalloon(nr, this.wtl_events[nr]['divaltfrom'].id, balloontop, this.wtl_events[nr]['eventlongname'], this.wtl_events[nr]['fromyear'], this.wtl_events[nr]['frommonth'], this.wtl_events[nr]['fromday'], this.wtl_events[nr]['toyear'], this.wtl_events[nr]['tomonth'], this.wtl_events[nr]['today'],
                    this.wtl_events[nr]['altfromyear'], this.wtl_events[nr]['altfrommonth'], this.wtl_events[nr]['altfromday'], this.wtl_events[nr]['alttoyear'], this.wtl_events[nr]['alttomonth'], this.wtl_events[nr]['alttoday'],
                    this.wtl_events[nr]['eventtype'], this.wtl_events[nr]['eventtext'], this.wtl_events[nr]['articlelink'],this.wtl_events[nr]['ongoingdate'],this.wtl_events[nr]['ongoingaltdate'],this.wtl_events[nr]['removelink']);
   }
   if(this.wtl_events[nr]['divaltto']!=null)
   {
      this.makeBalloon(nr, this.wtl_events[nr]['divaltto'].id, balloontop, this.wtl_events[nr]['eventlongname'], this.wtl_events[nr]['fromyear'], this.wtl_events[nr]['frommonth'], this.wtl_events[nr]['fromday'], this.wtl_events[nr]['toyear'], this.wtl_events[nr]['tomonth'], this.wtl_events[nr]['today'],
                    this.wtl_events[nr]['altfromyear'], this.wtl_events[nr]['altfrommonth'], this.wtl_events[nr]['altfromday'], this.wtl_events[nr]['alttoyear'], this.wtl_events[nr]['alttomonth'], this.wtl_events[nr]['alttoday'],
                    this.wtl_events[nr]['eventtype'], this.wtl_events[nr]['eventtext'], this.wtl_events[nr]['articlelink'],this.wtl_events[nr]['ongoingdate'],this.wtl_events[nr]['ongoingaltdate'],this.wtl_events[nr]['removelink']);
   }

   this.wtl_neweventnr++;

   return this.wtl_events[nr]['level'];
}

/**
 * Calculates if year is currently visible on the
 * horizontal date lines and displays it. Also removes 
 * no longer visible years and adds newly visible years.
 * Uses the array {@link wtl_container#wtl_dlyears} heavily.
 * @param {Integer} nr Index of the year in {@link wtl_container#wtl_dlyears}.
 */
wtl_container.prototype.drawYearLine = function (nr)
{
   var inval;
   var startpix;
   var endpix
   var parent;
   var append=false;
   var calcwidth=true;
   var newnr;
   var i;
   var o;

   if(this.wtl_dlyears[nr]!=null)
   {
	   var fromyear=this.wtl_dlyears[nr]['fromyear'];
	   var toyear=this.wtl_dlyears[nr]['toyear'];
	   
	   inval=this.isInside(fromyear, 1, 1, toyear, 1, 1);

	   if(inval>0)
	   {
	      if(inval==3 && this.wtl_dlyears[nr]['fullvisible']==true)
	         calcwidth=false;

	      if(inval==1 || inval==4)
	      {
               this.wtl_dlyears[nr]['div'].style.borderLeftWidth='0px';
	         this.wtl_dlyears[nr]['div2'].style.borderLeftWidth='0px';
	         this.wtl_dlyears[nr]['maindiv'].style.borderLeftWidth='0px';
	         startpix=-1;
	      }
            else
            {
               this.wtl_dlyears[nr]['div'].style.borderLeftWidth='1px';
	         this.wtl_dlyears[nr]['div2'].style.borderLeftWidth='1px';
	         this.wtl_dlyears[nr]['maindiv'].style.borderLeftWidth='1px';
            }
	      if(inval==3 || inval==2)
	      {
	         startpix=this.getPixelFromStart(fromyear, 1, 1);
	      }
	      if(inval==2 || inval==4)
	      {
/* We won't need it for now
	         endpix=this.wtl_pixel-startpix;
*/
               endpix=1;
	      }
	      if(inval==1)
	      {
/* We won't need it for now
	         endpix=this.getPixelFromStart(toyear, 1, 1)-startpix;
*/
               endpix=1;
	      }

	      if(inval==3)
	      {
               endpix=1;
	         if(this.wtl_dlyears[nr]['fullvisible']==false)
	         {
/* We won't need it for now
                  endpix=this.wtl_dlyears[nr]['div_width'];
*/
	            this.wtl_dlyears[nr]['fullvisible']=true;
	            this.wtl_dlyears[nr]['endpix']=endpix;
	         }
/* We won't need it for now
	         else
	         {
	            endpix=this.wtl_dlyears[nr]['endpix'];
	         }
*/
	      }
	      else if(this.wtl_dlyears[nr]['fullvisible']==true)
	      {
	         this.wtl_dlyears[nr]['fullvisible']=false;
	      }

	      this.wtl_dlyears[nr]['left']=startpix+3;
	      this.wtl_dlyears[nr]['div'].style.left=startpix + 'px';
	      this.wtl_dlyears[nr]['div'].style.width=endpix + 'px';
	      this.wtl_dlyears[nr]['div2'].style.left=startpix + 'px';
	      this.wtl_dlyears[nr]['div2'].style.width=endpix + 'px';
	      this.wtl_dlyears[nr]['divtext'].style.left=(startpix+3) + 'px';

	      this.wtl_dlyears[nr]['maindiv'].style.left=startpix + 'px';
	      this.wtl_dlyears[nr]['maindiv'].style.width=endpix + 'px';


	      if(this.wtl_dlyears[nr]['appended']==false)
	      {
               this.loc.appendChild(this.wtl_dlyears[nr]['div']);
	         this.loc.appendChild(this.wtl_dlyears[nr]['div2']);
	         this.loc.appendChild(this.wtl_dlyears[nr]['divtext']);
	         this.loc.appendChild(this.wtl_dlyears[nr]['maindiv']);
	         this.wtl_dlyears[nr]['appended']=true;
	      }

            if(inval==1 || inval==3)
            {
               if(this.wtl_dlyears[nr]['inval']==2 || this.wtl_dlyears[nr]['inval']==4)
               {
                  newnr=this.createYearLine(this.wtl_dlyears[nr]['fromyear']+this.wtl_stepyears,1);
                  this.drawYearLine(newnr);
               }
            }

            if(inval==2 || inval==3)
            {
               if(this.wtl_dlyears[nr]['inval']==1 || this.wtl_dlyears[nr]['inval']==4)
               {
                  newnr=this.createYearLine(this.wtl_dlyears[nr]['fromyear']-this.wtl_stepyears,-1);
                  this.drawYearLine(newnr);
               }
            }

            if(inval==3 && this.wtl_dlyears[nr]['inval']==-1 && this.wtl_dlyears[nr]['f']!=0)
            {
               newnr=this.createYearLine(this.wtl_dlyears[nr]['fromyear']+(this.wtl_dlyears[nr]['f']*this.wtl_stepyears),this.wtl_dlyears[nr]['f']);
               this.drawYearLine(newnr);
            }

            this.drawAllMonthLines(nr);

            this.wtl_dlyears[nr]['inval']=inval;

	   }
	   else if(this.wtl_dlyears[nr]['appended']==true)
	   {
            for(i=0,o=0;i<this.wtl_dlyearsorder.length;i++,o++)
            {
               if(this.wtl_dlyearsorder[o]==nr)
                  i++;
               if(i<this.wtl_dlyearsorder.length)
                  this.wtl_dlyearsorder[o]=this.wtl_dlyearsorder[i];
            }
            this.wtl_dlyearsorder.length--;

            this.removeMonths(this.wtl_dlyears[nr]['months']);

	      parent=this.wtl_dlyears[nr]['div'].parentNode;
	      parent.removeChild(this.wtl_dlyears[nr]['div']);
	      parent=this.wtl_dlyears[nr]['div2'].parentNode;
	      parent.removeChild(this.wtl_dlyears[nr]['div2']);
	      parent=this.wtl_dlyears[nr]['divtext'].parentNode;
	      parent.removeChild(this.wtl_dlyears[nr]['divtext']);
	      parent=this.wtl_dlyears[nr]['maindiv'].parentNode;
	      parent.removeChild(this.wtl_dlyears[nr]['maindiv']);

            this.wtl_dlyears[nr]['div']=null;
            this.wtl_dlyears[nr]['div2']=null;
            this.wtl_dlyears[nr]['divtext']=null;
            this.wtl_dlyears[nr]['maindiv']=null;
            this.wtl_dlyears[nr]=null;
	   }
   }
}

/**
 * Calculates if event bar is currently visible on the
 * horizontal date lines and displays it. Also removes 
 * no longer visible event bars from the timeline and adds
 * newly visible event bars to the timeline.
 * Uses the array {@link wtl_container#wtl_events} heavily.
 * @param {Integer} nr Index of the event in {@link wtl_container#wtl_events}.
 * @param {Integer} pixel Movement of timeline in pixel. See {@link wtl_container#moveStartDate}.
 */
wtl_container.prototype.drawBar = function (nr, pixel)
{
   var inval;
   var maininval;
   var startpix;
   var endpix
   var parent;
   var append;
   var calcwidth;
   var i;
   var fromyear;
   var frommonth;
   var fromday;
   var toyear;
   var tomonth;
   var today;
   var textstart=-2;
   var textend=-2;
   var textvisible=false;
   var textleft=0;
   var mainwidth=0;

 for(i=0;i<3;i++)
 {
  if(i==0 || (i==1 && this.wtl_events[nr]['divaltfrom']!=null) || (i==2 && this.wtl_events[nr]['divaltto']!=null))
  {
   append=false;

  if(i==0)
  {
   fromyear=this.wtl_events[nr]['fromyear'];
   frommonth=this.wtl_events[nr]['frommonth'];
   fromday=this.wtl_events[nr]['fromday'];
   toyear=this.wtl_events[nr]['toyear'];
   tomonth=this.wtl_events[nr]['tomonth'];
   today=this.wtl_events[nr]['today'];
  }
  else if(i==1)
  {
   fromyear=this.wtl_events[nr]['altfromyear'];
   frommonth=this.wtl_events[nr]['altfrommonth'];
   fromday=this.wtl_events[nr]['altfromday'];
   toyear=this.wtl_events[nr]['fromyear'];
   tomonth=this.wtl_events[nr]['frommonth'];
   today=this.wtl_events[nr]['fromday'];
  }
  else if(i==2)
  {
   fromyear=this.wtl_events[nr]['toyear'];
   frommonth=this.wtl_events[nr]['tomonth'];
   fromday=this.wtl_events[nr]['today'];
   toyear=this.wtl_events[nr]['alttoyear'];
   tomonth=this.wtl_events[nr]['alttomonth'];
   today=this.wtl_events[nr]['alttoday'];
  }
   
   inval=this.isInside(fromyear, frommonth, fromday, toyear, tomonth, today);
   if(i==0)
      maininval=inval;

   if(inval>0)
   {
      textvisible=true;

      if(inval==1 || inval==4)
      {
         startpix=-1;
      }
      if(inval==3 || inval==2)
      {
         if(i==0 && (((inval==3 && this.wtl_events[nr]['lastinval']!=3) || (inval==2 && this.wtl_events[nr]['lastinval']!=2)) || pixel==0))
         {
            startpix=this.getPixelFromStart(fromyear, frommonth, fromday);
            this.wtl_events[nr]['oldstartpix']=startpix;
         }
         else if(i==1 && (((inval==3 && this.wtl_events[nr]['lastinvalaltfrom']!=3) || (inval==2 && this.wtl_events[nr]['lastinvalaltfrom']!=2)) || pixel==0))
         {
            startpix=this.getPixelFromStart(fromyear, frommonth, fromday);
            this.wtl_events[nr]['oldstartpixaltfrom']=startpix;
         }
         else if(i==2 && (((inval==3 && this.wtl_events[nr]['lastinvalaltto']!=3) || (inval==2 && this.wtl_events[nr]['lastinvalaltto']!=2)) || pixel==0))
         {
            startpix=this.getPixelFromStart(fromyear, frommonth, fromday);
            this.wtl_events[nr]['oldstartpixaltto']=startpix;
         }
         else if(i==0)
         {
            this.wtl_events[nr]['oldstartpix']+=pixel;
            startpix=this.wtl_events[nr]['oldstartpix'];
         }
         else if(i==1)
         {
            this.wtl_events[nr]['oldstartpixaltfrom']+=pixel;
            startpix=this.wtl_events[nr]['oldstartpixaltfrom'];
         }
         else if(i==2)
         {
            this.wtl_events[nr]['oldstartpixaltto']+=pixel;
            startpix=this.wtl_events[nr]['oldstartpixaltto'];
         }
      }
      if(inval==2 || inval==4)
      {
         endpix=this.wtl_pixel-startpix;
      }
      if(inval==1)
      {
         if(i==0)
         {
            this.wtl_events[nr]['div'].style.borderLeftWidth='0px';
            this.wtl_events[nr]['div'].style.borderRightWidth='1px';
         }
         else if(i==1)
         {
            this.wtl_events[nr]['divaltfrom'].style.borderLeftWidth='0px';
         }
         else if(i==2)
         {
            this.wtl_events[nr]['divaltto'].style.borderRightWidth='1px';
         }

//            endpix=this.getPixelFromStart(toyear, tomonth, today)-startpix;
         if(i==0 && (this.wtl_events[nr]['lastinval']!=1 || pixel==0))
         {
            endpix=this.getPixelFromStart(toyear, tomonth, today)-startpix;
            this.wtl_events[nr]['oldendpix']=endpix;
         }
         else if(i==1 && (this.wtl_events[nr]['lastinvalaltfrom']!=1 || pixel==0))
         {
            endpix=this.getPixelFromStart(toyear, tomonth, today)-startpix;
            this.wtl_events[nr]['oldendpixaltfrom']=endpix;
         }
         else if(i==2 && (this.wtl_events[nr]['lastinvalaltto']!=1 || pixel==0))
         {
            endpix=this.getPixelFromStart(toyear, tomonth, today)-startpix;
            this.wtl_events[nr]['oldendpixaltto']=endpix;
         }
         else if(i==0)
         {
            this.wtl_events[nr]['oldendpix']+=pixel;
            endpix=this.wtl_events[nr]['oldendpix'];
         }
         else if(i==1)
         {
            this.wtl_events[nr]['oldendpixaltfrom']+=pixel;
            endpix=this.wtl_events[nr]['oldendpixaltfrom'];
         }
         else if(i==2)
         {
            this.wtl_events[nr]['oldendpixaltto']+=pixel;
            endpix=this.wtl_events[nr]['oldendpixaltto'];
         }
      }
      else if(inval==2)
      {
         if(i==0)
         {
            this.wtl_events[nr]['div'].style.borderLeftWidth='1px';
            this.wtl_events[nr]['div'].style.borderRightWidth='0px';
         }
         else if(i==1)
         {
            this.wtl_events[nr]['divaltfrom'].style.borderLeftWidth='1px';
         }
         else if(i==2)
         {
            this.wtl_events[nr]['divaltto'].style.borderRightWidth='0px';
         }
      }
      else if(inval==4)
      {
         if(i==0)
         {
            this.wtl_events[nr]['div'].style.borderLeftWidth='0px';
            this.wtl_events[nr]['div'].style.borderRightWidth='0px';
         }
         else if(i==1)
         {
            this.wtl_events[nr]['divaltfrom'].style.borderLeftWidth='0px';
         }
         else if(i==2)
         {
            this.wtl_events[nr]['divaltto'].style.borderRightWidth='0px';
         }      
      }
      if(inval==3)
      {
         if(i==0)
         {
            this.wtl_events[nr]['div'].style.borderLeftWidth='1px';
            this.wtl_events[nr]['div'].style.borderRightWidth='1px';
         }
         else if(i==1)
         {
            this.wtl_events[nr]['divaltfrom'].style.borderLeftWidth='1px';
         }
         else if(i==2)
         {
            this.wtl_events[nr]['divaltto'].style.borderRightWidth='1px';
         }


         if((i==0 && this.wtl_events[nr]['fullvisible']==false) ||
            (i==1 && this.wtl_events[nr]['altfrom_fullvisible']==false) ||
            (i==2 && this.wtl_events[nr]['altto_fullvisible']==false))
         {
            if(i==0)
            {
               endpix=this.wtl_events[nr]['div_width'];
               this.wtl_events[nr]['fullvisible']=true;
               this.wtl_events[nr]['endpix']=endpix;
            }
            else if(i==1)
            {
               endpix=this.wtl_events[nr]['divaltfrom_width'];
               this.wtl_events[nr]['altfrom_fullvisible']=true;
               this.wtl_events[nr]['altfrom_endpix']=endpix;
            }
            else if(i==2)
            {
               endpix=this.wtl_events[nr]['divaltto_width'];
               this.wtl_events[nr]['altto_fullvisible']=true;
               this.wtl_events[nr]['altto_endpix']=endpix;
            }
         }
         else if(i==0)
         {
            endpix=this.wtl_events[nr]['endpix'];
         }
         else if(i==1)
         {
            endpix=this.wtl_events[nr]['altfrom_endpix'];
         }
         else if(i==2)
         {
            endpix=this.wtl_events[nr]['altto_endpix'];
         }
      }
      else if(i==0 && this.wtl_events[nr]['fullvisible']==true)
      {
         this.wtl_events[nr]['fullvisible']=false;
      }
      else if(i==1 && this.wtl_events[nr]['altfrom_fullvisible']==true)
      {
         this.wtl_events[nr]['altfrom_fullvisible']=false;
      }
      else if(i==2 && this.wtl_events[nr]['altto_fullvisible']==true)
      {
         this.wtl_events[nr]['altto_fullvisible']=false;
      }

      if(i==0)
      {
         this.wtl_events[nr]['div'].style.left=startpix + 'px';
         this.wtl_events[nr]['div'].style.width=endpix + 'px';
         mainwidth=endpix;
      }
      else if(i==1)
      {
         if(mainwidth>=2)
            endpix++;
         this.wtl_events[nr]['divaltfrom'].style.left=startpix + 'px';
         this.wtl_events[nr]['divaltfrom'].style.width=endpix + 'px';
      }
      else if(i==2)
      {
         if(mainwidth>=2)
         {
            startpix--;
            endpix++;
         }
         this.wtl_events[nr]['divaltto'].style.left=startpix + 'px';
         this.wtl_events[nr]['divaltto'].style.width=endpix + 'px';
      }

      if(i==0 && this.wtl_events[nr]['appended']==false)
      {
         this.loc.appendChild(this.wtl_events[nr]['div']);
         this.wtl_events[nr]['appended']=true;
      }
      else if(i==1 && this.wtl_events[nr]['altfrom_appended']==false)
      {
         this.loc.appendChild(this.wtl_events[nr]['divaltfrom']);
         this.wtl_events[nr]['altfrom_appended']=true;
      }
      else if(i==2 && this.wtl_events[nr]['altto_appended']==false)
      {
         this.loc.appendChild(this.wtl_events[nr]['divaltto']);
         this.wtl_events[nr]['altto_appended']=true;
      }

      if(textstart==-2 || startpix<textstart)
         textstart=startpix;
      if(textend==-2 || endpix>textend)
         textend=endpix;
   }
   else if(i==0 && this.wtl_events[nr]['appended']==true)
   {
      parent=this.wtl_events[nr]['div'].parentNode;
      parent.removeChild(this.wtl_events[nr]['div']);
      this.wtl_events[nr]['appended']=false;
      this.wtl_events[nr]['fullvisible']=false;
   }
   else if(i==1 && this.wtl_events[nr]['altfrom_appended']==true)
   {
      parent=this.wtl_events[nr]['divaltfrom'].parentNode;
      parent.removeChild(this.wtl_events[nr]['divaltfrom']);
      this.wtl_events[nr]['altfrom_appended']=false;
      this.wtl_events[nr]['altfrom_fullvisible']=false;
   }
   else if(i==2 && this.wtl_events[nr]['altto_appended']==true)
   {
      parent=this.wtl_events[nr]['divaltto'].parentNode;
      parent.removeChild(this.wtl_events[nr]['divaltto']);
      this.wtl_events[nr]['altto_appended']=false;
      this.wtl_events[nr]['altto_fullvisible']=false;
   }
  }

  if(i==0)
     this.wtl_events[nr]['lastinval']=inval;
  if(i==1)
     this.wtl_events[nr]['lastinvalaltfrom']=inval;
  if(i==2)
     this.wtl_events[nr]['lastinvalaltto']=inval;
 }

      textleft=(textstart+(textend/2));

      if(textleft>this.wtl_pixel-this.wtl_events[nr]['textwidth']-5)
         textleft=this.wtl_pixel-this.wtl_events[nr]['textwidth']-5;
      if(textleft<5)
         textleft=5;
      this.wtl_events[nr]['textleft']=textleft;

      wtl_alldivs[this.wtl_events[nr]['divtext'].id].style.left=textleft + this.locleft + 'px';
      wtl_alldivs[this.wtl_events[nr]['div'].id].style.left=textleft + this.locleft + 'px';
      if(this.wtl_events[nr]['divaltfrom']!=null)
      {
         wtl_alldivs[this.wtl_events[nr]['divaltfrom'].id].style.left=textleft + this.locleft + 'px';
      }
      if(this.wtl_events[nr]['divaltto']!=null)
      {
         wtl_alldivs[this.wtl_events[nr]['divaltto'].id].style.left=textleft + this.locleft + 'px';
      }

  if(this.wtl_connection!=2)
  {
   if(textvisible==true && this.wtl_events[nr]['showtext']==true)
   {

      if(this.wtl_events[nr]['text_appended']==false)
      {
         this.wtl_events[nr]['text_appended']=true;
         this.loc.appendChild(this.wtl_events[nr]['divtext']);
      }
      this.wtl_events[nr]['divtext'].style.left=textleft + 'px';
   }
   else if(this.wtl_events[nr]['text_appended']==true)
   {
      parent=this.wtl_events[nr]['divtext'].parentNode;
      parent.removeChild(this.wtl_events[nr]['divtext']);
      this.wtl_events[nr]['text_appended']=false;
   }
  }
}

/**
 * Calculates if the month is currently visible on the
 * horizontal date lines and displays it. Also removes 
 * no longer visible months and adds newly visible months.
 * @param {Array} month Month Array with all data concerning the month.
 */
wtl_container.prototype.drawMonthLine = function (month)
{
   var inval;
   var startpix;
   var endpix
   var parent;
   var append=false;
   var calcwidth=true;

   var fromyear=month['fromyear'];
   var frommonth=month['frommonth'];
   var toyear=month['fromyear'];
   var tomonth=month['frommonth'];
   var fromday=1;
   var today=29;
   
   inval=this.isInside(fromyear, frommonth, fromday, toyear, tomonth, today);

   if(inval>0)
   {
      if(inval==3 && month['fullvisible']==true)
         calcwidth=false;

      if(inval==1 || inval==4)
      {
         month['div'].style.borderLeftWidth='0px';
         month['div2'].style.borderLeftWidth='0px';
         startpix=-1;
      }
      else
      {
         month['div'].style.borderLeftWidth='1px';
         month['div2'].style.borderLeftWidth='1px';
      }
      if(inval==3 || inval==2)
      {
         startpix=this.getPixelFromStart(fromyear, frommonth, fromday);
      }
      if(inval==2 || inval==4)
      {
         endpix=1;
/* We won't need it for now
         endpix=this.wtl_pixel-startpix;
*/
      }
      if(inval==1)
      {
         endpix=1;
/* We won't need it for now
         endpix=this.getPixelFromStart(toyear, tomonth, today)-startpix;
*/
      }
      if(inval==3)
      {
         endpix=1;
         if(month['fullvisible']==false)
         {
/* We won't need it for now
            endpix=month['div_width'];
*/
            month['fullvisible']=true;
            month['endpix']=endpix;
         }
/* We won't need it for now
         else
         {
            endpix=month['endpix'];
         }
*/
      }
      else if(month['fullvisible']==true)
      {
         month['fullvisible']=false;
      }

      month['left']=startpix+2;
      month['div'].style.left=startpix + 'px';
      month['div'].style.width=endpix + 'px';
      month['div2'].style.left=startpix + 'px';
      month['div2'].style.width=endpix + 'px';
      month['divtext'].style.left=startpix+2 + 'px';

      if(month['appended']==false)
      {
         this.loc.appendChild(month['div']);
         this.loc.appendChild(month['div2']);
         this.loc.appendChild(month['divtext']);
         month['appended']=true;
      }

      this.drawAllDayLines(month['days']);
   }
   else if(month['appended']==true)
   {
      this.removeDays(month['days']);

      parent=month['div'].parentNode;
      parent.removeChild(month['div']);
      parent=month['div2'].parentNode;
      parent.removeChild(month['div2']);
      parent=month['divtext'].parentNode;
      parent.removeChild(month['divtext']);
      month['appended']=false;
      month['fullvisible']=false;
   }
}

/**
 * Removes a day from the timeline.
 * @param {Array} day Day Array with all data concerning the day.
 */
wtl_container.prototype.removeDays = function (days)
{
   var i;
   var parent;

   for(i=0;i<days.length;i++)
   {
      if(days[i]['appended']==true)
      {
         parent=days[i]['div'].parentNode;
         parent.removeChild(days[i]['div']);
         parent=days[i]['div2'].parentNode;
         parent.removeChild(days[i]['div2']);
         parent=days[i]['divtext'].parentNode;
         parent.removeChild(days[i]['divtext']);
         days[i]['appended']=false;
         days[i]['fullvisible']=false;
      }
   }
}

/**
 * Removes a day from the timeline and all its days.
 * @param {Array} month Month Array with all data concerning the month.
 */
wtl_container.prototype.removeMonths = function (months)
{
   var i;
   var parent;

   for(i=0;i<months.length;i++)
   {
      if(months[i]['appended']==true)
      {
         parent=months[i]['div'].parentNode;
         parent.removeChild(months[i]['div']);
         parent=months[i]['div2'].parentNode;
         parent.removeChild(months[i]['div2']);
         parent=months[i]['divtext'].parentNode;
         parent.removeChild(months[i]['divtext']);
         months[i]['appended']=false;
         months[i]['fullvisible']=false;
      }
      this.removeDays(months[i]['days']);
   }
}

/**
 * Calculates if the day is currently visible on the
 * horizontal date lines and displays it. Also removes 
 * no longer visible days and adds newly visible days.
 * @param {Array} day Day Array with all data concerning the day.
 */
wtl_container.prototype.drawDayLine = function (day)
{
   var inval;
   var startpix;
   var endpix
   var parent;
   var append=false;
   var calcwidth=true;

   var fromyear=day['fromyear'];
   var frommonth=day['frommonth'];
   var fromday=day['fromday'];
   var toyear=day['fromyear'];
   var tomonth=day['frommonth'];
   var today=fromday+1;
   
   inval=this.isInside(fromyear, frommonth, fromday, toyear, tomonth, today);

   if(inval>0)
   {
      if(inval==3 && day['fullvisible']==true)
         calcwidth=false;

      if(inval==1 || inval==4)
      {
         day['div'].style.borderLeftWidth='0px';
         day['div2'].style.borderLeftWidth='0px';
         startpix=-1;
      }
      else
      {
         day['div'].style.borderLeftWidth='1px';
         day['div2'].style.borderLeftWidth='1px';
      }
      if(inval==3 || inval==2)
      {
         startpix=this.getPixelFromStart(fromyear, frommonth, fromday);
      }
      if(inval==2 || inval==4)
      {
         endpix=1;
/* We won't need it for now
         endpix=this.wtl_pixel-startpix;
*/
      }
      if(inval==1)
      {
         endpix=1;
/* We won't need it for now
         endpix=this.getPixelFromStart(toyear, tomonth, today)-startpix;
*/
      }
      if(inval==3)
      {
         endpix=1;
         if(day['fullvisible']==false)
         {
/* We won't need it for now
            endpix=day['div_width'];
*/
            day['fullvisible']=true;
            day['endpix']=endpix;
         }
/* We won't need it for now
         else
         {
            endpix=day['endpix'];
         }
*/
      }
      else if(day['fullvisible']==true)
      {
         day['fullvisible']=false;
      }

      day['left']=startpix+2;
      day['div'].style.left=startpix + 'px';
      day['div'].style.width=endpix + 'px';
      day['div2'].style.left=startpix + 'px';
      day['div2'].style.width=endpix + 'px';
      day['divtext'].style.left=startpix+2 + 'px';

      if(day['appended']==false)
      {
         this.loc.appendChild(day['div']);
         this.loc.appendChild(day['div2']);
         this.loc.appendChild(day['divtext']);
         day['appended']=true;
      }
   }
   else if(day['appended']==true)
   {
      parent=day['div'].parentNode;
      parent.removeChild(day['div']);
      parent=day['div2'].parentNode;
      parent.removeChild(day['div2']);
      parent=day['divtext'].parentNode;
      parent.removeChild(day['divtext']);
      day['appended']=false;
      day['fullvisible']=false;
   }
}

/**
 * Checks if an event bar is inside the currently displayed timeline,
 * or if it is cut off on the left and/or right side or if it is outside the timeline.
 * @param {Integer} fromyear Start year of the event bar
 * @param {Integer} frommonth Start month of the event bar
 * @param {Integer} fromday Start day of the event bar
 * @param {Integer} toyear End year of the event bar
 * @param {Integer} tomonth End month of the event bar
 * @param {Integer} today End day of the event bar
 * @return Returns 0 if an event bar is outside the timeline, 1 if it is cut off left but
 *          not on the right side, 2 if it is cut off right but not on the left side, 3 if it
 *          is inside the timeline (not cut off left or right) and 4 if the event bar is partially
 *          visible in the timeline but cut off left and right.
 * @type Integer
 */
wtl_container.prototype.isInside = function (fromyear, frommonth, fromday, toyear, tomonth, today)
{
   var retval=0;
   var leftout=false;
   var rightout=false;
   var notin=false;
   
   if(this.wtl_exactfromyear>toyear)
      notin=true;
   else if(this.wtl_exactfromyear==toyear)
   {
      if(this.wtl_exactfrommonth>tomonth)
         notin=true;
      else if(this.wtl_exactfrommonth==tomonth)
      {
         if(this.wtl_exactfromday>today)
            notin=true;
      }
   }

   if(notin==false)
   {
      if(this.wtl_exacttoyear<fromyear)
         notin=true;
      else if(this.wtl_exacttoyear==fromyear)
      {
         if(this.wtl_exacttomonth<frommonth)
            notin=true;
         else if(this.wtl_exacttomonth==frommonth)
         {
            if(this.wtl_exacttoday<fromday)
               notin=true;
         }
      }

      if(notin==false)
      {
         if(this.wtl_exacttoyear<toyear)
            rightout=true;
         else if(this.wtl_exacttoyear==toyear)
         {
            if(this.wtl_exacttomonth<tomonth)
               rightout=true;
            else if(this.wtl_exacttomonth==tomonth)
            {
               if(this.wtl_exacttoday<today)
                  rightout=true;
            }
         }

         if(this.wtl_exactfromyear>fromyear)
            leftout=true;
         else if(this.wtl_exactfromyear==fromyear)
         {
            if(this.wtl_exactfrommonth>frommonth)
               leftout=true;
            else if(this.wtl_exactfrommonth==frommonth)
            {
               if(this.wtl_exactfromday>fromday)
                  leftout=true;
            }
         }
      }
   }

   if(notin==true)
      return 0;
   else if(leftout==true && rightout==false)
      return 1;
   else if(leftout==false && rightout==true)
      return 2;
   else if(leftout==false && rightout==false)
      return 3;
   else if(leftout==true && rightout==true)
      return 4;
}

/**
 * Returns position of date on the timeline by pixels from left starting point of the timeline.
 * @param {Integer} year Year of the date.
 * @param {Integer} month Month of the date.
 * @param {Integer} day Day of the date.
 * @return Exact position of the date by pixels from the left of the timeline
 * @type Float
 */
wtl_container.prototype.getPixelFromStart = function (year, month, day)
{
   var days;
   var pixel;

   days=this.getDaysBetweenDates(this.wtl_exactfromyear, this.wtl_exactfrommonth, this.wtl_exactfromday, year, month, day);
   pixel = this.wtl_abs * days;

   return pixel;
}

/**
 * Gets the best number of years for the interval
 * of years beeing displayed on the horizontal date lines.
 * Can only be a 1 or a 5 with a variable number of zeros behind.
 * For example: 10.000 years, 50.000 years, 100.000 years, and so on...
 * @return Interval in years
 * @type Integer
 */
wtl_container.prototype.getDateLineYears = function ()
{
   var stepyears=1;
   var nextstepyears=1;
   var switchvar=false;
   var firstrun=true;
   var endwhile=false;
   var pixel;
   var lastpixel=-1;

   this.wtl_isodd=false;
      do
      {
         if(firstrun==false)
         {
            if(switchvar==false)
            {
               stepyears=nextstepyears*5;
               this.wtl_isodd=true;
               switchvar=true;
            }
            else if(switchvar==true)
            {
               stepyears=nextstepyears*10;
               nextstepyears=nextstepyears*10;
               switchvar=false;
               this.wtl_isodd=false;
            }
         }
         else
            firstrun=false;

         pixel = this.wtl_abs * stepyears * 366;

         if(pixel>=40)
         {
            endwhile=true;
         }

         if(lastpixel!=-1 && !(lastpixel<pixel))
         {
            /* Error: Created endless loop */
            wtl_showError(wtl_errorendlessloop);
            endwhile=true;
         }

         lastpixel=pixel;
      }
      while(endwhile==false);
      
   return stepyears;
}

/**
 * Gets the best number of months for the interval
 * of months beeing displayed on the horizontal date lines for each
 * year. Can only be a 1, 2, 3, 4 or 6.
 * @return Interval in months
 * @type Integer
 */
wtl_container.prototype.getDateLineMonths = function ()
{
   var stepmonths=0;
   var pixel;
   var minpixel;


   minpixel=20;
   pixel = this.wtl_abs * 366;

   if(pixel/13>minpixel)
   {
       stepmonths=1;
   }
   else if(pixel/7>minpixel)
   {
       stepmonths=2;
   }
   else if(pixel/5>minpixel)
   {
       stepmonths=3;
   }
   else if(pixel/4>minpixel)
   {
       stepmonths=4;
   }

   return stepmonths;
}

/**
 * Gets the best number of days for the interval
 * of days beeing displayed on the horizontal date lines for each
 * months. Can only be a 1 for every day or a 10 (still, this will
 * only display day 10 and 20, but not day 30).
 * @return Interval in days
 * @type Integer
 */
wtl_container.prototype.getDateLineDays = function ()
{
   var stepdays=0;
   var pixel;
   var minpixel;


   minpixel=25;

   if(this.wtl_abs>minpixel)
   {
       stepdays=1;
   }
   else if((this.wtl_abs * 31) / 3 >minpixel)
   {
       stepdays=10;
   }

   return stepdays;
}

/**
 * Calculates the best date intervalls to be displayed on the
 * horizontal date lines. Uses the methods {@link wtl_container#getDateLineYears},
 * {@link wtl_container#getDateLineMonths} and {@link wtl_container#getDateLineDays}.
 */
wtl_container.prototype.setDateLineDates = function ()
{
   var stepyears=1;
   var stepdays=0;
   var stepmonths=0;

   stepyears=this.getDateLineYears();
   if(stepyears==1)
   {
      stepmonths=this.getDateLineMonths();
      if(stepmonths==1)
         stepdays=this.getDateLineDays();
   }

   this.wtl_stepyears=stepyears;
   this.wtl_stepmonths=stepmonths;
   this.wtl_stepdays=stepdays;
}

/**
 * Creates all years, visible on the horizontal date line, at the beginning.
 * See {@link wtl_container#createYearLine} for later adding of years.
 * See {@link wtl_container#createMonthLineDiv} for creation associated div element.
 */
wtl_container.prototype.createStartYearLines = function()
{
   var tmpyear=this.wtl_startdlyear-this.wtl_stepyears;
   var tmpfromyear;
   var nr=0;

   while(tmpyear<=this.wtl_exacttoyear)
   {
      this.wtl_dlyears[nr]=new Array();
      this.wtl_dlyears[nr]['fromyear']=tmpyear;
      tmpyear=tmpyear + this.wtl_stepyears;
      this.wtl_dlyears[nr]['toyear']=tmpyear;

      this.wtl_dlyears[nr]['left']=0;

      this.wtl_dlyears[nr]['div']=this.createYearLineDiv(1);
      this.wtl_dlyears[nr]['div2']=this.createYearLineDiv(2);
      this.wtl_dlyears[nr]['divtext']=this.createYearLineDiv(3);

      this.wtl_dlyears[nr]['maindiv']=this.createYearLineDiv(0);
      this.wtl_dlyears[nr]['appended']=false;
      this.wtl_dlyears[nr]['fullvisible']=false;

/* We won't need it for now
      this.wtl_dlyears[nr]['div_width']=this.wtl_abs*this.getDaysBetweenDates(this.wtl_dlyears[nr]['fromyear'], 1, 1, this.wtl_dlyears[nr]['toyear'], 1, 1);
*/

      this.wtl_dlyears[nr]['inval']=-1;
      this.wtl_dlyears[nr]['f']=0;

      this.wtl_dlyears[nr]['months']=this.createYearMonths(this.wtl_dlyears[nr]['fromyear']);

      this.wtl_dlyears[nr]['upvisible']=false;
      this.wtl_dlyears[nr]['downvisible']=false;

      this.wtl_dlyearsorder[nr]=nr;

      this.wtl_dlyears[nr]['divtext'].firstChild.nodeValue=this.addSeparator(new String(this.wtl_dlyears[nr]['fromyear']));
      this.wtl_dlyears[nr]['divtext'].style.display='inline';

      this.wtl_dlyears[nr]['textwidth']=this.getNumberWidth(this.wtl_dlyears[nr]['divtext'].firstChild.nodeValue);

      nr++;
   }

   this.wtl_startdlyear=tmpyear+this.wtl_stepyears;
}

/**
 * Creates the divs for the years visible on the horizontal date line.
 * See {@link wtl_container#createStartYearLines} and {@link wtl_container#createYearLine}.
 * @return The created div element.
 * @type HTML-Element (div)
 */
wtl_container.prototype.createYearLineDiv = function(divtype)
{
   var div;

      div=document.createElement('div');

      if(divtype==3)
         div.appendChild(document.createTextNode(''));

      div.style.position='absolute';
      if(divtype==3)
      {
         div.style.zIndex='3';      
         div.style.borderLeftWidth='0px';
         div.style.height=this.wtl_fontsize + 'px';
      }
      else
      {
         div.style.height='10px';
         div.style.zIndex='2';      
         div.style.borderLeftWidth='1px';
      }
      div.style.borderRightWidth='0px';
      div.style.borderBottomWidth='0px';
      div.style.borderTopWidth='0px';
      div.style.borderColor='black';
      div.style.borderStyle='solid';
      div.style.whiteSpace='nowrap';
      div.style.overflow='hidden';

      if(divtype==1)
      {
         div.style.top= '5px';
      }
      else if(divtype==2)
      {
         div.style.top= (this.wtl_height-15) + 'px';
      }
      else if(divtype==0)
      {
         div.style.borderColor='rgb(115,111,110)';
         div.style.top='15px';
         div.style.height=(this.wtl_height-30) + 'px';
         div.style.zIndex='4';
      }
      else if(divtype==3)
      {
         div.style.top= '2px';
         div.style.backgroundColor=this.wtl_bgrgb;
      }

   return div;
}

/**
 * Draws the horizontal line (and only the horizontal line) for the horizontal
 * datelines (the top as the bottom one).
 */
wtl_container.prototype.drawHDL = function()
{
   var divup;
   var divdown;

      divup=document.createElement('div');

      divup.style.left='0px';
      divup.style.width=this.wtl_pixel + 'px';
      divup.style.zIndex='4';
      divup.style.height='1px';
      divup.style.position='absolute';
      divup.style.borderLeftWidth='0px';
      divup.style.borderRightWidth='0px';
      divup.style.borderBottomWidth='0px';
      divup.style.borderTopWidth='1px';
      divup.style.borderColor='black';
      divup.style.borderStyle='solid';
      divup.style.whiteSpace='nowrap';
      divup.style.overflow='hidden';

      divup.style.top= '15px';

      divdown=document.createElement('div');

      divdown.style.left='0px';
      divdown.style.width=this.wtl_pixel + 'px';
      divdown.style.zIndex='4';
      divdown.style.height='1px';
      divdown.style.position='absolute';
      divdown.style.borderLeftWidth='0px';
      divdown.style.borderRightWidth='0px';
      divdown.style.borderBottomWidth='0px';
      divdown.style.borderTopWidth='1px';
      divdown.style.borderColor='black';
      divdown.style.borderStyle='solid';
      divdown.style.whiteSpace='nowrap';
      divdown.style.overflow='hidden';

      divdown.style.top= (this.wtl_height-15) + 'px';

   this.wtl_divdown=divdown;
   this.wtl_divup=divup;

   this.loc.appendChild(divup);
   this.loc.appendChild(divdown);
}

/**
 * Creates the divs for the months visible on the horizontal date line.
 * See {@link wtl_container#createYearMonths}.
 * @return The created div element.
 * @type HTML-Element (div)
 */
wtl_container.prototype.createMonthLineDiv = function(divtype)
{
   var div;

      div=document.createElement('div');

      div.style.zIndex='1';
      if(divtype!=3)
         div.style.height='7px';
      div.style.position='absolute';
      div.style.borderLeftWidth='1px';
      div.style.borderRightWidth='0px';
      div.style.borderBottomWidth='0px';
      div.style.borderTopWidth='0px';
      div.style.borderColor='green';
      div.style.borderStyle='solid';
      div.style.whiteSpace='nowrap';
      div.style.overflow='hidden';

      if(divtype==1)
      {
         div.style.top= '8px';
      }
      else if(divtype==2)
      {
         div.style.top= (this.wtl_height-15) + 'px';
      }
      else if(divtype==3)
      {
         div.style.zIndex='3';      
         div.style.borderLeftWidth='0px';
         div.style.top= '5px';
         div.appendChild(document.createTextNode(''));
         div.style.backgroundColor=this.wtl_bgrgb;
         div.style.color='green';
      }

   return div;
}

/**
 * Creates the divs for the days visible on the horizontal date line.
 * See {@link wtl_container#createMonthDays}.
 * @return The created div element.
 * @type HTML-Element (div)
 */
wtl_container.prototype.createDayLineDiv = function(divtype)
{
   var div;

      div=document.createElement('div');

      div.style.zIndex='2';
      if(divtype!=3)
         div.style.height='4px';
      div.style.position='absolute';
      div.style.borderLeftWidth='1px';
      div.style.borderRightWidth='0px';
      div.style.borderBottomWidth='0px';
      div.style.borderTopWidth='0px';
      div.style.borderColor='blue';
      div.style.borderStyle='solid';
      div.style.whiteSpace='nowrap';
      div.style.overflow='hidden';

      if(divtype==1)
      {
         div.style.top= '11px';
      }
      else if(divtype==2)
      {
         div.style.top= (this.wtl_height-15) + 'px';
      }
      else if(divtype==3)
      {
         div.style.height=this.wtl_fontsize + 'px';
         div.style.zIndex='3';      
         div.style.borderLeftWidth='0px';
         div.style.top= '5px';
         div.appendChild(document.createTextNode(''));
         div.style.backgroundColor=this.wtl_bgrgb;
         div.style.color='blue';
      }

   return div;
}

/**
 * Creates a year line visible on the horizontal date line.
 * See {@link wtl_container#createStartYearLines} for creation of year lines at
 * the beginning.
 * See {@link wtl_container#createYearLineDiv} for creation associated div element.
 * @param {Integer} startyear The year to be created (and therefore also caption of this year line).
 * @param {Integer} f 0 if this is a year created at the beginning, -1 if it is a year to the left side
 *                    of the timeline or 1 if it is a year to the right side of the timeline.
 * @return The index of the created year line in the {@link wtl_container#wtl_dlyears} array.
 * @type Integer
 */
wtl_container.prototype.createYearLine = function(startyear, f)
{
   var nr;
   var i;
   var newval;

   for(nr=0;nr<this.wtl_dlyears.length && this.wtl_dlyears[nr]!=null;nr++);

      this.wtl_dlyears[nr]=new Array();
      this.wtl_dlyears[nr]['fromyear']=startyear;
      this.wtl_dlyears[nr]['toyear']=startyear + this.wtl_stepyears;

      this.wtl_dlyears[nr]['left']=0;

      this.wtl_dlyears[nr]['div']=this.createYearLineDiv(1);
      this.wtl_dlyears[nr]['div2']=this.createYearLineDiv(2);
      this.wtl_dlyears[nr]['divtext']=this.createYearLineDiv(3);

      this.wtl_dlyears[nr]['maindiv']=this.createYearLineDiv(0);

      this.wtl_dlyears[nr]['appended']=false;
      this.wtl_dlyears[nr]['fullvisible']=false;

      this.wtl_dlyears[nr]['div_width']=this.wtl_abs*this.getDaysBetweenDates(this.wtl_dlyears[nr]['fromyear'], 1, 1, this.wtl_dlyears[nr]['toyear'], 1, 1);

      this.wtl_dlyears[nr]['upvisible']=false;
      this.wtl_dlyears[nr]['downvisible']=false;

      this.wtl_dlyears[nr]['f']=f;
      this.wtl_dlyears[nr]['inval']=-1;

      this.wtl_dlyears[nr]['months']=this.createYearMonths(this.wtl_dlyears[nr]['fromyear']);

      this.wtl_dlyears[nr]['divtext'].firstChild.nodeValue=this.addSeparator(new String(startyear));
      this.wtl_dlyears[nr]['divtext'].style.display='inline';

      this.wtl_dlyears[nr]['textwidth']=this.getNumberWidth(this.wtl_dlyears[nr]['divtext'].firstChild.nodeValue);

   if(f==-1)
   {
      for(i=this.wtl_dlyearsorder.length;i>0;i--)
      {
         this.wtl_dlyearsorder[i]=this.wtl_dlyearsorder[i-1];
      }
      
      this.wtl_dlyearsorder[0]=nr;
   }
   else if(f==1)
   {
      this.wtl_dlyearsorder[this.wtl_dlyearsorder.length]=nr;
   }

   return nr;
}

/**
 * Creates all month lines of one year visible on the horizontal date line.
 * See {@link wtl_container#createMonthLineDiv} for creation associated div elements.
 * @param {Integer} startyear The parent year of the months.
 * @return The month array.
 * @type Array
 */
wtl_container.prototype.createYearMonths = function(startyear)
{
   var len;
   var i;
   var cur;
   var months=new Array();

   if(this.wtl_stepmonths>0)
      len=12/this.wtl_stepmonths;
   else
      len=0;

   for(i=0;i<len;i++)
   {
      cur=i*this.wtl_stepmonths+1;

      months[i]=new Array();
      months[i]['fromyear']=startyear;
      months[i]['frommonth']=cur;

      months[i]['div']=this.createMonthLineDiv(1);
      months[i]['div2']=this.createMonthLineDiv(2);
      months[i]['divtext']=this.createMonthLineDiv(3);

      months[i]['divtext'].firstChild.nodeValue=this.wtl_marrname[cur-1];
      months[i]['textwidth']=this.getTextWidth(months[i]['divtext'].firstChild.nodeValue);

      months[i]['appended']=false;
      months[i]['fullvisible']=false;

/* We won't need it for now
      months[i]['div_width']=this.wtl_abs*this.getDaysBetweenDates(months[i]['fromyear'], months[i]['frommonth'], 1, months[i]['fromyear'], months[i]['frommonth'], 29);
*/

      months[i]['upvisible']=true;
      months[i]['downvisible']=false;
      months[i]['left']=0;

      months[i]['days']=this.createMonthDays(startyear,cur);
   }

   return months;
}

/**
 * Creates all day lines of one months visible on the horizontal date line.
 * See {@link wtl_container#createDayLineDiv} for creation associated div elements.
 * @param {Integer} startyear The parent year of the days.
 * @param {Integer} startmonths The parent month of the days.
 * @return The day array.
 * @type Array
 */
wtl_container.prototype.createMonthDays = function(startyear, startmonth)
{
   var len;
   var i;
   var cur;
   var days=new Array();

   if((this.wtl_stepdays==10 && this.wtl_inzoom<2) || (this.wtl_stepdays==1 && this.wtl_inzoom==1))
   {
         days[0]=new Array();
         days[0]['fromyear']=startyear;
         days[0]['frommonth']=startmonth;
         days[0]['fromday']=10;

         days[0]['div']=this.createDayLineDiv(1);
         days[0]['div2']=this.createDayLineDiv(2);
         days[0]['divtext']=this.createDayLineDiv(3);

         days[0]['divtext'].firstChild.nodeValue=10;
         days[0]['textwidth']=this.getNumberWidth(days[0]['divtext'].firstChild.nodeValue);

         days[0]['appended']=false;
         days[0]['fullvisible']=false;

/* We won't need it for now
         days[0]['div_width']=this.wtl_abs*this.getDaysBetweenDates(days[0]['fromyear'], days[0]['frommonth'], days[0]['fromday'], days[0]['fromyear'], days[0]['frommonth'], days[0]['fromday']+1);
*/

         days[0]['upvisible']=true;
         days[0]['downvisible']=false;
         days[0]['left']=0;

         days[1]=new Array();
         days[1]['fromyear']=startyear;
         days[1]['frommonth']=startmonth;
         days[1]['fromday']=20;

         days[1]['div']=this.createDayLineDiv(1);
         days[1]['div2']=this.createDayLineDiv(2);
         days[1]['divtext']=this.createDayLineDiv(3);

         days[1]['divtext'].firstChild.nodeValue=20;
         days[1]['textwidth']=this.getNumberWidth(days[1]['divtext'].firstChild.nodeValue);

         days[1]['appended']=false;
         days[1]['fullvisible']=false;

/* We won't need it for now
         days[1]['div_width']=this.wtl_abs*this.getDaysBetweenDates(days[1]['fromyear'], days[1]['frommonth'], days[1]['fromday'], days[1]['fromyear'], days[1]['frommonth'], days[1]['fromday']+1);
*/

         days[1]['upvisible']=true;
         days[1]['downvisible']=false;
         days[1]['left']=0;
   }
   else if(this.wtl_stepdays==1 && this.wtl_inzoom==0)
   {
      len=this.wtl_marr[startmonth-1];

      for(i=0;i<len-1;i++)
      {
         cur=i+2;

         days[i]=new Array();
         days[i]['fromyear']=startyear;
         days[i]['frommonth']=startmonth;
         days[i]['fromday']=cur;

         days[i]['div']=this.createDayLineDiv(1);
         days[i]['div2']=this.createDayLineDiv(2);
         days[i]['divtext']=this.createDayLineDiv(3);

         days[i]['divtext'].firstChild.nodeValue=cur;
         days[i]['textwidth']=this.getNumberWidth(days[i]['divtext'].firstChild.nodeValue);

         days[i]['appended']=false;
         days[i]['fullvisible']=false;

/* We won't need it for now
         days[i]['div_width']=this.wtl_abs*this.getDaysBetweenDates(days[i]['fromyear'], days[i]['frommonth'], days[i]['fromday'], days[i]['fromyear'], days[i]['frommonth'], days[i]['fromday']+1);
*/

         days[i]['upvisible']=true;
         days[i]['downvisible']=false;
         days[i]['left']=0;
      }
   }

   return days;
}

/**
 * Calculates the visible starting year on the horizontal date line.
 * Uses the {@link wtl_container#wtl_stepyears} intevall created by {@link wtl_container#getDateLineYears}
 * for calculation of the first visible year fitting to this intervall.
 */
wtl_container.prototype.setStartDLYear = function()
{
   var strdate;
   var tmpdate;
   var zeros;
   var run_zeros=0;
   var base=0;
   var switchuvar=true;
   var tmpval;

   strdate=this.wtl_stepyears.toString();
   if(this.wtl_exactfrommonth==1 && this.wtl_exactfromday==1)
      tmpdate=this.wtl_exactfromyear;
   else
      tmpdate=this.wtl_exactfromyear+1;
   zeros=strdate.length-1;

   for(i=0;i<zeros;i++)
   {
      base=Math.pow(10,i);
      u=0;
      do
      {
         tmpval=(tmpdate+u*base)/(base*10);
         if(tmpval==Math.floor(tmpval))
         {
            switchuvar=false;
         }
         else
            u++;
      }
      while(switchuvar==true);

      switchuvar=true;
      tmpdate=tmpdate+(u*base);
   }

   if(this.wtl_isodd==true)
   {
      i=zeros-1;

      base=Math.pow(10,i);
      secondbase=Math.pow(10,i+1);
      u=0;
      do
      {
         tmpval=(tmpdate+u*secondbase)/(base*50);
         if(tmpval==Math.floor(tmpval))
         {
            switchuvar=false;
         }
         else
            u++;
      }
      while(switchuvar==true);

      tmpdate=tmpdate+(u*secondbase);
   }

   this.wtl_startdlyear=tmpdate;
}

/**
 * Calculates the number of days between two dates
 * @param {Integer} fromyear Start year (Year of first date)
 * @param {Integer} frommonth Start month (Month of first date)
 * @param {Integer} fromday Start day  (Day of first date)
 * @param {Integer} toyear End year (Year of second date)
 * @param {Integer} tomonth End month (Month of second date)
 * @param {Integer} today End day (Day of second date)
 * @return Number of days between the two dates.
 * @type Integer
 */
wtl_container.prototype.getDaysBetweenDates = function (fromyear, frommonth, fromday, toyear, tomonth, today)
{
   var days=0;
   var years;
   var fulldays=0;
   var i;
   var tmpto;

   if(fromyear!=toyear)
   {
      years=toyear-fromyear-1;
      for(i=frommonth;i<12;i++)
      {
         days=days+this.wtl_marr[i];
      }
      tmpto=tomonth-1;
      for(i=0;i<tmpto;i++)
      {
         days=days+this.wtl_marr[i];
      }
      days=days+years*366;
      days=days+(this.wtl_marr[frommonth-1]-fromday);
      days=days+today;
   }
   else
   {
      if(frommonth!=tomonth)
      {
         tmpto=tomonth-1;
         for(i=frommonth;i<tmpto;i++)
         {
            days=days+this.wtl_marr[i];
         }
         days=days+(this.wtl_marr[frommonth-1]-fromday);
         days=days+today;
      }
      else
      {
         days=today-fromday;
      }
   }

   return days;
}

/**
 * Calculates a new date by adding days to a given date.
 * Does work with a positiv (adding days) or a negative (subtract days) day value.
 * @param {Integer} year Start year
 * @param {Integer} month Start month
 * @param {Integer} day Start day
 * @param {Integer} days Positive or negative number of days to add (or substract if negative).
 * @return Array of new date.
 * @type Array (Indices: 'year'=>year,'month'=>month,'day'=>day)
 */
wtl_container.prototype.getDatePlusDays = function (year, month, day, days)
{
   var years;
   var datearr=new Array();
   var i;
   var minusdays;
   var plusdays;

   if(days<0)
   {
      days=Math.abs(days);
      years=Math.floor(days/366);
      datearr['year']=year-years;
      days=days-(years*366);
      minusdays=day-days;
      if(minusdays<1)
      {
         days=days-day;
         i=(month-2);
         if(i==-1)
         {
            i=11;
            datearr['year']--;
         }
         while((this.wtl_marr[i]-1)<=days)
         {
            days=days-this.wtl_marr[i];
            i--;
            if(i==-1)
            {
               i=11;
               datearr['year']--;
            }
         }
         datearr['day']=this.wtl_marr[i]-days;
         datearr['month']=i+1;

      }
      else
      {
         datearr['day']=minusdays;
         datearr['month']=month;
      }
   }
   else
   {
      years=Math.floor(days/366);
      datearr['year']=year+years;
      days=days-(years*366);
      plusdays=day+days;
      if(plusdays>=this.wtl_marr[month-1]+1)
      {
         days=days-(this.wtl_marr[month-1]-day);
         i=month;
         if(i==12)
         {
            i=0;
            datearr['year']++;
         }
         while((this.wtl_marr[i]+1)<=days)
         {
            days=days-this.wtl_marr[i];
            i++;
            if(i==12)
            {
               i=0;
               datearr['year']++;
            }
         }
         datearr['day']=days;
         datearr['month']=i+1;
      }
      else
      {
         datearr['day']=plusdays;
         datearr['month']=month;
      }
   }


   /* if one of the following is true, there is a problem
      with close float calculations. So we will set the
      day manually (so no 1-1-32 or 1-1-0.9 can be produced) */
   if(datearr['day']>=this.wtl_marr[i]+1)
   {
      datearr['day']=1;
      i++
      if(i==12)
      {
         i=0;
         datearr['year']++;
      }
      datearr['month']=i+1;
   }
   if(datearr['day']<1)
   {
      datearr['day']=1;
   }

   return datearr;
}

/**
 * Calculates the text-width of a string.
 * @param {String} str The text
 * @return The width of the text
 * @type Integer
 */
wtl_container.prototype.getTextWidth = function (str)
{
   return (str.toString()).length * this.wtl_textwidth;
}

/**
 * Calculates the number-width of a string.
 * @param {String} str The digit text
 * @return The width of the digit text
 * @type Integer
 */
wtl_container.prototype.getNumberWidth = function (str)
{
   return (str.toString()).length * this.wtl_digitwidth;
}

/**
 * This will actually create the container at the beginning (after {@link wtl_container#setFromTo} and {@link wtl_container#createEvent} have been called)
 * and make it visible.
 */
wtl_container.prototype.createContainer = function ()
{
  if(this.loc!=null)
  {     
     var oneheight;
     var height;
     var basespace;
     var width=this.wtl_pixel;

     if(this.locparent!=null)
     {
        this.locparent.style.lineHeight=(this.wtl_fontsize + 3) + 'px';
     }
     else
     {
        this.loc.style.lineHeight=(this.wtl_fontsize + 3) + 'px';
     }

     oneheight=this.wtl_barheight+this.wtl_barspace;
     basespace=this.wtl_margespace*2-this.wtl_barspace;
     height=this.wtl_levels.length*oneheight+basespace;
     this.wtl_height=height;

     this.loc.onmousemove=wtl_mousemovecontainer;
     this.loc.onmousedown=wtl_mousedowncontainer;
     document.onmouseup=wtl_mouseupcontainer;
     this.loc.onclick=wtl_mouseoutclickdiv;

     this.loc.style.zIndex='0';
     this.loc.style.clip='rect(0px, ' + width + 'px, ' + (height) +  'px, 0px)';
     this.loc.style.width=width + 'px';
     this.loc.style.height=(height) +  'px';
     this.loc.style.position='relative';
     this.loc.style.backgroundColor=this.wtl_bgrgb;
     this.loc.style.cursor='move';

/*
   this.loc.appendChild(this.startdiv);
   this.loc.appendChild(this.startdiv2);

   this.startdiv.style.height=this.wtl_fontsize + 'px';
   this.startdiv.style.zIndex='4';
   this.startdiv.style.backgroundColor=this.wtl_bgrgb;
   this.startdiv.style.position='absolute';
   this.startdiv.style.top='1px';
   this.startdiv.style.whiteSpace='nowrap';
   this.startdiv2.style.height=this.wtl_fontsize + 'px';
   this.startdiv2.style.zIndex='4';
   this.startdiv2.style.backgroundColor=this.wtl_bgrgb;
   this.startdiv2.style.position='absolute';
   this.startdiv2.style.top= (this.wtl_levels.length*oneheight+basespace-15)+ 'px';
   this.startdiv2.style.whiteSpace='nowrap';

   this.loc.appendChild(this.enddiv);
   this.loc.appendChild(this.enddiv2);

   this.enddiv.style.height=this.wtl_fontsize + 'px';
   this.enddiv.style.zIndex='4';
   this.enddiv.style.backgroundColor=this.wtl_bgrgb;
   this.enddiv.style.position='absolute';
   this.enddiv.style.top='1px';
   this.enddiv.style.whiteSpace='nowrap';
   this.enddiv2.style.height=this.wtl_fontsize + 'px';
   this.enddiv2.style.zIndex='4';
   this.enddiv2.style.backgroundColor=this.wtl_bgrgb;
   this.enddiv2.style.position='absolute';
   this.enddiv2.style.top= (this.wtl_levels.length*oneheight+basespace-15)+ 'px';
   this.enddiv2.style.whiteSpace='nowrap';
*/
   this.locleft=this.loc.offsetLeft;

   this.drawHDL();

   if(this.wtl_connection!=2)
   {
      this.setFromTo(this.wtl_minfromyear,this.wtl_minfrommonth,this.wtl_minfromday,this.wtl_maxtoyear, this.wtl_maxtomonth,this.wtl_maxtoday);
   }

   if(this.wtl_connection==2)
   {
      this.adapt(this.wtl_connobj.wtl_minfromyear,this.wtl_connobj.wtl_minfrommonth,this.wtl_connobj.wtl_minfromday,this.wtl_connobj.wtl_maxtoyear, this.wtl_connobj.wtl_maxtomonth,this.wtl_connobj.wtl_maxtoday);
   }
   else
   {
      this.startContainer();
   }
  }
}

/**
 * This will arrange the top of the yellow info balloons again and is
 * needed if an event is added or removed.
 */
wtl_container.prototype.arrangeBalloons = function ()
{
   var nr;
   var balloontop;

   for(nr=0;nr<this.wtl_events.length;nr++)
   {
      balloontop=(((this.wtl_events[nr]['level'] * (this.wtl_barheight+this.wtl_barspace)) + this.wtl_margespace) - wtl_alldivs[this.wtl_events[nr]['div'].id].offsetHeight/2 + this.loc.offsetTop) + 'px';
      wtl_alldivs[this.wtl_events[nr]['div'].id].style.top=balloontop;
      wtl_alldivs[this.wtl_events[nr]['divtext'].id].style.top=balloontop;

      if(this.wtl_events[nr]['divaltfrom']!=null)
      {
         wtl_alldivs[this.wtl_events[nr]['divaltfrom'].id].style.top=balloontop;
      }
      if(this.wtl_events[nr]['divaltto']!=null)
      {
         wtl_alldivs[this.wtl_events[nr]['divaltto'].id].style.top=balloontop;
      }
   }
}

/**
 * This will start or restart the container and call the important methods.
 * It also hides the containers if there are no events added.
 * Called methods are (in this order): {@link wtl_container#setStartDLYear}, {@link wtl_container#showStartEndDate}, {@link wtl_container#createStartYearLines}, 
 * {@link wtl_container#drawAllYearLines}, {@link wtl_container#calculateBars}, {@link wtl_container#drawAllBars}, {@link wtl_container#arrangeBalloons}.
 */
wtl_container.prototype.startContainer = function ()
{
  var donothing=false;

   if(this.locparent!=null)
   {
      if(this.wtl_events.length!=0)
      {
         this.locparent.style.display='block';
         this.wtl_visible=true;
      }
      else
      {
         this.locparent.style.display='none';  
         donothing=true;
         this.wtl_visible=false;
      }
   }
   else if(this.loc!=null)
   {
      if(this.wtl_events.length!=0)
      {
         this.loc.style.display='block';
         this.wtl_visible=true;
      }
      else
      {
         this.loc.style.display='none';
         donothing=true;
         this.wtl_visible=false;
      }
   }

   if(donothing==false)
   {
      this.setStartDLYear();
  
    //  this.showStartEndDate();

      this.createStartYearLines();

      this.drawAllYearLines();

      this.calculateBars();

      this.drawAllBars(0);

      this.arrangeBalloons();
   }
/*
   if(this.locparent!=null)
   {
      if(this.wtl_events.length==0)
      {
            this.locparent.style.display='none';
      }
   }
   else if(this.loc!=null)
   {
      if(this.wtl_events.length==0)
      {
            this.loc.style.display='none';
      }
   }
*/
}

/**
 * This will arrange the level placement of the events new, but without
 * creating new levels. If some events can't be arranged in another level, they will
 * simply be left where they are now and the changes made at other events are still carried out.
 * (unlinke in {@link wtl_container#shuffleEvents}).
 */
wtl_container.prototype.arrangeEvents = function()
{
   var height;
   var oneheight;
   var basespace;
   var parent;
   var i;
   var u;
   var tmpevents;
   var tmplevels;
   var error=false;
   var ev;

  if(this.wtl_connection!=2)
  {
   tmplevels=new Array();
   for(i=0;i<this.wtl_levels.length;i++)
   {
      tmplevels[i]=new Array();
      for(u=0;u<this.wtl_levels[i].length;u++)
      {
         tmplevels[i][u]=this.wtl_levels[i][u];
      }
   }

   for(i=0;i<tmplevels.length;i++)
   {
      for(u=0;u<tmplevels[i].length;u++)
      {
         ev=this.wtl_events[tmplevels[i][u]];
         this.getLevel(tmplevels[i][u],ev['textwidth'],ev['altfromyear'], ev['altfrommonth'], ev['altfromday'], ev['alttoyear'], ev['alttomonth'], ev['alttoday'],true);
      }
   }

   tmpevents=new Array();
   for(i=0;i<this.wtl_events.length;i++)
   {
      tmpevents[i]=new Array();
      tmpevents[i]['name']=this.wtl_events[i]['divtext'].firstChild.nodeValue;
      tmpevents[i]['fromyear']=this.wtl_events[i]['fromyear'];
      tmpevents[i]['frommonth']=this.wtl_events[i]['frommonth'];
      tmpevents[i]['fromday']=this.wtl_events[i]['fromday'];
      tmpevents[i]['toyear']=this.wtl_events[i]['toyear'];
      tmpevents[i]['tomonth']=this.wtl_events[i]['tomonth'];
      tmpevents[i]['today']=this.wtl_events[i]['today'];
      tmpevents[i]['altfromyear']=this.wtl_events[i]['altfromyear'];
      tmpevents[i]['altfrommonth']=this.wtl_events[i]['altfrommonth'];
      tmpevents[i]['altfromday']=this.wtl_events[i]['altfromday'];
      tmpevents[i]['alttoyear']=this.wtl_events[i]['alttoyear'];
      tmpevents[i]['alttomonth']=this.wtl_events[i]['alttomonth'];
      tmpevents[i]['alttoday']=this.wtl_events[i]['alttoday'];
      tmpevents[i]['level']=this.wtl_events[i]['level'];      
      tmpevents[i]['eventlongname']=this.wtl_events[i]['eventlongname'];
      tmpevents[i]['eventtype']=this.wtl_events[i]['eventtype'];
      tmpevents[i]['eventcolor']=this.wtl_events[i]['eventcolor'];
      tmpevents[i]['articlelink']=this.wtl_events[i]['articlelink'];
      tmpevents[i]['eventtext']=this.wtl_events[i]['eventtext'];   
      tmpevents[i]['removelink']=this.wtl_events[i]['removelink'];   
      tmpevents[i]['ongoingdate']=this.wtl_events[i]['ongoingdate'];   
      tmpevents[i]['ongoingaltdate']=this.wtl_events[i]['ongoingaltdate'];   
   }

   this.removeBalloons();
   this.removeAll();

   this.wtl_neweventnr=0;
   this.wtl_events.length=0;
   this.wtl_levels.length=0;
   this.levelarray=new Array();

   if(this.wtl_connection==1)
   {
      this.wtl_connobj.removeAll();
      this.wtl_connobj.wtl_neweventnr=0;
      this.wtl_connobj.wtl_events.length=0;
      this.wtl_connobj.wtl_levels.length=0;
      this.wtl_connobj.levelarray=new Array();
   }

   for(i=0;i<tmpevents.length;i++)
   {
      this.adaptEvent(tmpevents[i]['name'],tmpevents[i]['fromyear'],tmpevents[i]['frommonth'],tmpevents[i]['fromday'],
                       tmpevents[i]['toyear'],tmpevents[i]['tomonth'],tmpevents[i]['today'],
                       tmpevents[i]['altfromyear'],tmpevents[i]['altfrommonth'],tmpevents[i]['altfromday'],
                       tmpevents[i]['alttoyear'],tmpevents[i]['alttomonth'],tmpevents[i]['alttoday'],tmpevents[i]['eventlongname'], tmpevents[i]['eventtype'], tmpevents[i]['eventcolor'], tmpevents[i]['articlelink'], tmpevents[i]['eventtext'],tmpevents[i]['ongoingdate'],tmpevents[i]['ongoingaltdate'], tmpevents[i]['removelink'],tmpevents[i]['level']);
   }

   oneheight=this.wtl_barheight+this.wtl_barspace;
   basespace=this.wtl_margespace*2-this.wtl_barspace;
   height=this.wtl_levels.length*oneheight+basespace;
   this.loc.style.height=(height) +  'px';
   this.wtl_height=height;

   parent=this.wtl_divdown.parentNode;
   parent.removeChild(this.wtl_divdown);
   parent=this.wtl_divup.parentNode;
   parent.removeChild(this.wtl_divup);
/*
   this.startdiv2.style.top= (this.wtl_levels.length*oneheight+basespace-15)+ 'px';
   this.enddiv2.style.top= (this.wtl_levels.length*oneheight+basespace-15)+ 'px';
*/
   this.checkText();

   this.drawHDL();
   
   this.startContainer();

   if(this.wtl_connection==1)
   {
      if(this.wtl_connection==1)
      {
         this.wtl_connobj.removeAll();
         this.wtl_connobj.wtl_neweventnr=0;
         this.wtl_connobj.wtl_events.length=0;
         this.wtl_connobj.wtl_levels.length=0;
      }

      for(i=0;i<tmpevents.length;i++)
      {
         this.wtl_connobj.adaptEvent(tmpevents[i]['name'],tmpevents[i]['fromyear'],tmpevents[i]['frommonth'],tmpevents[i]['fromday'],
                       tmpevents[i]['toyear'],tmpevents[i]['tomonth'],tmpevents[i]['today'],
                       tmpevents[i]['altfromyear'],tmpevents[i]['altfrommonth'],tmpevents[i]['altfromday'],
                       tmpevents[i]['alttoyear'],tmpevents[i]['alttomonth'],tmpevents[i]['alttoday'],tmpevents[i]['eventlongname'], tmpevents[i]['eventtype'], tmpevents[i]['eventcolor'], tmpevents[i]['articlelink'], tmpevents[i]['eventtext'],tmpevents[i]['ongoingdate'],tmpevents[i]['ongoingaltdate'],tmpevents[i]['removelink'], tmpevents[i]['level']);
      }

      oneheight=this.wtl_connobj.wtl_barheight+this.wtl_connobj.wtl_barspace;
      basespace=this.wtl_connobj.wtl_margespace*2-this.wtl_connobj.wtl_barspace;
      height=this.wtl_connobj.wtl_levels.length*oneheight+basespace;
      this.wtl_connobj.loc.style.height=(height) +  'px';
      this.wtl_connobj.wtl_height=height;

      parent=this.wtl_connobj.wtl_divdown.parentNode;
      parent.removeChild(this.wtl_connobj.wtl_divdown);
      parent=this.wtl_connobj.wtl_divup.parentNode;
      parent.removeChild(this.wtl_connobj.wtl_divup);
/*
      this.wtl_connobj.startdiv2.style.top= (this.wtl_connobj.wtl_levels.length*oneheight+basespace-15)+ 'px';
      this.wtl_connobj.enddiv2.style.top= (this.wtl_connobj.wtl_levels.length*oneheight+basespace-15)+ 'px';
*/
      this.wtl_connobj.drawHDL();
   
      this.wtl_connobj.startContainer();

   }
  }
}

/**
 * This will arrange the level placement of the events new, with the creation of new levels
 * if needed. If some (or just one) events can't be arranged in another level, no event will
 * be arranged in another level and therefore no changes are carried out.
 * (unlinke in {@link wtl_container#arrangeEvents}).
 */
wtl_container.prototype.shuffleEvents = function()
{
   var height;
   var oneheight;
   var basespace;
   var parent;
   var i;
   var tmpevents;
   var tmplevels;
   var error=false;

  if(this.wtl_connection!=2)
  {
   tmpevents=new Array();
   for(i=0;i<this.wtl_events.length;i++)
   {
      tmpevents[i]=new Array();
      tmpevents[i]['name']=this.wtl_events[i]['divtext'].firstChild.nodeValue;
      tmpevents[i]['fromyear']=this.wtl_events[i]['fromyear'];
      tmpevents[i]['frommonth']=this.wtl_events[i]['frommonth'];
      tmpevents[i]['fromday']=this.wtl_events[i]['fromday'];
      tmpevents[i]['toyear']=this.wtl_events[i]['toyear'];
      tmpevents[i]['tomonth']=this.wtl_events[i]['tomonth'];
      tmpevents[i]['today']=this.wtl_events[i]['today'];
      tmpevents[i]['altfromyear']=this.wtl_events[i]['altfromyear'];
      tmpevents[i]['altfrommonth']=this.wtl_events[i]['altfrommonth'];
      tmpevents[i]['altfromday']=this.wtl_events[i]['altfromday'];
      tmpevents[i]['alttoyear']=this.wtl_events[i]['alttoyear'];
      tmpevents[i]['alttomonth']=this.wtl_events[i]['alttomonth'];
      tmpevents[i]['alttoday']=this.wtl_events[i]['alttoday'];
      tmpevents[i]['level']=this.wtl_events[i]['level'];      
      tmpevents[i]['eventlongname']=this.wtl_events[i]['eventlongname'];
      tmpevents[i]['eventtype']=this.wtl_events[i]['eventtype'];
      tmpevents[i]['eventcolor']=this.wtl_events[i]['eventcolor'];
      tmpevents[i]['articlelink']=this.wtl_events[i]['articlelink'];
      tmpevents[i]['eventtext']=this.wtl_events[i]['eventtext'];   
      tmpevents[i]['removelink']=this.wtl_events[i]['removelink'];   
      tmpevents[i]['ongoingdate']=this.wtl_events[i]['ongoingdate'];   
      tmpevents[i]['ongoingaltdate']=this.wtl_events[i]['ongoingaltdate'];   
   }

   this.removeBalloons();
   this.removeAll();

   this.wtl_neweventnr=0;
   this.wtl_events.length=0;
   this.wtl_levels.length=0;
   this.levelarray=new Array();

   if(this.wtl_connection==1)
   {
      this.wtl_connobj.removeAll();
      this.wtl_connobj.wtl_neweventnr=0;
      this.wtl_connobj.wtl_events.length=0;
      this.wtl_connobj.wtl_levels.length=0;
      this.wtl_connobj.levelarray=new Array();
   }

   for(i=0;i<tmpevents.length;i++)
   {
      if(this.createEvent(tmpevents[i]['name'],tmpevents[i]['fromyear'],tmpevents[i]['frommonth'],tmpevents[i]['fromday'],
                       tmpevents[i]['toyear'],tmpevents[i]['tomonth'],tmpevents[i]['today'],
                       tmpevents[i]['altfromyear'],tmpevents[i]['altfrommonth'],tmpevents[i]['altfromday'],
                       tmpevents[i]['alttoyear'],tmpevents[i]['alttomonth'],tmpevents[i]['alttoday'],tmpevents[i]['eventlongname'], tmpevents[i]['eventtype'], tmpevents[i]['eventcolor'], tmpevents[i]['articlelink'], tmpevents[i]['eventtext'],tmpevents[i]['ongoingdate'],tmpevents[i]['ongoingaltdate'], tmpevents[i]['removelink'])!=0)
         error=true;
   }

   if(error==true)
   {
      this.removeBalloons();
      this.removeAll();

      this.wtl_neweventnr=0;
      this.wtl_events.length=0;
      this.wtl_levels.length=0;
      this.levelarray=new Array()

      if(this.wtl_connection==1)
      {
         this.wtl_connobj.removeAll();
         this.wtl_connobj.wtl_neweventnr=0;
         this.wtl_connobj.wtl_events.length=0;
         this.wtl_connobj.wtl_levels.length=0;
         this.wtl_connobj.levelarray=new Array();  
      }

      for(i=0;i<tmpevents.length;i++)
      {
         this.adaptEvent(tmpevents[i]['name'],tmpevents[i]['fromyear'],tmpevents[i]['frommonth'],tmpevents[i]['fromday'],
                          tmpevents[i]['toyear'],tmpevents[i]['tomonth'],tmpevents[i]['today'],
                          tmpevents[i]['altfromyear'],tmpevents[i]['altfrommonth'],tmpevents[i]['altfromday'],
                          tmpevents[i]['alttoyear'],tmpevents[i]['alttomonth'],tmpevents[i]['alttoday'],tmpevents[i]['eventlongname'], tmpevents[i]['eventtype'], tmpevents[i]['eventcolor'], tmpevents[i]['articlelink'], tmpevents[i]['eventtext'],tmpevents[i]['ongoingdate'],tmpevents[i]['ongoingaltdate'],tmpevents[i]['removelink'], tmpevents[i]['level']);

         if(this.wtl_connection==1)
         {
            this.wtl_connobj.adaptEvent(tmpevents[i]['name'],tmpevents[i]['fromyear'],tmpevents[i]['frommonth'],tmpevents[i]['fromday'],
                          tmpevents[i]['toyear'],tmpevents[i]['tomonth'],tmpevents[i]['today'],
                          tmpevents[i]['altfromyear'],tmpevents[i]['altfrommonth'],tmpevents[i]['altfromday'],
                          tmpevents[i]['alttoyear'],tmpevents[i]['alttomonth'],tmpevents[i]['alttoday'],tmpevents[i]['eventlongname'], tmpevents[i]['eventtype'], tmpevents[i]['eventcolor'], tmpevents[i]['articlelink'], tmpevents[i]['eventtext'],tmpevents[i]['ongoingdate'],tmpevents[i]['ongoingaltdate'],tmpevents[i]['removelink'], tmpevents[i]['level']);
         }
      }

      wtl_showError(wtl_errornospaceforshuffle);
   }

   oneheight=this.wtl_barheight+this.wtl_barspace;
   basespace=this.wtl_margespace*2-this.wtl_barspace;
   height=this.wtl_levels.length*oneheight+basespace;
   this.loc.style.height=(height) +  'px';
   this.wtl_height=height;

   parent=this.wtl_divdown.parentNode;
   parent.removeChild(this.wtl_divdown);
   parent=this.wtl_divup.parentNode;
   parent.removeChild(this.wtl_divup);
/*
   this.startdiv2.style.top= (this.wtl_levels.length*oneheight+basespace-15)+ 'px';
   this.enddiv2.style.top= (this.wtl_levels.length*oneheight+basespace-15)+ 'px';
*/
   this.checkText();

   this.drawHDL();
   
   this.startContainer();

   if(this.wtl_connection==1)
   {
      oneheight=this.wtl_connobj.wtl_barheight+this.wtl_connobj.wtl_barspace;
      basespace=this.wtl_connobj.wtl_margespace*2-this.wtl_connobj.wtl_barspace;
      height=this.wtl_connobj.wtl_levels.length*oneheight+basespace;
      this.wtl_connobj.loc.style.height=(height) +  'px';
      this.wtl_connobj.wtl_height=height;

      parent=this.wtl_connobj.wtl_divdown.parentNode;
      parent.removeChild(this.wtl_connobj.wtl_divdown);
      parent=this.wtl_connobj.wtl_divup.parentNode;
      parent.removeChild(this.wtl_connobj.wtl_divup);
/*
      this.wtl_connobj.startdiv2.style.top= (this.wtl_connobj.wtl_levels.length*oneheight+basespace-15)+ 'px';
      this.wtl_connobj.enddiv2.style.top= (this.wtl_connobj.wtl_levels.length*oneheight+basespace-15)+ 'px';
*/
      this.wtl_connobj.drawHDL();
   
      this.wtl_connobj.startContainer();

   }
  }
}

/**
 * Removes all div elements of the yellow info balloons from the timeline.
 */
wtl_container.prototype.removeBalloons = function()
{
   var i;
   var o;
   var u;
   var parent;

   for(u=0;u<wtl_alldivsnr.length;u++)
   {
      for(i=0;i<wtl_alldivsnr[u].length;i++)
      {
         for(o=0;o<wtl_alldivsnr[u][i].length;o++)
         {
            parent=wtl_alldivsnr[u][i][o].parentNode;
            parent.removeChild(wtl_alldivsnr[u][i][o]);
         }
      }
      wtl_alldivsnr[u].length=0;
   }

   wtl_alldivs.length=0;
}

/**
 * Removes all div elements of all events from the timeline.
 * It also removes and deletes all year, month and day lines
 * from the horizontal date lines.
 */
wtl_container.prototype.removeAll = function()
{
   var i;
   var nr;
   var parent;

   for(i=0;i<this.wtl_dlyearsorder.length;i++)
   {
      nr=this.wtl_dlyearsorder[i];

	   if(this.wtl_dlyears[nr]['appended']==true)
	   {
            this.removeMonths(this.wtl_dlyears[nr]['months']);

	      parent=this.wtl_dlyears[nr]['div'].parentNode;
	      parent.removeChild(this.wtl_dlyears[nr]['div']);
	      parent=this.wtl_dlyears[nr]['div2'].parentNode;
	      parent.removeChild(this.wtl_dlyears[nr]['div2']);
	      parent=this.wtl_dlyears[nr]['divtext'].parentNode;
	      parent.removeChild(this.wtl_dlyears[nr]['divtext']);
	      parent=this.wtl_dlyears[nr]['maindiv'].parentNode;
	      parent.removeChild(this.wtl_dlyears[nr]['maindiv']);

            this.wtl_dlyears[nr]['div']=null;
            this.wtl_dlyears[nr]['div2']=null;
            this.wtl_dlyears[nr]['divtext']=null;
            this.wtl_dlyears[nr]['maindiv']=null;
            this.wtl_dlyears[nr]=null;
	   }
   }

   this.wtl_dlyears.length=0;
   this.wtl_dlyearsorder.length=0;

  for(i=0;i<this.wtl_events.length;i++)
  {

   if(this.wtl_events[i]['appended']==true)
   {
      parent=this.wtl_events[i]['div'].parentNode;
      parent.removeChild(this.wtl_events[i]['div']);
      this.wtl_events[i]['appended']=false;
      this.wtl_events[i]['fullvisible']=false;
   }
   if(this.wtl_events[i]['altfrom_appended']==true)
   {
      parent=this.wtl_events[i]['divaltfrom'].parentNode;
      parent.removeChild(this.wtl_events[i]['divaltfrom']);
      this.wtl_events[i]['altfrom_appended']=false;
      this.wtl_events[i]['altfrom_fullvisible']=false;
   }
   if(this.wtl_events[i]['altto_appended']==true)
   {
      parent=this.wtl_events[i]['divaltto'].parentNode;
      parent.removeChild(this.wtl_events[i]['divaltto']);
      this.wtl_events[i]['altto_appended']=false;
      this.wtl_events[i]['altto_fullvisible']=false;
   }
   if(this.wtl_events[i]['text_appended']==true)
   {
      parent=this.wtl_events[i]['divtext'].parentNode;
      parent.removeChild(this.wtl_events[i]['divtext']);
      this.wtl_events[i]['text_appended']=false;
   }
  }
}

/**
 * Makes a connectoin between two containers. This object will be
 * the primary container/connection and the passed container is
 * the secondary (see {@link wtl_container#wtl_connection}).
 * Will call {@link wtl_container#secondaryConnection} of the connected container.
 * @param {wtl_container} conobj Reference to the container which shall be connected (secondary container).
 * @param {Integer} percent Percentage of zooming out in the secondary container (500 means 500% zooming out).
 */
wtl_container.prototype.setConnection = function (conobj, percent)
{
   var fromyear;
   var frommonth;
   var fromday;
   var toyear;
   var tomonth;
   var today;

   fromyear=this.wtl_exactfromyear;
   frommonth=this.wtl_exactfrommonth;
   fromday=this.wtl_exactfromday;
   toyear=this.wtl_exacttoyear;
   tomonth=this.wtl_exacttomonth;
   today=this.wtl_exacttoday;

   this.wtl_connection=1;
   this.wtl_connobj=conobj;

   this.wtl_connobj.secondaryConnection(fromyear,frommonth,fromday,toyear,tomonth,today,percent,this);
}

/**
 * Makes a connectoin between two containers. This object will be
 * the secondary container/connection and the passed container is
 * the primary (see {@link wtl_container#wtl_connection}).
 * Is called by the primary container in {@link wtl_container#setConnection}.
 * @param {Integer} fromyear Start year of the timeline in the primary container.
 * @param {Integer} frommonth Start month of the timeline in the primary container.
 * @param {Integer} fromday Start day of the timeline in the primary container.
 * @param {Integer} toyear End year of the timeline in the primary container.
 * @param {Integer} tomonth End month of the timeline in the primary container.
 * @param {Integer} today End day of the timeline in the primary container.
 * @param {Integer} percent Percentage of zooming out in the secondary container (500 means 500% zooming out).
 * @param {wtl_container} conobj Reference to the container which shall be connected (primary container).
 */
wtl_container.prototype.secondaryConnection = function (fromyear,frommonth,fromday,toyear,tomonth,today,percent,conobj)
{
   var add_days;
   var fromdatearr;
   var todatearr;

   this.wtl_barheight=2;
   this.wtl_barspace=4;

   this.wtl_adaptpercent=percent;
   this.wtl_connection=2;
   this.wtl_connobj=conobj;

   this.setFromTo(fromyear,frommonth,fromday,toyear,tomonth,today);

   add_days=(this.wtl_days/100)*this.wtl_adaptpercent;

   fromdatearr=this.getDatePlusDays(fromyear,frommonth,fromday,add_days * (-1));
   todatearr=this.getDatePlusDays(toyear,tomonth,today,add_days);

   this.setFromTo(fromdatearr['year'], fromdatearr['month'], fromdatearr['day'], todatearr['year'], todatearr['month'], todatearr['day']);
}

/**
 * Sets new from-to (start-end) date for the secondary container if that has
 * changed in the primary container by zooming in or out (or something drastic like that).
 * (See {@link wtl_container#wtl_connection}).
 * Is called by the primary container.
 * @param {Integer} fromyear Start year of the timeline in the primary container.
 * @param {Integer} frommonth Start month of the timeline in the primary container.
 * @param {Integer} fromday Start day of the timeline in the primary container.
 * @param {Integer} toyear End year of the timeline in the primary container.
 * @param {Integer} tomonth End month of the timeline in the primary container.
 * @param {Integer} today End day of the timeline in the primary container.
 */
wtl_container.prototype.adapt = function (fromyear,frommonth,fromday,toyear,tomonth,today)
{
   var add_days;
   var fromdatearr;
   var todatearr;

   this.setFromTo(fromyear,frommonth,fromday,toyear,tomonth,today);

   add_days=(this.wtl_days/100)*this.wtl_adaptpercent;

   fromdatearr=this.getDatePlusDays(fromyear,frommonth,fromday,add_days * (-1));
   todatearr=this.getDatePlusDays(toyear,tomonth,today,add_days);

   this.removeAll();

   this.setFromTo(fromdatearr['year'], fromdatearr['month'], fromdatearr['day'], todatearr['year'], todatearr['month'], todatearr['day']);

   this.startContainer();
}

/**
 * Zooms the timeline of this container out by the given percent.
 * @param {Integer} percent Percent to zoom out.
 */
wtl_container.prototype.zoomOut = function (percent)
{
   var fromyear;
   var frommonth;
   var fromday;
   var toyear;
   var tomonth;
   var today;
   var add_days;
   var fromdatearr;
   var todatearr;
   var fromyearstr;
   var toyearstr;

   if(this.wtl_connection==2)
   {
      this.wtl_connobj.zoomOut(percent);
   }
   else
   {

	fromyear=this.wtl_exactfromyear;
	frommonth=this.wtl_exactfrommonth;
	fromday=this.wtl_exactfromday;
	toyear=this.wtl_exacttoyear;
	tomonth=this.wtl_exacttomonth;
      today=this.wtl_exacttoday;

	add_days=(this.wtl_days/100)*percent;

	fromdatearr=this.getDatePlusDays(fromyear,frommonth,fromday,add_days * (-1));
	todatearr=this.getDatePlusDays(toyear,tomonth,today,add_days);

      fromyearstr=new String(fromdatearr['year']);
      toyearstr=new String(todatearr['year']);
      if(fromyearstr.length<14 && toyearstr.length<14)
      {
	   this.removeAll();

	   this.setFromTo(fromdatearr['year'], fromdatearr['month'], fromdatearr['day'], todatearr['year'], todatearr['month'], todatearr['day']);

         this.checkText();

	   this.startContainer();

	   if(this.wtl_connection==1)
	   {
	      this.wtl_connobj.adapt(fromdatearr['year'], fromdatearr['month'], fromdatearr['day'], todatearr['year'], todatearr['month'], todatearr['day']);
	   }
      }
      else
      {
         wtl_showError(wtl_errorcantzoomout);
         /* Error: can't zoom out that far */
      }
   }
}

/**
 * Checks the captions of all events on their visibility and
 * hides or shows them.
 */
wtl_container.prototype.checkText = function ()
{
   var i;
   var u;
   var o;
   var nr;
   var checknr;
   var days;
   var show;

  if(this.wtl_connection!=2)
  {
   for(i=0;i<this.wtl_levels.length;i++)
   {
      for(u=0;u<this.wtl_levels[i].length;u++)
      {
         nr=this.wtl_levels[i][u];
         show=true;
         for(o=0;o<this.wtl_levels[i].length;o++)
         {
            if(o!=u)
            {
               checknr=this.wtl_levels[i][o];
               if(this.wtl_events[checknr]['altfromyear']>this.wtl_events[nr]['alttoyear'] ||
                  (this.wtl_events[checknr]['altfromyear']==this.wtl_events[nr]['alttoyear'] && this.wtl_events[checknr]['altfrommonth']>this.wtl_events[nr]['alttomonth']) ||
                  (this.wtl_events[checknr]['altfromyear']==this.wtl_events[nr]['alttoyear'] && this.wtl_events[checknr]['altfrommonth']==this.wtl_events[nr]['alttomonth'] && this.wtl_events[checknr]['altfromday']>this.wtl_events[nr]['alttoday']))
               {
                  days=this.getDaysBetweenDates(this.wtl_events[nr]['alttoyear'], this.wtl_events[nr]['alttomonth'], this.wtl_events[nr]['alttoday'], this.wtl_events[checknr]['altfromyear'],this.wtl_events[checknr]['altfrommonth'],this.wtl_events[checknr]['altfromday']);
                  if((this.wtl_abs * days)<this.wtl_pixbetween+this.wtl_events[nr]['textwidth'])
                  {
                     show = false;
                  }
               }
            }
         }
         this.wtl_events[nr]['showtext']=show;
      }
   }
  }
}

/**
 * Changes the start and end date of the timeline to such, that
 * all events are visible, but no more or less. (So, it zooms exactly
 * to the earliest starting date of any event and the latest end date of
 * any event).
 */
wtl_container.prototype.showAll = function ()
{
	   var fromyear=this.wtl_minfromyear;
	   var frommonth=this.wtl_minfrommonth;
	   var fromday=this.wtl_minfromday;
	   var toyear=this.wtl_maxtoyear;
	   var tomonth=this.wtl_maxtomonth;
	   var today=this.wtl_maxtoday;

	   this.removeAll();

	   this.setFromTo(fromyear, frommonth, fromday, toyear, tomonth, today);

         this.checkText();

	   this.startContainer();

	   if(this.wtl_connection==1)
	   {
	      this.wtl_connobj.adapt(fromyear, frommonth, fromday, toyear, tomonth, today);
	   }
}

/**
 * Zooms to from-to dates, needed to zoom in on events
 * @param {Integer} fromyear Start year of the timeline in the primary container.
 * @param {Integer} frommonth Start month of the timeline in the primary container.
 * @param {Integer} fromday Start day of the timeline in the primary container.
 * @param {Integer} toyear End year of the timeline in the primary container.
 * @param {Integer} tomonth End month of the timeline in the primary container.
 * @param {Integer} today End day of the timeline in the primary container.
 */
wtl_container.prototype.zoomEvent = function (fromyear,frommonth,fromday,toyear,tomonth,today)
{
   var fromyear;
   var frommonth;
   var fromday;
   var toyear;
   var tomonth;
   var today;
   var add_days;
   var fromdatearr;
   var todatearr;

   if(this.wtl_connection==2)
   {
      this.wtl_connobj.zoomEvent(fromyear,frommonth,fromday,toyear,tomonth,today);
   }
   else
   {
	   this.removeAll();

	   this.setFromTo(fromyear,frommonth,fromday,toyear,tomonth,today);

         this.checkText();

	   this.startContainer();

	   if(this.wtl_connection==1)
	   {
	      this.wtl_connobj.adapt(fromyear,frommonth,fromday,toyear,tomonth,today);
	   }
   }
}

/**
 * Zooms the timeline of this container in by the given percent.
 * @param {Integer} percent Percent to zoom in.
 */
wtl_container.prototype.zoomIn = function (percent)
{
   var fromyear;
   var frommonth;
   var fromday;
   var toyear;
   var tomonth;
   var today;
   var add_days;
   var fromdatearr;
   var todatearr;

   if(this.wtl_connection==2)
   {
      this.wtl_connobj.zoomIn(percent);
   }
   else
   {

	   fromyear=this.wtl_exactfromyear;
	   frommonth=this.wtl_exactfrommonth;
	   fromday=this.wtl_exactfromday;
	   toyear=this.wtl_exacttoyear;
	   tomonth=this.wtl_exacttomonth;
	   today=this.wtl_exacttoday;

	   add_days=(this.wtl_days/100)*percent;

	   todatearr=this.getDatePlusDays(toyear,tomonth,today,add_days * (-1));
	   fromdatearr=this.getDatePlusDays(fromyear,frommonth,fromday,add_days);

	   this.removeAll();

	   this.setFromTo(fromdatearr['year'], fromdatearr['month'], fromdatearr['day'], todatearr['year'], todatearr['month'], todatearr['day']);

         this.checkText();

	   this.startContainer();

	   if(this.wtl_connection==1)
	   {
	      this.wtl_connobj.adapt(fromdatearr['year'], fromdatearr['month'], fromdatearr['day'], todatearr['year'], todatearr['month'], todatearr['day']);
	   }
   }
}

/**
 * Sets the beginning or a new start and end date for the timeline (the intervall that is visible).
 * @param {Integer} fromyear Start year of the timeline
 * @param {Integer} frommonth Start month of the timeline
 * @param {Integer} fromday Start day of the timeline
 * @param {Integer} toyear End year of the timeline
 * @param {Integer} tomonth End month of the timeline
 * @param {Integer} today End day of the timeline
 */
wtl_container.prototype.setFromTo = function (fromyear, frommonth, fromday, toyear, tomonth, today)
{
   var days;
   var pixel=this.wtl_pixel;

   this.wtl_exactfromyear=fromyear;
   this.wtl_exactfrommonth=frommonth;
   this.wtl_exactfromday=fromday;
   this.wtl_exacttoyear=toyear;
   this.wtl_exacttomonth=tomonth;
   this.wtl_exacttoday=today;
   this.wtl_pixel=pixel;

   days=this.getDaysBetweenDates(fromyear, frommonth, fromday, toyear, tomonth, today);

   this.wtl_days=days;

   this.wtl_abs=pixel/days;     /* how many pixel is a day */
   this.wtl_pixdays=days/pixel; /* how many days is a pixel */

   this.setFullAndPartDates();

   this.setDateLineDates();
}

/**
 * Gets the data from a webpage per AJAX at the beginning and
 * creates the events to start with (this is to avoid the cache).
 * @param {String} url The URL from where the data is to retrieve from
 */
wtl_container.prototype.getDataFrom = function (url)
{
   var getdataxhr=null;

   if(url!='')
   {
      getdataxhr=wtl_getXHR();
      if(getdataxhr!=null)
      {
         getdataxhr.open('GET',encodeURI(url),false);

         getdataxhr.send(null);
         this.loaddata(getdataxhr);
      }
   }
}

/**
 * Reads in the data from a webpage per AJAX at the beginning and
 * creates the events to start with (this is to avoid the cache).
 * @param {XMLHttpRequest Object} getdataxhr The XMLHttpRequest object with the data of the events
 */
wtl_container.prototype.loaddata = function (getdataxhr)
{
   var i;
   var u;
   var datatext;
   var dataarr=new Array();
   var len=0;

   var minfromyear;
   var minfrommonth;
   var minfromday;
   var maxtoyear;
   var maxtomonth;
   var maxtoday;

   var eventarr=new Array();
   var ealen=0;

   if (getdataxhr.readyState == 4)
   {
      if (getdataxhr.status == 200)
      {
            if(this.wtl_connection!=2)
            {
               datatext=getdataxhr.responseText;
               dataarr=datatext.split("\n");
               len=dataarr.length;

               for(u=0;u<len-1;u++)
               {
                  ealen=eventarr.length;
                  eventarr[ealen]=new Array();

                  eventarr[ealen]['name']=dataarr[u];
                  u++;
                  eventarr[ealen]['fromyear']=parseInt(dataarr[u]);
                  u++;
                  eventarr[ealen]['frommonth']=parseInt(dataarr[u]);
                  u++;
                  eventarr[ealen]['fromday']=parseInt(dataarr[u]);
                  u++;
                  eventarr[ealen]['toyear']=parseInt(dataarr[u]);
                  u++;
                  eventarr[ealen]['tomonth']=parseInt(dataarr[u]);
                  u++;
                  eventarr[ealen]['today']=parseInt(dataarr[u]);
                  u++;
                  eventarr[ealen]['altfromyear']=parseInt(dataarr[u]);
                  u++;
                  eventarr[ealen]['altfrommonth']=parseInt(dataarr[u]);
                  u++;
                  eventarr[ealen]['altfromday']=parseInt(dataarr[u]);
                  u++;
                  eventarr[ealen]['alttoyear']=parseInt(dataarr[u]);
                  u++;
                  eventarr[ealen]['alttomonth']=parseInt(dataarr[u]);
                  u++;
                  eventarr[ealen]['alttoday']=parseInt(dataarr[u]);

                  if(ealen==0 || eventarr[ealen]['altfromyear']<minfromyear ||
                     (eventarr[ealen]['altfromyear']==minfromyear && eventarr[ealen]['altfrommonth']<minfrommonth) ||
                     (eventarr[ealen]['altfromyear']==minfromyear && eventarr[ealen]['altfrommonth']==minfrommonth && eventarr[ealen]['altfromday']<minfromday))
                  {
                     minfromyear=eventarr[ealen]['altfromyear'];
                     minfrommonth=eventarr[ealen]['altfrommonth'];
                     minfromday=eventarr[ealen]['altfromday'];
                  }
                  if(ealen==0 || eventarr[ealen]['alttoyear']>maxtoyear ||
                     (eventarr[ealen]['alttoyear']==maxtoyear && eventarr[ealen]['alttomonth']>maxtomonth) ||
                     (eventarr[ealen]['alttoyear']==maxtoyear && eventarr[ealen]['alttomonth']==maxtomonth && eventarr[ealen]['alttoday']>maxtoday))
                  {
                     maxtoyear=eventarr[ealen]['alttoyear'];
                     maxtomonth=eventarr[ealen]['alttomonth'];
                     maxtoday=eventarr[ealen]['alttoday'];
                  }

                  u++;
                  eventarr[ealen]['longname']=dataarr[u];
                  u++;
                  eventarr[ealen]['eventtype']=dataarr[u];
                  u++;
                  eventarr[ealen]['color']=dataarr[u];
                  u++;
                  eventarr[ealen]['link']=dataarr[u];
                  u++;
                  eventarr[ealen]['eventtext']=dataarr[u];
                  u++;
                  eventarr[ealen]['ongoingdate']=dataarr[u];
                  u++;
                  eventarr[ealen]['ongoingaltdate']=dataarr[u];
                  u++;
                  eventarr[ealen]['removelink']=dataarr[u];
               }
               if(ealen>0)
                  this.setFromTo(minfromyear,minfrommonth,minfromday,maxtoyear,maxtomonth,maxtoday);

               ealen=eventarr.length;
               for(u=0;u<ealen;u++)
               {
                  this.createEvent(eventarr[u]['name'], eventarr[u]['fromyear'], eventarr[u]['frommonth'], eventarr[u]['fromday'], eventarr[u]['toyear'], eventarr[u]['tomonth'], eventarr[u]['today'],
                                                      eventarr[u]['altfromyear'], eventarr[u]['altfrommonth'], eventarr[u]['altfromday'], eventarr[u]['alttoyear'], eventarr[u]['alttomonth'], eventarr[u]['alttoday'],
                                                eventarr[u]['longname'], eventarr[u]['eventtype'], eventarr[u]['color'], eventarr[u]['link'], eventarr[u]['eventtext'], (eventarr[u]['ongoingdate']=='TRUE'?true:false), (eventarr[u]['ongoingaltdate']=='TRUE'?true:false), eventarr[u]['removelink']);
               }
            }
      }
      else
      {
          //Error
      }
   }
   else
   {
    // not yet ready
   }
}

/**
 * Hides any error message displayed.
 */
function wtl_hideerror()
{
   wtl_errorloc.style.display='none';
}

/**
 * Shows an error message.
 * @param {String} msg Error Message to be displayed
 */
function wtl_showError(msg)
{
   if(wtl_errorloc!=null && msg!='')
   {
      wtl_errorloc.firstChild.nodeValue= msg + ' ';
      wtl_errorloc.style.display='block';
   }
}

/**
 * Sets the HTML-div-element to be used as error message displayer, its width,
 * the message for hiding the error again and all error messages.
 * @param {String} error_id HTML-id of the div element to be used as error message displayer
 * @param {Integer} pixel Width of the error message displayer in pixel (the widht is the browser-window-width minus these pixels)
 * @param {String} hidemsg Message for hiding the last error again
 * @param {String} msg Error Message to be displayed
 * @param {String} errormaxlevel Error message for 'no more levels free'
 * @param {String} errormaxevent Error message for 'reached max. number of events'
 * @param {String} errortoolarge Error message for 'event too large'
 * @param {String} errorcantzoomout Error message for 'cannot zoom out'
 * @param {String} errorcantmove Error message for 'cannot move timeline'
 * @param {String} errorendlessloop Error message for 'endless loop created'
 * @param {String} errornospaceforshuffle Error message for 'no space to shuffle events'
 * @param {String} errorunknown Error message for an unknown error.
 */
function wtl_setError(error_id, pixel, hidemsg, errormaxlevel, errormaxevent, errortoolarge, errorcantzoomout, errorcantmove, errorendlessloop, errornospaceforshuffle, errorunknown)
{
   var hidelink;
   var hidelinkhref;

   wtl_errorloc=document.getElementById(error_id);
   wtl_errormaxlevel=errormaxlevel;
   wtl_errormaxevent=errormaxevent;
   wtl_errortoolarge=errortoolarge;
   wtl_errorcantzoomout=errorcantzoomout;
   wtl_errorcantmove=errorcantmove;
   wtl_errorendlessloop=errorendlessloop;
   wtl_errornospaceforshuffle=errornospaceforshuffle;
   wtl_errorunknown=errorunknown;
   wtl_hidemsg=hidemsg;

   if(wtl_errorloc!=null)
   {
      hidelink=document.createElement('a');
      hidelinkhref=document.createAttribute('href');
      hidelinkhref.nodeValue='javascript:wtl_hideerror();';
      hidelink.setAttributeNode(hidelinkhref);
      hidelink.appendChild(document.createTextNode(wtl_hidemsg));

      wtl_errorloc.style.backgroundColor='rgb(255,215,0)';
      wtl_errorloc.style.textAlign='center';
      wtl_errorloc.style.display='none';
      if(window.innerWidth)
         wtl_errorloc.style.width=(window.innerWidth-pixel) + 'px';
      else if(document.body.clientWidth)
         wtl_errorloc.style.width=(document.body.clientWidth-pixel) + 'px';
      else
         wtl_errorloc.style.width=pixel + 'px';
      wtl_errorloc.style.maxWidth=wtl_errorloc.style.width;
      wtl_errorloc.style.borderStyle='solid';
      wtl_errorloc.style.borderColor='rgb(255,0,0)';
      wtl_errorloc.style.borderWidth='4px';
      wtl_errorloc.appendChild(document.createTextNode(''));
      wtl_errorloc.appendChild(hidelink);
   }
}

/**
 * Removes an event from the timeline (and its connected timeline) in realtime and
 * send the information of the removing to the server or change to a new page for
 * removing the event if AJAX is not supported.
 * @param {String} toloc the URL that will be called (with AJAX or by changing the page).
 * @param {String} event_nr Index of the event in {@link wtl_container#wtl_events}.
 */
function wtl_removeEventLink(toloc, event_nr)
{
   if(toloc!='')
   {
      var xhr=wtl_getXHR();
      if(xhr!=null)
      {
         xhr.open('GET',encodeURI(wtl_scriptpath + toloc + '&wtl_deletenr=' + event_nr),false);
         xhr.send(null);
      }
      wtl_removeEvent(event_nr);
   }
   else
   {
      wtl_removeEvent(event_nr);
   }
}

/**
 * Removes an event from the timeline (and its connected timeline) in realtime.
 * @param {String} event_nr Index of the event in {@link wtl_container#wtl_events}.
 */
function wtl_removeEvent(event_nr)
{
   var parent;
   var lastevent;
   var i;
   var u;
   var o;
   var locobj=null;
   var level=0;
   var foundinlevel=false;

   for(i=0;i<wtl_alllocsnr.length;i++)
   {
      locobj=wtl_alllocsnr[i];
     if(locobj.wtl_connection!=2)
     {
      lastevent=locobj.wtl_events[event_nr];
      level=lastevent['level'];
      
      if(locobj.wtl_levels[level].length>1)
      {
         for(u=0;u<locobj.wtl_levels[level].length-1;u++)
         {
            if(locobj.wtl_levels[level][u]==event_nr)
               foundinlevel=true;
            if(foundinlevel==true)
               locobj.wtl_levels[level][u]=locobj.wtl_levels[level][u+1];
         }
         locobj.wtl_levels[level].length--;
      }
      else
      {
         for(u=level;u<locobj.wtl_levels.length-1;u++)
         {
            locobj.wtl_levels[u]=new Array();
            locobj.wtl_levels[u]=locobj.wtl_levels[u+1].slice(0);
            for(o=0;o<locobj.wtl_levels[u].length;o++)
            {
               locobj.wtl_events[locobj.wtl_levels[u][o]]['level']=u;
            }
         }
         locobj.wtl_levels.length--;
      }

      parent=wtl_alldivs[lastevent['div'].id].parentNode;
      parent.removeChild(wtl_alldivs[lastevent['div'].id]);
      wtl_alldivs[lastevent['div'].id]=null;
      parent=wtl_alldivs[lastevent['divtext'].id].parentNode;
      parent.removeChild(wtl_alldivs[lastevent['divtext'].id]);
      wtl_alldivs[lastevent['divtext'].id]=null;

      if(lastevent['divaltfrom']!=null)
      {
         parent=wtl_alldivs[lastevent['divaltfrom'].id].parentNode;
         parent.removeChild(wtl_alldivs[lastevent['divaltfrom'].id]);
         wtl_alldivs[lastevent['divaltfrom'].id]=null;
      }
      if(lastevent['divaltto']!=null)
      {
         parent=wtl_alldivs[lastevent['divaltto'].id].parentNode;
         parent.removeChild(wtl_alldivs[lastevent['divaltto'].id]);
         wtl_alldivs[lastevent['divaltto'].id]=null;
      }

      for(u=event_nr;u<wtl_alldivsnr[locobj.wtl_contnr].length-1;u++)
      {
         wtl_alldivsnr[locobj.wtl_contnr][u]=wtl_alldivsnr[locobj.wtl_contnr][u+1];
      }
      wtl_alldivsnr[locobj.wtl_contnr].length--;

      if(lastevent['appended']==true)
      {
         parent=lastevent['div'].parentNode;
         parent.removeChild(lastevent['div']);
         lastevent['appended']=false;
         lastevent['fullvisible']=false;
      }
      if(lastevent['altfrom_appended']==true)
      {
         parent=lastevent['divaltfrom'].parentNode;
         parent.removeChild(lastevent['divaltfrom']);
         lastevent['altfrom_appended']=false;
         lastevent['altfrom_fullvisible']=false;
      }
      if(lastevent['altto_appended']==true)
      {
         parent=lastevent['divaltto'].parentNode;
         parent.removeChild(lastevent['divaltto']);
         lastevent['altto_appended']=false;
         lastevent['altto_fullvisible']=false;
      }
      if(lastevent['text_appended']==true)
      {
         parent=lastevent['divtext'].parentNode;
         parent.removeChild(lastevent['divtext']);
         lastevent['text_appended']=false;
      }

      for(u=event_nr;u<locobj.wtl_events.length-1;u++)
      {
         locobj.wtl_events[u]=locobj.wtl_events[u+1];
      }
      locobj.wtl_events.length--;

      for(u=0;u<locobj.wtl_levels.length;u++)
      {
         for(o=0;o<locobj.wtl_levels[u].length;o++)
         {
            if(locobj.wtl_levels[u][o]>event_nr)
               locobj.wtl_levels[u][o]--;
         }
      }
      locobj.wtl_neweventnr--;

      locobj.arrangeEvents();
     }
   }
}

