
var exactTimeStBoard = null;
var exactTimeStBoardObject = null;
var exactTimeJSObject = null;

var cookieName = "stBoardTicker=";
var cookieParamEvaId = "evaId=";
var cookieParamStName = "stName=";
var cookieParamType = "type=";
var cookieParamTitle = "title=";
var cookieParamPosX = "posX=";
var cookieParamPosY = "posY=";

var defaultPositionX = new Array();
var defaultPositionY = new Array();
defaultPositionX["HIM"] = 20;
defaultPositionY["HIM"] = 525;
defaultPositionX["STBOARD"] = 20;
defaultPositionY["STBOARD"] = 330;

var stBoards = new Array();
var ticker = new Array();
var tickerTimeout = new Array();
var tickerParameter = new Array();
var tickerTitle = new Array();

/**
 * Class stBoard
 * Class stBoard manages a station board according to the given parameters
 */
var stBoard = Class.create();
stBoard.prototype = {

  /**
   * Constructor of class stBoard
   */
  initialize: function(evaId,name,type,productsFilter,intermediateStops,useAdjustStBoard,
                        updateStBoard,storeWholeDay,realtime,maxNrOfJourneys,time, journeyDate, slim, index)
    {
    this.evaId = parseInt(evaId);                       //! evaId of current station
    this.name = name;                                   //! name of currentStation
    this.metaZTM = (this.evaId < 1000000)? true:false;  //! ZTM Halte haben eine führende "0" in der evaid ->
                                                        //! da diese entfernt wird sind die evaids 6-stellig -> also kleiner als 1.000.000 :-) Mantis: 2159
    if(type == "arr")
      this.type = "arr";
    else
      this.type = "dep";                                //! arrival or departure board
    this.productsFilter = productsFilter;               //! product filter
    this.intermediateStops = intermediateStops;         //! boolean:should intermediate stops be shown?
    this.realtime = realtime;                           //! boolean:should realtime data be retrieved
    if(this.realtime)
      this.refreshOffset = 60000;                       //! int: interval in which realtime infos are refreshed
    this.maxNrOfJourneys = maxNrOfJourneys;             //! int:max. number of journeys that can be shown simultaniously
    this.updateStBoard = updateStBoard;                 //! boolean: should the stBoard be refreshed?
    if(this.realtime)
        this.updateStBoard = false;                     //! if realtime is active, the board will be updated by this
    this.storeWholeDay = storeWholeDay;                 //! boolean:should data for the whole day be stored in journeys?
    this.journeyDate = journeyDate;                     //! time up to which the journeys are stored in journeys
    if(this.realtime)
       this.journeyDate = "today";
    if(storeWholeDay)
      {
      this.useAdjustStBoard =  useAdjustStBoard;        //! boolean:if set the periods vary from 1/2h to 24h (according varies nrOfPeriods)
      if(useAdjustStBoard)
        this.nrOfPeriods = null;
      else
        this.nrOfPeriods = 24;                          //! number of periods. all periods have the same length
      }
    this.currentTime = time;                            //! starttime of journeys to display ("now" for actual time)
    if(this.realtime)
       this.time = "now";
    this.slim = slim;
    this.slim = false;

    this.journeys = null;                               //! array containing the journeys
    this.nextJourney = null;                            //! journey that is displayed as next journey
    this.lastJourney = null;                            //! journey that is the last displayed journey
    this.journeyIndex = null;                           //! array containing all shown journeys, index is journeyId
    this.container = null;                              //! container to display the journeys
    this.journeyTable = null;
    this.underRows = 0;
    this.lastRequestedTime = null;

    this.timeoutRefresh = null;

    //this.globalIndex = stBoards.length;
    this.globalIndex = index;

    // set cookie to save stBoard
    if(this.globalIndex == 0)
      this.setStBoardCookie();

    // create stBoard Container and get data
    this.createContainer();

    stBoards[this.globalIndex] = this;
    // get journeys
    this.getJourneys(this.time);

    },

  /**
   * get journeys via AJAX and insert them into the journeys array
   */
  getJourneys : function(time)
    {
    // catenate Url for AJAX request
    //alert(time);
    if($("tmpDiv"+this.globalIndex).style.position == "absolute")
      $("tmpDiv"+this.globalIndex).style.display = "none";
    this.lastRequestedTime = time;
    var date = new Date();
    var ajaxUrl = baseUrl;
    if(isNaN(this.evaId))
       ajaxUrl += "input="+encodeURIComponent(this.name+"!")+"&";
    else
       ajaxUrl += "input="+this.evaId+"&";
    ajaxUrl += "boardType="+this.type+"&";
// Änderung aufgrund Fehler 2070
    if(this.metaZTM)
      ajaxUrl += "ignoreMasts=1&E=0";
    else
      ajaxUrl += "disableEquivs=yes&ignoreMasts=yes&";
//    ajaxUrl += "E=0&ignoreMasts=1&";
    ajaxUrl += "selectDate="+this.journeyDate+"&";
    ajaxUrl += "time="+time+"&";
    ajaxUrl += "productsFilter="+this.productsFilter+"&";
    if((this.maxNrOfJourneys) && (!(this.storeWholeDay) || (this.journeys == null))){
      var getNrOfJourneys = 2 * this.maxNrOfJourneys;
      ajaxUrl += "maxJourneys="+getNrOfJourneys+"&";
      }
    ajaxUrl += "start="+date.getTime()+"&ajax=yes&";
    if(this.intermediateStops)
      ajaxUrl += "intermediateStops=yes&";

    // AJAX
    var myAjax = new Ajax.Request(
      ajaxUrl,
      {
        method: 'get',
        onComplete: this.insertJourneys.bind(this)
      });
    },


  /**
   * insertJourneys : handles the response to an AJAX request, fills journeys in data
   */
  insertJourneys : function(ajaxResponse)
    {
    // check if the stBoard has been deleted inbetween
    if(this.globalIndex == null)
       return;
    // check if response is JSON
    if(ajaxResponse.responseText.charAt(0) != "{"){
      // notSuccessfull, try again after a while
      //alert(this.refreshOffset);
      var time = this.lastRequestedTime;
      $("tmpDiv"+this.globalIndex).innerHTML = tError+"<br \/><a href=\"javascript:stBoards["+this.globalIndex+"].getJourneys(\'"+time+"\')\">"+tTryAgain+"</a>";
      $("tmpDiv"+this.globalIndex).style.display = "block";
      $("tmpDiv"+this.globalIndex).style.position = "absolute";
      $("tmpDiv"+this.globalIndex).style.top = "30px";
      $("tmpDiv"+this.globalIndex).style.left = "10px";
      //this.timeoutRefresh = window.setTimeout(this.getJourneys.bind(this,time),this.refreshOffset*3);
      return;
      }
    var response = eval('(' + ajaxResponse.responseText + ')');
    // set time if it isn't set already
    if (exactTimeJSObject == null) {
       exactTimeJSObject = new Date();
       exactTimeStBoardObject = new Date();
       exactTimeStBoard = response.stBoard.exactTime;
       exactTimeStBoardObject.setHours(response.stBoard.exactTimeHour);
       exactTimeStBoardObject.setMinutes(response.stBoard.exactTimeMinute);
       exactTimeStBoardObject.setSeconds(response.stBoard.exactTimeSecond);
    }

    if(isNaN(this.evaId))
         this.evaId = response.stBoard.evaId;
    var nrOfNewJourneys = response.stBoard.journey.length;
    //alert(nrOfNewJourneys);
    if(nrOfNewJourneys == 0)
      return;     // no journeys!
    // initialize journeys
    if(this.journeys == null)
      this.journeys = new Array();
    if (this.journeyIndex == null)
       this.journeyIndex = new Array();

    // if there are already journeys make sure there are no duplicates
    var currentJourneyIndex = this.journeys.length;
    var firstJourneyToInsert = 0;
    if(currentJourneyIndex > 0) {
       var lastJourneyTime = this.journeys[currentJourneyIndex - 1].time;
       var currentJourneyTime = response.stBoard.journey[0].time;
       while(lastJourneyTime == currentJourneyTime) {
         if(this.journeys[currentJourneyIndex - 1].id == response.stBoard.journey[firstJourneyToInsert].id){
            firstJourneyToInsert++;
            break;
         }
         firstJourneyToInsert++;
         currentJourneyTime = response.stBoard.journey[firstJourneyToInsert].time;
       }
    }
    // insert new journeys at the end
    var correctionOffset = 0;
    for(var i = firstJourneyToInsert; i < nrOfNewJourneys; i++)
      {
      if(this.journeyIndex[response.stBoard.journey[i].id]){
        correctionOffset++;
        //nrOfNewJourneys--;
        }
      else
        {
        this.journeys[currentJourneyIndex + i - firstJourneyToInsert - correctionOffset] = response.stBoard.journey[i];
        var currentJourneyId = response.stBoard.journey[i].id;
        this.journeyIndex[currentJourneyId] = currentJourneyIndex + i - firstJourneyToInsert - correctionOffset;
        }
      }
    // correct nr of new journeys
    nrOfNewJourneys -= correctionOffset;
    // set timeout if this was the initial request and the StBoard has to be updated
    if(nrOfNewJourneys == this.journeys.length)
      {
      this.name = response.stBoard.name;
      if(this.globalIndex == 0)
        this.setStBoardCookie();
      this.nextJourney = 0;
      if (this.updateStBoard) {
         var tmpExactTime = exactTimeStBoard.split(":");
         var exactMinutes = eval(tmpExactTime[0]*60 + parseInt(tmpExactTime[1]));
         var tmpNextJourneyTime = this.journeys[this.nextJourney].time.split(":");
         var nextJourneyMinutes = eval((tmpNextJourneyTime[0]*60) + parseInt(tmpNextJourneyTime[1]));
         if(exactMinutes <= nextJourneyMinutes)
            var minutesOffset = nextJourneyMinutes - exactMinutes +1;
         else
            var minutesOffset = (1440 - nextJourneyMinutes) + exactMinutes +1;//nächster Tag
         //alert(minutesOffset);
         //window.setTimeout(this.refreshStBoard().bind(this),minutesOffset*60000);
         }
      this.fillContainer(minutesOffset);
      }
    else if(this.storeWholeDay)
      {
       if(response.stBoard.daybreak) {
          // whole day loaded
          }
       else {
          var nextTime = this.journeys[this.journeys.length-1].time;
          this.getJourneys(encodeURIComponent(nextTime+"+1"));
          }
      }
    },


  /**
   * createContainer : creates initial div-Container containing a 'please wait' message
   */
  createContainer : function()
    {
    // create div
    this.container = document.createElement("div");
    this.container.id = "ajaxStBoard"+this.globalIndex;
    this.container.className = "ajaxStBoard";
    if(this.slim)
      this.container.style.width = "130px";
    else
      this.container.style.width = "255px";
    this.container.style.height = "auto";
    this.container.style.left = defaultPositionX["STBOARD"] + "px";
    this.container.style.position = "absolute";
    this.container.style.top = defaultPositionY["STBOARD"] + "px";
    this.container.style.zIndex = 100;

    // insert header etc.
    var headline = document.createElement("div");
    //headline.className = "ajaxStBoardHeadline";
    //var closeButton = "<div style=\"float:right;\" onclick=\"stBoards["+this.globalIndex+"].deleteStBoard()\" >x<\/div>";
    var closeButton = "<a style=\"float:right;color:#fff;padding-left:20px;\" href=\"javascript:stBoards["+this.globalIndex+"].deleteStBoard()\" >[x]<\/a>";
    //headline.innerHTML = closeButton+this.name;
    if(this.slim)
      headline.innerHTML = closeButton + this.name;
    else
      headline.innerHTML = this.name;
    this.container.appendChild(headline);
    this.journeyTable = document.createElement("table");
    if(this.slim)
      this.journeyTable.style.width = "130px";
    else
      this.journeyTable.style.width = "255px";
    this.journeyTable.style.borderSpacing = "0px";
    this.journeyTable.setAttribute("cellspacing",0,false);
    //this.journeyTable.style.overflow = "scroll";
    //journeyTable.className = "ajaxStBoard";
    this.journeyTable.style.display = "none";
    var journeyTableBody = document.createElement("tbody");
    var tableHeader = document.createElement("tr");
    var tableHeaderCell = document.createElement("th");
    tableHeaderCell.innerHTML = tTime;
    if(this.slim)
      tableHeaderCell.style.width = "45px";
    tableHeader.appendChild(tableHeaderCell);
    tableHeaderCell = document.createElement("th");
    tableHeaderCell.innerHTML = tLine;
    if(this.slim)
      tableHeaderCell.style.width = "61px";
    tableHeader.appendChild(tableHeaderCell);
    tableHeaderCell = document.createElement("th");
    tableHeaderCell.innerHTML = tDirection;
    if(this.slim)
      tableHeaderCell.style.width = "30px";
    if(this.slim)
      tableHeaderCell.style.display = "none";
    //tableHeaderCell.style.width = "120px";
    tableHeader.appendChild(tableHeaderCell);
    if(this.realtime){
       tableHeaderCell = document.createElement("th");
       tableHeaderCell.innerHTML = tRT;
       tableHeader.appendChild(tableHeaderCell);
    }
    journeyTableBody.appendChild(tableHeader);

    this.journeyTable.appendChild(journeyTableBody);
    this.container.appendChild(this.journeyTable);

    // insert div with temporary message
    var tmpDiv = document.createElement("div");
    tmpDiv.innerHTML = tWait+"<br \/><img src="+waitIcon+" \>";
    tmpDiv.id = "tmpDiv"+this.globalIndex;
    this.container.appendChild(tmpDiv);
    // insert container into body
    if(this.globalIndex == 1)
      document.getElementById("Mainmap").appendChild(this.container);
    else {
      document.getElementsByTagName("body")[0].appendChild(this.container);
      new Draggable("ajaxStBoard"+this.globalIndex, {revert:this.dragPerformed.bind(this)} );
      }
    //alert("createDiv3");

    },

  /**
   * fillContainer : fills initial div-Container with the initial journeys
   */
  fillContainer : function(minutesOffset)
    {
    if (this.container == null) {
       this.createContainer();
    }

    // show table and hide message-div
    if(this.journeyTable.style.display == "none"){
       this.journeyTable.style.display = "";
       $("tmpDiv"+this.globalIndex).style.display = "none";
    }

    // insert journeys
    if(this.globalIndex == 1)
      var closeButton = "";
    else
      var closeButton = "<a style=\"float:right;color:#fff;padding-left:20px;\" href=\"javascript:stBoards["+this.globalIndex+"].deleteStBoard()\" >[x]<\/a>";
    this.container.firstChild.innerHTML = closeButton+this.name;
    //this.container.firstChild.innerHTML = this.name;
    var journeyTableBody = this.journeyTable.firstChild;
    var nrOfJourneysToInsert = this.journeys.length;
    if((this.maxNrOfJourneys) && (this.maxNrOfJourneys < nrOfJourneysToInsert))
      nrOfJourneysToInsert = this.maxNrOfJourneys;
    if(!(this.maxNrOfJourneys))
       this.maxNrOfJourneys = nrOfJourneysToInsert;
    for(var i = 0; i < nrOfJourneysToInsert; i++){
       this.insertRow(i);
    }


    if(minutesOffset != null) {
       //alert(minutesOffset);
       this.timeoutRefresh = window.setTimeout(this.refreshStBoard.bind(),minutesOffset*60000);
    }

    // if whole day should be stored get it now
    if (this.storeWholeDay) {
       var nextTime = this.journeys[this.journeys.length-1].time;
       this.getJourneys(encodeURIComponent(nextTime+"+1"));
    }

    // if realtime is active, refresh rt infos every x seconds
    if(this.realtime){
       this.timeoutRefresh = window.setTimeout(this.refreshRealtime.bind(this),this.refreshOffset);
    }
    },


  /**
   * refreshStBoard : updates the shown journeys
   * removes the next journey and all following with the same time
   */
  refreshStBoard : function()
    {
    //alert ("refresh "+this.evaId+" "+minutesOffset);
    var removeJourney = false;
    if (this.nextJourney >= 0) {
       var removeJourney = true;
       var removeTime = this.journeys[this.nextJourney].time;
    }
    //alert(this.nextJourney);
    while(removeJourney) {
      // remove nextJourney
      this.removeJourney(this.nextJourney);

      //insert journey at the end
      if(this.journeys[this.lastJourney]){
         this.insertRow(this.lastJourney);
      }
      // update nextJourney and test if it has to be deleted, else set timeout
      this.nextJourney++;
      if((this.nextJourney >= this.journeys.length) || (this.journeys[this.nextJourney].time != removeTime)){
         removeJourney = false;
      }
    }
    // set timeout to remove next journey(s)
    var tmpExactTime = exactTimeStBoard.split(":");
    var exactMinutes = eval(tmpExactTime[0]*60 + parseInt(tmpExactTime[1]));
    var tmpNextJourneyTime = this.journeys[this.nextJourney].time.split(":");
    var nextJourneyMinutes = eval((tmpNextJourneyTime[0]*60) + parseInt(tmpNextJourneyTime[1]));
    if(exactMinutes <= nextJourneyMinutes)
       var minutesOffset = nextJourneyMinutes - exactMinutes;
    else
       var minutesOffset = (1440 - nextJourneyMinutes) + exactMinutes;//nächster Tag
    //alert(minutesOffset);
    // subtract elapsed time since setting of exactTimeJSObject
    var currentTimeObject = new Date();
    var timeDiff = currentTimeObject.getTime() - exactTimeJSObject.getTime();
    var timeOut = minutesOffset*60000 - timeDiff;
    //alert(timeOut);
    //alert(currentTimeObject.getTime()+" "+exactTimeJSObject.getTime());
    this.timeoutRefresh = this.timeoutRefresh = window.setTimeout(this.refreshStBoard.bind(this),timeOut);
    },

  /**
   * refreshRealtime : updates realtime infos and removes out of date journeys (i.e. shown journeys that are not listed in RT AJAX response)
   */
  refreshRealtime : function() {
    // get actual realtime data
    //this.getJourneys("realtime");
    // catenate Url for AJAX request
    $("tmpDiv"+this.globalIndex).style.display = "none";
    var date = new Date();
    var ajaxUrl = baseUrl;
    if(isNaN(this.evaId))
       ajaxUrl += "input="+encodeURIComponent(this.name+"!")+"&";
    else
       ajaxUrl += "input="+this.evaId+"&";
    ajaxUrl += "boardType="+this.type+"&";
    ajaxUrl += "selectDate=today&time=now&";
    ajaxUrl += "productsFilter="+this.productsFilter+"&";
    if(this.maxNrOfJourneys)
      ajaxUrl += "maxJourneys="+this.maxNrOfJourneys+"&";
    ajaxUrl += "start=yes&ajax=yes&";
    ajaxUrl += "updateRealtime="+date.getTime()+"&";
    // AJAX
    var myAjax = new Ajax.Request(
      ajaxUrl,
      {
         method: 'get',
         onComplete: this.updateRealtime.bind(this)
      });
    },

  /**
   * updateRealtime : handles the response to an AJAX realtime request
   */
  updateRealtime : function(ajaxResponse)
    {
    if(this.globalIndex == null)
       return;

    // check if response is JSON
    if(ajaxResponse.responseText.charAt(0) != "{")
      {
      //alert("test");
      $("tmpDiv"+this.globalIndex).innerHTML = tError+"<br \/><a href=\"javascript:stBoards["+this.globalIndex+"].refreshRealtime()\">"+tTryAgain+"</a>";
      $("tmpDiv"+this.globalIndex).style.display = "block";
      $("tmpDiv"+this.globalIndex).style.position = "absolute";
      $("tmpDiv"+this.globalIndex).style.top = "30px";
      $("tmpDiv"+this.globalIndex).style.left = "10px";
      //this.timeoutRefresh = window.setTimeout(this.refreshRealtime.bind(this),this.refreshOffset*3);
      return;
      }
    // alert( ajaxResponse.responseText);
    // alert( ajaxResponse.responseText);
    var response = eval('(' + ajaxResponse.responseText + ')');

    /*
    //alert(response.stBoard.journey.length);
    var nextJourneyIdRT = response.stBoard.journey[0].id;
    // remove all journeys up to nextJourneyIdRT and append new journeys for every removed one
    while(this.journeys[this.nextJourney].id != nextJourneyIdRT){
       // remove journey
       this.removeJourney(this.nextJourney);
       while(this.journeys[this.nextJourney] == null){
         this.nextJourney++;
         //alert("alt"+this.nextJourney);
         }
       // and append new one at the end
       if(this.journeys[this.lastJourney]){
          this.insertRow(this.lastJourney);
          }
       else
          this.underRows++;
    }
    while((this.underRows > 0) && (this.journeys[this.lastJourney])){
       this.insertRow(this.lastJourney);
       this.underRows--;
       }
    // remove journeys that come after a delayed journey, but have to be removed
    */

    if(response.stBoard.currentTimeLine)
      var currentTimeLineIndex = response.stBoard.currentTimeLine;
    else
      var currentTimeLineIndex = 0;

      //var currentTimeLineJourneyId = response.stBoard.journey[response.stBoard.currentTimeLine].id;
      var tmpNextJourney = this.nextJourney;
      for(var i = 0; i <= currentTimeLineIndex; i++)
        {
       // alert("i"+i+" id"+response.stBoard.journey[i].id+" index:"+this.journeyIndex[response.stBoard.journey[i].id]+" test:"+this.journeys[this.journeyIndex[response.stBoard.journey[i].id]].id);
        if(typeof(this.journeyIndex[response.stBoard.journey[i].id]) != "undefined")
          {
          var removeUpTo = this.journeyIndex[response.stBoard.journey[i].id] - 1;
          removeUpTo = (removeUpTo < (this.lastJourney - 1)) ? removeUpTo : (this.lastJourney - 1);
          for(var j = tmpNextJourney; j <= removeUpTo; j++)
            {
            if(this.journeys[j] != null)
              {
             // alert(this.journeys[j].product+" ->"+removeUpTo+"  "+response.stBoard.journey[i]+"  p:"+response.stBoard.journey[i].id);
              this.removeJourney(j);
              // and append new one at the end
              if(this.journeys[this.lastJourney]){
                 this.insertRow(this.lastJourney);
                 }
              else
                 this.underRows++;
              }
            }
          tmpNextJourney = removeUpTo + 2; // = this.journeyIndex[response.stBoard.journey[i].id]+1
          }
        }

        // fill up again to max nr of journeys
        while((this.underRows > 0) && (this.journeys[this.lastJourney])){
           this.insertRow(this.lastJourney);
           this.underRows--;
           }
    /*    while(response.stBoard.journey[i].id != this.journeys[tmpNextJourney].id){
          this.removeJourney(tmpNextJourney);
          while(this.journeys[tmpNextJourney] == null)
            tmpNextJourney++;
          alert(this.journeys[tmpNextJourney]);
          }
        tmpNextJourney++;
        } */
      // tidy up row colors and realtime-line

      //}

    // update delay info in table and data
    for(var i = 0; i < response.stBoard.journey.length; i++){
       var currentJourneyId = response.stBoard.journey[i].id;
       var currentCell = document.getElementById("delay"+currentJourneyId);
       if((currentCell) && (typeof(this.journeyIndex[currentJourneyId]) != "undefined")){
          var currentJourneyIndex = this.journeyIndex[currentJourneyId];
          if(response.stBoard.journey[i].delay){
             if(response.stBoard.journey[i].delay == "OK")
               currentCell.innerHTML = "<img src="+okIcon+" \/>";
             else {
                currentCell.innerHTML = response.stBoard.journey[i].delay;
                currentCell.className = "red";
                }
             this.journeys[currentJourneyIndex].delay = response.stBoard.journey[i].delay;
          }
          else if(response.stBoard.journey[i].status){
            if(response.stBoard.journey[i].status == "FAILURE")
              currentCell.innerHTML =  "<img src="+cancelIcon+" \/>";
            else if(response.stBoard.journey[i].status == "NEW")
              currentCell.innerHTML =  "<img src="+newIcon+" \/>";
            this.journeys[currentJourneyIndex].delay = response.stBoard.journey[i].status;
            }
          else {
            currentCell.innerHTML = "-";
            currentCell.className = "";
            this.journeys[currentJourneyIndex].delay = null;
             }
       }
    }
    //alert(document.getElementById("j"+currentJourneyId).offsetWidth+4);
    //this.container.style.width = (document.getElementById("j"+currentJourneyId).offsetWidth+4)+"px";

    // check if there are enough journeys saved for next time jump
    if(!(this.storeWholeDay)){
       var nextLast = this.lastJourney + this.maxNrOfJourneys;
       if(nextLast > this.journeys.length){
          var nextTime = this.journeys[this.journeys.length-1].time;
          this.getJourneys(encodeURIComponent(nextTime+"+1"));
          }
       }
    // next update
    this.timeoutRefresh = window.setTimeout(this.refreshRealtime.bind(this),this.refreshOffset);

    },

  /**
   * insertRow : inserts row from data into table
   */
  insertRow : function(journeyIndex) {
    var journeyTableBody = this.journeyTable.firstChild;
    var journeyRow = document.createElement("tr");
    journeyRow.id = "j"+this.journeys[journeyIndex].id;
    journeyRow.className = (journeyIndex % 2 == 0) ? "uneven":"even";
    var journeyCell = document.createElement("td");
    journeyCell.innerHTML = this.journeys[journeyIndex].time;
    journeyRow.appendChild(journeyCell);

    var directionCell = document.createElement("td");
    //directionCell.setAttribute("style","width:auto;");
    directionCell.innerHTML = this.journeys[journeyIndex].dest;
    journeyCell = document.createElement("td");
    journeyCell.innerHTML = this.journeys[journeyIndex].product;
    if(this.slim)
      journeyCell.title = directionCell.innerHTML;
    journeyRow.appendChild(journeyCell);
    if(this.slim)
      directionCell.style.display = "none";
    journeyRow.appendChild(directionCell);
    if(this.realtime){
       var journeyCell = document.createElement("td");
       journeyCell.id = "delay"+this.journeys[journeyIndex].id;
       if(this.journeys[journeyIndex].delay)
         {
         if(this.journeys[journeyIndex].delay == "OK")
           journeyCell.innerHTML = "<img src="+okIcon+" \/>";
         else
           {
           journeyCell.innerHTML = this.journeys[journeyIndex].delay;
           journeyCell.className = "red";
           }
         }
       else
         {
         journeyCell.innerHTML = "-";
         journeyCell.className = "";
         }
       journeyRow.appendChild(journeyCell);
    }
    journeyTableBody.appendChild(journeyRow);
    this.lastJourney++;
    },


  /**
   * removeJourney : removes row from data and table
   */
  removeJourney : function(journeyIndex) {
    var journeyId = this.journeys[journeyIndex].id;
    var journeyTableBody = this.journeyTable.firstChild;
    var journeyRow = $("j"+journeyId);
    journeyTableBody.removeChild(journeyRow);
    journeyRow = null;
    delete this.journeyIndex[journeyId];
    this.journeys[journeyIndex].id = null;
    this.journeys[journeyIndex].time = null;
    this.journeys[journeyIndex].product = null;
    this.journeys[journeyIndex].dest = null;
    this.journeys[journeyIndex].delay = null;
    this.journeys[journeyIndex] = null;
    },


  /**
   * deleteStBoard : deletes the stBoard with all data
   */
  deleteStBoard : function(journeyIndex) {
        if(this.globalIndex == 1)
          document.getElementById("Mainmap").removeChild(this.container);
        else
          document.getElementsByTagName("body")[0].removeChild(this.container);
        window.clearTimeout(this.timeoutRefresh);
        this.timeoutRefresh = null;
        this.evaId = null;
        this.name = null;
        this.type = null;
        this.productsFilter = null;
        this.intermediateStops = null;
        this.realtime = null;
        this.refreshOffset = null;
        this.maxNrOfJourneys = null;
        this.updateStBoard = null;
        this.storeWholeDay = null;
        this.journeyDate = null;
        this.useAdjustStBoard =  null;
        this.nrOfPeriods = null;
        this.currentTime = null;
        this.journeys = null;
        this.nextJourney = null;
        this.lastJourney = null;
        this.underRows = null;
        this.journeyIndex = null;
        this.container = null;
        this.journeyTable = null;
        var currentGlobalIndex = this.globalIndex;
        this.globalIndex = null;
        delete stBoards[currentGlobalIndex];

        // delete cookie
        if(currentGlobalIndex == 0)
          {
          var expireDate = new Date();
          expireDate.setTime(expireDate.getTime()-(24*60*60*1000)); // set date 1 day ago, so the cookie is expired
          document.cookie = cookieName + ";expires=" + expireDate.toGMTString() + ";domain=" + window.location.host + ";path=/";
          }
  },

  /**
   * setStBoardCookie : sets cookie to save stBoard
   */
  setStBoardCookie : function(){
     var cookieValue = "";
     if(this.evaId)
       cookieValue = cookieParamEvaId + this.evaId +"&";
     if(this.name)
       cookieValue += cookieParamStName + this.name +"&";
     cookieValue += cookieParamType + this.type +"&";
     if(this.container){
       cookieValue += cookieParamPosX + this.container.style.left +"&";
       cookieValue += cookieParamPosY + this.container.style.top +"&";
       }

     //alert(cookieValue);
     cookieValue = encodeURIComponent(cookieValue);

     var expireDate = new Date();
     expireDate.setFullYear(expireDate.getFullYear() + 1);
     document.cookie = cookieName + cookieValue+ ";expires=" + expireDate.toGMTString() + ";domain=" + window.location.host + ";path=/";
  },

  /**
   * dragPerformed : sets cookie to save position
   */
  dragPerformed : function(){
     // check if the stBoard has to be snapped in
     var currentX = parseInt(this.container.style.left);
     var currentY = parseInt(this.container.style.top);
     if((Math.abs(currentX - defaultPositionX["STBOARD"]) < 40) && (Math.abs(currentY - defaultPositionY["STBOARD"]) < 40)) {
       this.container.style.left = defaultPositionX["STBOARD"]+"px";
       this.container.style.top = defaultPositionY["STBOARD"]+"px";
       }
     // set cookie to save the new position
     if(this.globalIndex == 0)
      this.setStBoardCookie();
  }

};


  function initStBoardFromCookie() {
         // is there a stBoard cookie ?
         if (navigator.cookieEnabled == true)
            {
            var cookie = document.cookie;
            var startIndex = cookie.indexOf(cookieName);
            if (startIndex > -1)
               {
               // cookie found
               startIndex += cookieName.length;
               var endIndex = cookie.indexOf(";",startIndex);
               endIndex = (endIndex > -1) ? endIndex : cookie.length;
               var cookieValue = cookie.substring(startIndex,endIndex);
               cookieValue = decodeURIComponent(cookieValue);
               // search for parameters
               // evaId
               var cookieEvaId = "";
               startIndex = cookieValue.indexOf(cookieParamEvaId);
               if (startIndex > -1){
                 startIndex += cookieParamEvaId.length;
                 endIndex = cookieValue.indexOf("&",startIndex);
                 endIndex = (endIndex > -1) ? endIndex : cookieValue.length;
                 cookieEvaId = cookieValue.substring(startIndex,endIndex);
                 }
               // station name
               var cookieStation = "";
               startIndex = cookieValue.indexOf(cookieParamStName);
               if (startIndex > -1){
                 startIndex += cookieParamStName.length;
                 endIndex = cookieValue.indexOf("&",startIndex);
                 endIndex = (endIndex > -1) ? endIndex : cookieValue.length;
                 cookieStation = cookieValue.substring(startIndex,endIndex);
                 }
               // station type
               var cookieStType = "dep";
               startIndex = cookieValue.indexOf(cookieParamType);
               if (startIndex > -1){
                 startIndex += cookieParamType.length;
                 endIndex = cookieValue.indexOf("&",startIndex);
                 endIndex = (endIndex > -1) ? endIndex : cookieValue.length;
                 cookieStType = cookieValue.substring(startIndex,endIndex);
                 }
               // position of stBoard container
               var cookiePosX = "";
               startIndex = cookieValue.indexOf(cookieParamPosX);
               if (startIndex > -1){
                 startIndex += cookieParamPosX.length;
                 endIndex = cookieValue.indexOf("&",startIndex);
                 endIndex = (endIndex > -1) ? endIndex : cookieValue.length;
                 cookiePosX = cookieValue.substring(startIndex,endIndex);
                 }
               var cookiePosY = "";
               startIndex = cookieValue.indexOf(cookieParamPosY);
               if (startIndex > -1){
                 startIndex += cookieParamPosY.length;
                 endIndex = cookieValue.indexOf("&",startIndex);
                 endIndex = (endIndex > -1) ? endIndex : cookieValue.length;
                 cookiePosY = cookieValue.substring(startIndex,endIndex);
                 }

               // create stBoard
               var nextIndex = stBoards.length;
               stBoards[nextIndex] = new stBoard(cookieEvaId,cookieStation,cookieStType,"1111111111",false,false,false,false,true,10,"now","today", true, nextIndex);
               // move to position stored in the cookie
               if (cookiePosX != "")
                 {
                 stBoards[nextIndex].container.style.left = cookiePosX;
                 }
               if (cookiePosY != "")
                 {
                 stBoards[nextIndex].container.style.top = cookiePosY;
                 }
               }
            }
}


function testit(station,type,time, details){
//alert(station);
   //update board, store whole day
  //var testBoard = new stBoard(station,station,type,"1111111111",false,false,true,true,false,10,"now","19.03.2007");
  //update board, store whole day,realtime
  //var testBoard = new stBoard(station,"test",type,"1111111111",false,false,true,true,true,10,"now","19.03.2007");
   // realtime
   var nextIndex = stBoards.length;
   stBoards[nextIndex] = new stBoard(station,station,type,"1111111111",false,false,false,false,true,10,"now","today", true, nextIndex);
}

/**
 * createStBoardTicker(station,type)
 * creates stBoard to remain on the page (get data for one day, set cookie, draggable, slim)
 * realtime is true
 * only 1 ticker at the same time
 * @param station - the station, to which the journeys will be returned
 * @param type    - "dep","arr" departure or arrival
 * @see createStBoardTicker
 */
  function createStBoardTicker(station, type){
    if(station == "")
        return;
    // if there are ticker already, delete them
    var nextIndex = stBoards.length;
    if(nextIndex > 0) {
      for (var i = 0; i < nextIndex; i++)
        {
        if(stBoards[i] != null)
          {
          stBoards[i].deleteStBoard();
          delete stBoards[i];
          }
        }
      stBoards = new Array();
      nextIndex = 0;
      }
    if(type != "arr")
      type = "dep";
    stBoards[nextIndex] = new stBoard(station,station,type,"1111111111",false,false,false,false,true,10,"now","today", true, nextIndex);
  }


  function createStBoardTicker2(station, type, index, posX, posY){
    if(station == "")
        return;
    // if there are ticker already, delete them
    //var nextIndex = stBoards.length;
      if(typeof(stBoards[index]) != "undefined")
        {
        stBoards[index].deleteStBoard();
        delete stBoards[index];
        }

    if(type != "arr")
      type = "dep";
    stBoards[index] = new stBoard(station,station,type,"1111111111",false,false,false,false,true,10,"now","today", false, index);
    if(index == 1)
      {
      stBoards[index].container.style.top = posY+"px";
      stBoards[index].container.style.left = (posX+20)+"px";
      //stBoards[index].container.style.width = "230px"
      //stBoards[index].journeyTable.style.width = "230px"
      }
  }

  function createStBoardTicker3(evaId, station, type, index, posX, posY){
    if(station == ""||evaId=="")
        return;
    // if there are ticker already, delete them
    //var nextIndex = stBoards.length;
      if(typeof(stBoards[index]) != "undefined")
        {
        stBoards[index].deleteStBoard();
        delete stBoards[index];
        }

    if(type != "arr")
      type = "dep";
    stBoards[index] = new stBoard(evaId,station,type,"1111111111",false,false,false,false,true,10,"now","today", false, index);
    if(index == 1)
      {
      stBoards[index].container.style.top = posY+"px";
      stBoards[index].container.style.left = (posX+20)+"px";
      //stBoards[index].container.style.width = "230px"
      //stBoards[index].journeyTable.style.width = "230px"
      }
  }

  function createTicker(type, title){
    tickerTitle[type] = title;
    if(typeof(ticker[type]) != "undefined")
      return;
    ticker[type] = document.createElement("div");
    ticker[type].className = "ajaxStBoard";
    ticker[type].id = "ticker-"+type;
    ticker[type].style.width = "130px";
    ticker[type].style.position = "absolute";
    ticker[type].style.top = defaultPositionY[type]+"px";
    ticker[type].style.left = defaultPositionX[type]+"px";
    var himTickerHeader = document.createElement("div");
    var closeButton = "<a style=\"float:right;color:#fff;padding-left:20px;\" href=\"javascript:deleteTicker('"+type+"')\" >[x]<\/a>";
    himTickerHeader.innerHTML = closeButton + title;
    ticker[type].appendChild(himTickerHeader);
    var tickerMessageBox = document.createElement("div");
    tickerMessageBox.style.display = "none";
    tickerMessageBox.style.position = "absolute";
    tickerMessageBox.style.top = "30px";
    tickerMessageBox.style.left = "10px";
    tickerMessageBox.style.width = "100px";
    tickerMessageBox.style.zIndex = "100";
    ticker[type].appendChild(tickerMessageBox);

    //var himTickerTable = document.createElement("table");
    //himTickerTable.style.width = "130px";
    //himTickerTable.style.borderSpacing = "0px";
    //var himTableBody = document.createElement("tbody");
    //var himTableRow = document.createElement("tr");
    //var himTableCell = document.createElement("td");
    //himTableCell.colspan = "2";
    //himTableRow.appendChild(himTableCell);
    //himTableBody.appendChild(himTableRow);
    //himTickerTable.appendChild(himTableBody);
    //ticker[type].appendChild(himTickerTable);
    var tickerContentDiv = document.createElement("div");
    tickerContentDiv.innerHTML = "<div>"+tWait+"<br \/><img src="+waitIcon+" \><\/div>";
    tickerContentDiv.style.padding = "0px";
    tickerContentDiv.style.background = "#fff";
    tickerContentDiv.style.color = "#000"
    ticker[type].appendChild(tickerContentDiv);
    document.getElementsByTagName("body")[0].appendChild(ticker[type]);
    new Draggable("ticker-"+type, {revert:function() {tickerDragPerformed(type);}} );
    setTickerCookie(type);
    updateTickerMessages(type);

  }


  function updateTickerMessages(type)
    {
     //alert(ticker[type].firstChild.nextSibling.nodeName);
     ticker[type].firstChild.nextSibling.style.display = "none";
    //alert(ticker[type].firstChild.nextSibling.style.display);
    // catenate Url for AJAX request
    var date = new Date();
    if(type == "HIM")
      {
      var ajaxUrl = helpBaseUrl;
      ajaxUrl += "tpl=him_messages&";
      ajaxUrl += "start="+date.getTime();
      }
    else if(type == "STBOARD")
      {
      var ajaxUrl = baseUrl;
      ajaxUrl += tickerParameter[type];
      ajaxUrl += "start="+date.getTime();
      }
    //alert(type);

    // AJAX
    var myAjax = new Ajax.Request(
      ajaxUrl,
      {
        method: 'get',
        onComplete: function(ajaxResponse) {showTickerMessages(ajaxResponse, type);}
      });
    }

  function showTickerMessages(ajaxResponse, type){
    // search for tbody of himTicker
    var typeIndex = ajaxResponse.responseText.indexOf("&");
    // no valid answer
    if((typeIndex < 0) || (typeIndex > 10))
      {
      ticker[type].firstChild.nextSibling.innerHTML = tError+"<br /><a href=\"javascript:updateTickerMessages(\'"+type+"\')\">"+tTryAgain+"<\/a>";
      ticker[type].firstChild.nextSibling.style.display = "block";
      }
    else
      {
      //var type = ajaxResponse.responseText.slice(0,typeIndex);
      //alert(ajaxResponse.responseText.slice(typeIndex+1));
      //var tickerTBody = ticker[type].firstChild.nextSibling.nextSibling.firstChild;
      var tickerTBody = ticker[type].firstChild.nextSibling.nextSibling;
      //while((himTBody.nodeName != "TBODY"))
      //alert(himTBody.nodeName);
     //alert(ajaxResponse.responseText.slice(typeIndex+1));
      tickerTBody.innerHTML = ajaxResponse.responseText.slice(typeIndex+1);
      tickerTimeout[type] = window.setTimeout("updateTickerMessages('"+type+"')",10000);
      }
  }

  function tickerDragPerformed(type){
    //var type="HIM";
    //alert(type);
    var currentX = parseInt(ticker[type].style.left);
    var currentY = parseInt(ticker[type].style.top);
    //alert(currentX+" "+currentY);
    if((Math.abs(currentX - defaultPositionX[type]) < 40) && (Math.abs(currentY - defaultPositionY[type]) < 40)) {
      ticker[type].style.left = defaultPositionX[type]+"px";
      ticker[type].style.top = defaultPositionY[type]+"px";
      }
    setTickerCookie(type);
  }

  function setTickerCookie(type){
    var cookieName = "ticker"+type+"=";
    var cookieValue = "type="+type+"&title="+tickerTitle[type]+"&";
    cookieValue += cookieParamPosX+ticker[type].style.left+"&";
    cookieValue += cookieParamPosY+ticker[type].style.top+"&";
    var expireDate = new Date();
    expireDate.setFullYear(expireDate.getFullYear() + 1);
    document.cookie = cookieName + encodeURIComponent(cookieValue)+ ";expires=" + expireDate.toGMTString() + ";domain=" + window.location.host + ";path=/";
  }

  function deleteTicker(type){
    document.getElementsByTagName("body")[0].removeChild(ticker[type]);
    window.clearTimeout(tickerTimeout[type]);
    delete ticker[type];
    delete tickerTimeout[type];

    var expireDate = new Date();
    expireDate.setTime(expireDate.getTime()-(24*60*60*1000)); // set date 1 day ago, so the cookie is expired
    document.cookie = "tickerHIM=" + ";expires=" + expireDate.toGMTString() + ";domain=" + window.location.host + ";path=/";
  }

  function createStationBoardTicker(station,boardType,title){
    type = "STBOARD";
    tickerParameter[type] = "input="+station+"&boardType="+boardType+"&selectDate=today&time=now&maxJourneys=10&ajax=yes&style=HTML&";
    createTicker(type,title);
  }

  function initTickerFromCookie() {
    // is there a stBoard cookie ?
    if (navigator.cookieEnabled == true)
       {
       var cookie = document.cookie;
       var startIndex = cookie.indexOf("tickerHIM");
       if (startIndex > -1)
          {
          // cookie found
          startIndex += 10;
          var endIndex = cookie.indexOf(";",startIndex);
          endIndex = (endIndex > -1) ? endIndex : cookie.length;
          var cookieValue = cookie.substring(startIndex,endIndex);
          cookieValue = decodeURIComponent(cookieValue);
          // search for parameters
          // type
          var cookieType = "";
          startIndex = cookieValue.indexOf(cookieParamType);
          if (startIndex > -1){
            startIndex += cookieParamType.length;
            endIndex = cookieValue.indexOf("&",startIndex);
            endIndex = (endIndex > -1) ? endIndex : cookieValue.length;
            cookieType = cookieValue.substring(startIndex,endIndex);
            }
          // title
          var cookieTitle = "";
          startIndex = cookieValue.indexOf(cookieParamTitle);
          if (startIndex > -1){
            startIndex += cookieParamTitle.length;
            endIndex = cookieValue.indexOf("&",startIndex);
            endIndex = (endIndex > -1) ? endIndex : cookieValue.length;
            cookieTitle = cookieValue.substring(startIndex,endIndex);
            }
          // position of stBoard container
          var cookiePosX = "";
          startIndex = cookieValue.indexOf(cookieParamPosX);
          if (startIndex > -1){
            startIndex += cookieParamPosX.length;
            endIndex = cookieValue.indexOf("&",startIndex);
            endIndex = (endIndex > -1) ? endIndex : cookieValue.length;
            cookiePosX = cookieValue.substring(startIndex,endIndex);
            }
          var cookiePosY = "";
          startIndex = cookieValue.indexOf(cookieParamPosY);
          if (startIndex > -1){
            startIndex += cookieParamPosY.length;
            endIndex = cookieValue.indexOf("&",startIndex);
            endIndex = (endIndex > -1) ? endIndex : cookieValue.length;
            cookiePosY = cookieValue.substring(startIndex,endIndex);
            }

          // create ticker
          createTicker(cookieType,cookieTitle);
          // move to position stored in the cookie
          if (cookiePosX != "")
            {
            ticker[cookieType].style.left = cookiePosX;
            }
          if (cookiePosY != "")
            {
            ticker[cookieType].style.top = cookiePosY;
            }
          setTickerCookie(cookieType);
          }
       }
  }

  function initAllTickerFromCookie(){
    initStBoardFromCookie();
    initTickerFromCookie();
  }
