// JavaScript code for the VLiveScore page.
//
// Author:  OrdinaSoft
//          Patrick Lanz
//          Lausanne
//          www.ordinasoft.ch
//
// First version: November 2, 2006


var
  ScoreData = null;  // contains the current data for the score


// Returns an empty TeamData.
//
function EmptyTeamData () {

  var
    TeamData = new Object;

  TeamData.Code = '';
  TeamData.Serve = false;
  TeamData.Score = null;
  TeamData.SetScore = [null, null, null, null, null];
  TeamData.Points = 0;
  TeamData.OppError = 0;
  TeamData.Players = new Object;
  TeamData.PlayersByShirt = new Object;
  return TeamData;
}



// Initialization code for the ScoreData.
// Defines default data, so the management code will never generate an error.
//  - TournCode is the tournament code.
//  - NoMatch is the match number.
//  - Period is the refresh period, in seconds.
//
function InitScoreData (TournCode, NoMatch, Period) {
  ScoreData = new Object;
  ScoreData.TournCode = TournCode;
  ScoreData.NoMatch = NoMatch;
  ScoreData.Status = 0;
  ScoreData.OpenStats = 0;
  ScoreData.XmlType = 'Score';  // type of XML data to retrieve
  ScoreData.Length = [0, 0, 0, 0, 0];
  ScoreData.TeamA = EmptyTeamData ();
  ScoreData.TeamB = EmptyTeamData ();
  ScoreData.Period = 1000 * Period;
  ScoreData.Version = -1;
  ScoreData.No = new Date ().valueOf ();
  return true;
}



// Show the element with the specified name on the display and also hides the "loading" element.
//
function ShowElement (Name) {

  var
    LoadingElmt = document.getElementById ('div_Loading');

  if (LoadingElmt)
    LoadingElmt.style.display = 'none';
  document.getElementById (Name).style.visibility = 'visible';
  return true;
}



// Retrieving an XML attribute containing an integer, with error management.
//  - Elmt is the XML element.
//  - Name is the attribute name.
//
function GetXmlIntAttr (Elmt, Name) {
  Elmt = Elmt.attributes;
  if (Elmt == null)
    return 0;
  Elmt = Elmt.getNamedItem (Name);
  return (Elmt == null) ? 0 : parseInt (Elmt.value, 10)
}



// Retrieving the information about the teams.
//  - Data is the XML data.
//
function GetMatchData (Data) {

  var
    Elmt,
    Value;

  Value = GetXmlIntAttr (Data, 'Version');
  if (Value != 0)
    ScoreData.Version = Value;

  Elmt = Data.getElementsByTagName ('Status');
  if (Elmt.length != 0)
    ScoreData.Status = parseInt (Elmt [0].firstChild.nodeValue, 10);

  Data = Data.getElementsByTagName ('Length');
  if (Data.length != 0) {
    Data = Data [0];
    ScoreData.Length = [0, 0, 0, 0, 0];
    for (var i = 0; i < 5; i++) {
      Value = GetXmlIntAttr (Data, 'Set' + (i + 1));
      if (Value != 0)
        ScoreData.Length [i] = Value;
    }
  }
  return true;
}



// Retrieving the statistical data for a team.
//  - Data is the XML data for the team.
//  - TeamCode is 'A' or 'B' depending of the team.
//
function GetStatsData (Data, TeamCode) {

  var
    Elmt,     // an element in the XML data
    Elmt2,    // a second element in the XML data
    Elmt3,    // a third element in the XML data
    NoSet,    // number of the set
    NoShirt,  // shirt number for a player
    Player,   // data for a player
    Team = (TeamCode == 'A') ? ScoreData.TeamA : Team = ScoreData.TeamB;

  Team.OppError = 0;
  for (var i = 0; i < Team.NbPlayers; i++) {
    Player = Team.Players [i];
    Player.HasStats = 1;
    Player.Atk = 0;
    Player.Blo = 0;
    Player.Srv = 0;
    Player.SetStatus = ['', '', '', '', ''];
  }

  Elmt = Data.firstChild;
  while (Elmt != null) {
    if (Elmt.nodeName == 'Set') {
      NoSet = GetXmlIntAttr (Elmt, 'No');
      Elmt2 = Elmt.firstChild;
      while (Elmt2 != null) {
        switch (Elmt2.nodeName) {

          case 'Roster'  :
            for (var i = 1; i <= 6; i++) {
              Player = Team.PlayersByShirt [GetXmlIntAttr (Elmt2, 'p' + i.toString ())];
              if (Player != null)
                Player.SetStatus [NoSet - 1] = '\u25A0';
            }
            for (var i = 1; i <= 6; i++) {
              Player = Team.PlayersByShirt [GetXmlIntAttr (Elmt2, 'r' + i.toString ())];
              if (Player != null)
                Player.SetStatus [NoSet - 1] = '\u25A1';
            }
            for (var i = 1; i <= 2; i++) {
              Player = Team.PlayersByShirt [GetXmlIntAttr (Elmt2, 'l' + i.toString ())];
              if (Player != null)
                Player.SetStatus [NoSet - 1] = 'L';
            }
            break;

          case 'Statistics'  :
            Elmt3 = Elmt2.firstChild;
            while (Elmt3 != null) {
              switch (Elmt3.nodeName) {
                case 'Team'  :
                  Team.OppError += GetXmlIntAttr (Elmt3, 'OppError');
                  break;
                case 'Player'  :
                  Player = Team.PlayersByShirt [GetXmlIntAttr (Elmt3, 'NoShirt')];
                  if (Player != null) {
                    Player.Atk += GetXmlIntAttr (Elmt3, 'AtkPoint');
                    Player.Blo += GetXmlIntAttr (Elmt3, 'BlkPoint');
                    Player.Srv += GetXmlIntAttr (Elmt3, 'SrvPoint');
                  }
                  break;
              }
              Elmt3 = Elmt3.nextSibling;
            }
            break;
        }
        Elmt2 = Elmt2.nextSibling;
      }
    }
    Elmt = Elmt.nextSibling;
  }

  return true;
}



// Retrieving the information about the teams.
//  - Data is the XML data.
//  - TeamCode is 'A' or 'B' depending of the team.
//
function GetTeamData (Data, TeamCode) {
  Data = Data.getElementsByTagName ('Team' + TeamCode);
  if (Data.length != 0) {
    Data = Data [0];

    var
      Elmt,   // an element in the XML data
      Elmt2,  // a second element in the XML data
      Pts,    // number of points in a set
      Team = (TeamCode == 'A') ? ScoreData.TeamA : Team = ScoreData.TeamB;

    Team.Code = Data.attributes.getNamedItem ('Code').value;
    Team.Serve = Data.attributes.getNamedItem ('Serve') != null;
    Team.SetScore = [null, null, null, null, null];
    Team.Points = 0;

    Elmt = Data.firstChild;
    while (Elmt != null) {
      switch (Elmt.nodeName) {

        case 'Score'  :
          Team.Score = parseInt (Elmt.firstChild.nodeValue, 10);
          break;

        case 'Set'  :
          Elmt2 = Elmt.getElementsByTagName ('Score');
          if (Elmt2.length != 0) {
            Pts = parseInt (Elmt2 [0].firstChild.nodeValue, 10);
            Team.SetScore [GetXmlIntAttr (Elmt, 'No') - 1] = Pts;
            Team.Points += Pts;
          }
          break;

        case 'Captain'  :
          Team.Captain = parseInt (Elmt.firstChild.nodeValue, 10);
          break;
      }
      Elmt = Elmt.nextSibling;
    }
    if (Team.Points == 0)
      Team.Points = null;
    if (ScoreData.OpenStats & ((TeamCode == 'A') ? 1 : 2))
      GetStatsData (Data, TeamCode);
  }
  return true;
}



// Correct the score, so that '0' are displayed instead of empty score, where appropriate.
//
function CorrectScore () {
  if (ScoreData.Status != 0) {  // match started

    var
      TeamA = ScoreData.TeamA,
      TeamB = ScoreData.TeamB;

    if (TeamA.Score == null)
      TeamA.Score = 0;
    if (TeamB.Score == null)
      TeamB.Score = 0;

    for (var i = 0; i < 5; i++)
      if ((TeamA.SetScore [i] != null) || (TeamB.SetScore [i] != null)) {  // set started
        if (TeamA.SetScore [i] == null)
          TeamA.SetScore [i] = 0;
        if (TeamB.SetScore [i] == null)
          TeamB.SetScore [i] = 0;
      }
  }
  return true;
}



// Updating an image. Makes something only if the image is changes.
// - id is the identifier of the image tag.
// - Source is the URL for the source of the image.
// - Alt is the alternate text for the image
//
function UpdateImage (id, Source, Alt) {
  id = document.getElementById (id);
  if (id.src != Source) {
    id.src = Source;
    id.alt = Alt;
  }
  return true;
}



// Formatting the specified time, for display.
//
function FormatTime (Time) {

  var
    s;

  if (Time == 0)
    return '-';
  s = (Math.floor (Time / 60)).toString () + ':';
  Time = Time % 60;
  if (Time < 10)
    s += '0';
  return s + Time.toString ();
}



// Displaying the status of the match.
//
function MatchStatus () {

  var
    s = '';

  switch (ScoreData.Status) {
    case 0  :
      s = 'Match not started.';
      break;
    case 1  :
      s = 'Match in progress.';
      break;
    case 2  :
      s = 'Match finished.';
      break;
  }
  document.getElementById ('MatchStatus').innerHTML = s;
  return true;
}



// Displaying the length of the sets.
//
function MatchSetLength () {

  var
    Total = 0;

  for (var i = 0; i < 5; i++) {
    document.getElementById ('TimeSet' + (i + 1).toString ()).innerHTML =
      FormatTime (ScoreData.Length [i]);
    Total += ScoreData.Length [i];
  }
  document.getElementById ('TotalTime').innerHTML = FormatTime (Total);
  return true;
}



// Setting a digit display.
//  - id is the identifier of the image with the digit.
//  - Value is the value of the digit.
//
function SetDigit (id, Value) {

  var
    s;

  if (Value == null)
    Value = ' ';
  if (typeof Value == 'number')
    s = Value.toString ();
  else if (Value == '')
    s = ' ';
  else s = Value;
  if (s == ' ')
    s = 'SP';
  UpdateImage (id, 'Images/ScoreBoard' + s + '.gif', Value.toString ());
  return true;
}



// Setting a score display.
//  - id is the beginning of the identifier.
//  - Score is the score.
//  - Digits is the number of digits.
//
function SetScore (id, Score, Digits) {
  if (Score == null)
    Score = '';
  else if (typeof Score == 'number')
    Score = Score.toString ();
  while (Score.length < Digits)
    Score = ' ' + Score;
  for (var i = 1; i <= Digits; i++)
    SetDigit (id + i.toString (), Score.charAt (i - 1));
  return true;
}


// Updating statistical data for a team.
//  - TeamCode is 'A' or 'B' depending on the team.
//
function UpdateTeamStats (TeamCode) {

  var
    Line,
    OldHeight    = document.getElementById ('Stats' + TeamCode).offsetHeight,
    Player,
    s,
    Team         = (TeamCode == 'A') ? ScoreData.TeamA : ScoreData.TeamB,
    TotalAtk     = 0,
    TotalBlo     = 0,
    TotalSrv     = 0,
    TotalPlayer,
    Total        = 0;

  document.getElementById ('Stats' + TeamCode + 'TC11').innerHTML =
    (Team.OppError == 0) ? '-' : Team.OppError.toString ();
  Total += Team.OppError;

  for (var i = 0; i < Team.NbPlayers; i++) {
    Player = Team.Players [i];
    Line = 'Stats' + TeamCode + 'L' + i.toString ();
    document.getElementById (Line + 'C0').innerHTML = Player.NoShirt.toString ();
    s = (Player.NoShirt == Team.Captain) ? 'C' : '';
    s = (Player.NoShirt == Team.Libero)  ? s + 'L' : s;
    document.getElementById (Line + 'C1').innerHTML = s;
    document.getElementById (Line + 'C2').innerHTML = Player.LastName + ' ' + Player.FirstName;
    if (Player.HasStats != null) {
      TotalAtk += Player.Atk;
      TotalBlo += Player.Blo;
      TotalSrv += Player.Srv;
      document.getElementById (Line + 'C3').innerHTML = Player.SetStatus [0];
      document.getElementById (Line + 'C4').innerHTML = Player.SetStatus [1];
      document.getElementById (Line + 'C5').innerHTML = Player.SetStatus [2];
      document.getElementById (Line + 'C6').innerHTML = Player.SetStatus [3];
      document.getElementById (Line + 'C7').innerHTML = Player.SetStatus [4];
      document.getElementById (Line + 'C8').innerHTML =
        (Player.Atk == 0) ? '-' : Player.Atk.toString ();
      document.getElementById (Line + 'C9').innerHTML =
        (Player.Blo == 0) ? '-' : Player.Blo.toString ();
      document.getElementById (Line + 'C10').innerHTML =
        (Player.Srv == 0) ? '-' : Player.Srv.toString ();
      TotalPlayer = Player.Atk + Player.Blo + Player.Srv;
      Total += TotalPlayer;
      document.getElementById (Line + 'C11').innerHTML =
        (TotalPlayer == 0) ? '-' : TotalPlayer.toString ();
    }
  }

  document.getElementById ('Stats' + TeamCode + 'TTLC8').innerHTML =
    (TotalAtk == 0) ? '-' : TotalAtk.toString ();
  document.getElementById ('Stats' + TeamCode + 'TTLC9').innerHTML =
    (TotalBlo == 0) ? '-' : TotalBlo.toString ();
  document.getElementById ('Stats' + TeamCode + 'TTLC10').innerHTML =
    (TotalSrv == 0) ? '-' : TotalSrv.toString ();
  document.getElementById ('Stats' + TeamCode + 'TTLC11').innerHTML =
    (Total == 0) ? '-' : Total.toString ();

  window.resizeBy (0, document.getElementById ('Stats' + TeamCode).offsetHeight - OldHeight);
  return true;
}



// Updating team data.
//  - TeamCode is 'A' or 'B' depending on the team.
//
function UpdateTeam (TeamCode) {

  var
    OldHeight  = document.getElementById ('Stats' + TeamCode).offsetHeight,
    Team       = (TeamCode == 'A') ? ScoreData.TeamA : Team = ScoreData.TeamB;

  UpdateImage ('Flag' + TeamCode, '/Images/Flags/' + Team.Code + '2.gif',
               '[flag for ' + Team.Code + ']');

  document.getElementById ('TeamCode' + TeamCode).innerHTML = Team.Code;

  if (ScoreData.Status == 0) { // match not started
    UpdateImage ('Serve' + TeamCode, 'Images/Spacer.gif', '');
    SetDigit ('TeamSets' + TeamCode, null);
    SetScore ('TeamSet1' + TeamCode, null, 2);
    SetScore ('TeamSet2' + TeamCode, null, 2);
    SetScore ('TeamSet3' + TeamCode, null, 2);
    SetScore ('TeamSet4' + TeamCode, null, 2);
    SetScore ('TeamSet5' + TeamCode, null, 2);
    SetScore ('TeamPoints' + TeamCode, null, 3);
  }

  else {
    UpdateImage ('Serve' + TeamCode, (Team.Serve == 0) ?
                   'Images/Spacer.gif' : 'Images/ScoreBall.gif', '');
    SetDigit ('TeamSets' + TeamCode, Team.Score);
    SetScore ('TeamSet1' + TeamCode, Team.SetScore [0], 2);
    SetScore ('TeamSet2' + TeamCode, Team.SetScore [1], 2);
    SetScore ('TeamSet3' + TeamCode, Team.SetScore [2], 2);
    SetScore ('TeamSet4' + TeamCode, Team.SetScore [3], 2);
    SetScore ('TeamSet5' + TeamCode, Team.SetScore [4], 2);
    SetScore ('TeamPoints' + TeamCode, Team.Points, 3);
  }

  if (ScoreData.OpenStats & ((TeamCode == 'A') ? 1 : 2))
    UpdateTeamStats (TeamCode);
  window.resizeBy (0, document.getElementById ('Stats' + TeamCode).offsetHeight - OldHeight);
  return true;
}



// Title of the window: we display the teams and the current score.
//
function SetTitle () {

  var
    TeamA = ScoreData.TeamA,
    TeamB = ScoreData.TeamB,
    s     = TeamA.Code + '-' + TeamB.Code;

  if (ScoreData.Status != 0) {
    s += ' ' + TeamA.Score.toString () + '-' + TeamB.Score.toString ();
    var HasSetScore = false;
    for (var i = 0; i < 5; i++)
      if ((TeamA.SetScore [i] != null) && (TeamB.SetScore [i] != null)) {
        if (HasSetScore)
          s += ', ';
        else {
          s += ' (';
          HasSetScore = true;
        }
        s += TeamA.SetScore [i].toString () + '-' +
             TeamB.SetScore [i].toString ();
      }
    if (HasSetScore)
      s += ')';
  }
  document.title = s;
  return true;
}



// Creates an empty statistics line.
// - TeamCode is 'A' or 'B', depending on the team.
// - LineId is the identifier of the line.
// - AddlStyle is an eventual additional style for each cell
//
function EmptyStatsLine (TeamCode, LineId, AddlStyle) {

  var
    Line = 'Stats' + TeamCode + LineId;

  if (AddlStyle == null)
    AddlStyle = '';
  else AddlStyle = ' ' + AddlStyle;
  return '  <tr class="StatsData">\n' +
         '    <td id="' + Line + 'C0" align="right"' + AddlStyle + '>&nbsp;</td>\n' +
         '    <td id="' + Line + 'C1" align="center"' + AddlStyle + '>&nbsp;</td>\n' +
         '    <td id="' + Line + 'C2"' + AddlStyle + '>&nbsp;</td>\n' +
         '    <td id="' + Line + 'C3" align="center"' + AddlStyle + '>&nbsp;</td>\n' +
         '    <td id="' + Line + 'C4" align="center"' + AddlStyle + '>&nbsp;</td>\n' +
         '    <td id="' + Line + 'C5" align="center"' + AddlStyle + '>&nbsp;</td>\n' +
         '    <td id="' + Line + 'C6" align="center"' + AddlStyle + '>&nbsp;</td>\n' +
         '    <td id="' + Line + 'C7" align="center"' + AddlStyle + '>&nbsp;</td>\n' +
         '    <td' + AddlStyle + '>&nbsp;</td>\n' +
         '    <td id="' + Line + 'C8" align="center"' + AddlStyle + '>&nbsp;</td>\n' +
         '    <td id="' + Line + 'C9" align="center"' + AddlStyle + '>&nbsp;</td>\n' +
         '    <td id="' + Line + 'C10" align="center"' + AddlStyle + '>&nbsp;</td>\n' +
         '    <td id="' + Line + 'C11" align="center"' + AddlStyle + '>&nbsp;</td>\n' +
         '  </tr>\n';
}



// Creates a division to display the statistics.
// - TeamCode is 'A' or 'B', depending on the team.
//
function OpenStatDiv (TeamCode) {

  var
    Line,
    OldHeight  = document.getElementById ('Stats' + TeamCode).offsetHeight,
    s          =  '',
    Team       = (TeamCode == 'A') ? ScoreData.TeamA : ScoreData.TeamB;

  s += '<table border="0" cellpadding="2" cellspacing="0" ' +
              'style="border: 1px solid #000000">\n' +
       '  <tr class="StatsHeader">\n' +
       '    <td width="20"><img src="Images/Close.gif" alt="Close" style="cursor: pointer" ' +
              'onclick="ClosedStatDiv (\'' + TeamCode + '\');"/></td>\n' +
       '    <td width="15"></td>\n' +
       '    <td width="150">' + Team.Code + '</td>\n' +
       '    <td width="15" align="center">1</td>\n' +
       '    <td width="15" align="center">2</td>\n' +
       '    <td width="15" align="center">3</td>\n' +
       '    <td width="15" align="center">4</td>\n' +
       '    <td width="15" align="center">5</td>\n' +
       '    <td width="5"></td>\n' +
       '    <td width="35" align="center">ATK</td>\n' +
       '    <td width="35" align="center">BLO</td>\n' +
       '    <td width="35" align="center">SRV</td>\n' +
       '    <td width="45" align="center">Total</td>\n' +
       '  </tr>\n';

  for (var i = 0; i < Team.NbPlayers; i++)
    s += EmptyStatsLine (TeamCode, 'L' + i.toString ());
  s += EmptyStatsLine (TeamCode, 'T') +
       EmptyStatsLine (TeamCode, 'TTL', 'style="border-top: 1px solid #000000"');

  s += '</table>\n' +
       '<table border="0" cellpadding="2" cellspacing="0">\n' +
       '  <tr class="Body">\n' +
       '    <td><span style="font-size: 2px">&nbsp;</span></td>\n' +
       '  </tr>\n' +
       '  <tr class="Body">\n';

  document.getElementById ('Stats' + TeamCode).innerHTML = s;
  document.getElementById ('Stats' + TeamCode + 'TC2').innerHTML = 'Opponent errors';
  document.getElementById ('Stats' + TeamCode + 'TTLC2').innerHTML = 'Totals';
  ScoreData.OpenStats = ScoreData.OpenStats | ((TeamCode == 'A') ? 1 : 2);
  ScoreData.XmlType = 'Stats';
  ScoreData.Version = -1;
  UpdateTeamStats (TeamCode);
  if (ScoreData.Timer != null)
    clearTimeout (ScoreData.Timer);
  ScoreData.Timer = setTimeout ('UpdateLoop ()', 1);
  window.resizeBy (0, document.getElementById ('Stats' + TeamCode).offsetHeight - OldHeight);
  return true;
}



// Creates a division to open when we have the fixed scores.
// - TeamCode is 'A' or 'B', depending on the team.
//
function ClosedStatDiv (TeamCode) {

  var
    OldHeight  = document.getElementById ('Stats' + TeamCode).offsetHeight,
    s          =  '',
    Team       = (TeamCode == 'A') ? ScoreData.TeamA : Team = ScoreData.TeamB;

  s += '<table border="0" cellpadding="2" cellspacing="0" class="StatsHeader">\n' +
       '  <tr style="cursor: pointer" onclick="OpenStatDiv (\'' + TeamCode + '\');">\n' +
       '    <td><img src="Images/Open.gif" alt="Open" /></td>\n' +
       '    <td>&nbsp;Show statistics for ' + Team.Code + '&nbsp;</td>\n' +
       '  </tr>\n' +
       '  <tr class="Body">\n' +
       '    <td width="464" colspan="2"><span style="font-size: 2px">&nbsp;</span></td>\n' +
       '  </tr>\n' +
       '</table>\n';

  document.getElementById ('Stats' + TeamCode).innerHTML = s;
  if (ScoreData.OpenStats == 0)
    ScoreData.XmlType = 'Score';
  window.resizeBy (0, document.getElementById ('Stats' + TeamCode).offsetHeight - OldHeight);
  return true;
}



// Returns the data for a player, from its FIVB number. If the player's data is not found, it
// will be created.
//
function GetPlayer (NoFivb) {
  Player = ScoreData.Players [NoFivb];
  if (Player == null) {
    Player = new Object;
    Player.NoFivb = NoFivb;
    ScoreData.Players [NoFivb] = Player;
  }
  return Player;
}



// Management of the result of the Ajax call to the server, for fixed data.
//  - Data is the response data.
//
function ManageFixedData (Data) {

  Data = Data.getElementsByTagName ('VolleyMatch');
  if (Data.length != 1)
    return false;
  Data = Data [0];

  var
    Elmt = Data.firstChild,
    Elmt2,
    Player,
    Team;

  ScoreData.Players = new Object;

  while (Elmt != null) {
    switch (Elmt.nodeName) {

      case 'Player'  :
        Player = GetPlayer (GetXmlIntAttr (Elmt, 'NoFivb'));
        Elmt2 = Elmt.getElementsByTagName ('FirstName');
        if (Elmt2.length != 0)
          Player.FirstName = Elmt2 [0].firstChild.nodeValue;
        Elmt2 = Elmt.getElementsByTagName ('LastName');
        if (Elmt2.length != 0)
          Player.LastName = Elmt2 [0].firstChild.nodeValue;
        break;

      case 'Team'  :
        Team = (Elmt.attributes.getNamedItem ('Code').value == ScoreData.TeamA.Code) ?
               ScoreData.TeamA : ScoreData.TeamB;
        var ix = 0;
        Elmt2 = Elmt.firstChild;
        while (Elmt2 != null) {
          if (Elmt2.nodeName == 'Player') {
            Player = GetPlayer (GetXmlIntAttr (Elmt2, 'NoFivb'));
            Player.NoShirt = GetXmlIntAttr (Elmt2, 'NoShirt');
            Team.Players [ix++] = Player;
            Team.PlayersByShirt [Player.NoShirt] = Player;
          }
          Elmt2 = Elmt2.nextSibling;
        }
        Team.NbPlayers = ix;
        break;
    }
    Elmt = Elmt.nextSibling;
  }
  ClosedStatDiv ('A');
  ClosedStatDiv ('B');
  return true;
}



// Management of the result of the Ajax call to the server, for score data.
//  - Data is the response data.
//
function ManageResult (Data) {
  document.getElementById ('div_NoAjax').style.display = 'none';
  Data = Data.getElementsByTagName ('Match');

  // Check for errors
  if (Data.length != 1) {
    if (ScoreData.Version == -1)
      ShowElement ('div_NoInfo');
    return true;
  }
  document.getElementById ('div_NoInfo').style.display = 'none';
  Data = Data [0];

  // Read the received data
  GetMatchData (Data);
  GetTeamData (Data, 'A');
  GetTeamData (Data, 'B');
  CorrectScore ();

  // Update the data
  MatchStatus ();
  UpdateTeam ('A');
  UpdateTeam ('B');
  MatchSetLength ();
  SetTitle ();
  document.getElementById ('LastUpdate').innerHTML = new Date ().toLocaleString ();
  ShowElement ('div_Score');

  return true;
}



// Update loop: looks regularly for new information and updates the display.
//
function UpdateLoop () {

  var
    Requester = GetXmlRequester ();

  if (Requester == null) {
    ShowElement ('div_NoAjax');
    return false;
  }

  try {
    Requester.open ('GET',
                    '/visweb6/xml_vlivescore.aspx' +
                      '?TournCode=' + ScoreData.TournCode +
                      '&Type=' + ScoreData.XmlType +
                      '&NoMatch=' + ScoreData.NoMatch.toString () +
                      '&Version=' + ScoreData.Version.toString () +
                      '&No=' + (ScoreData.No++).toString ());
    Requester.onreadystatechange =

      function () {
        if (Requester.readyState == 4) {
          try {
            ScoreData.Timer = null;
            var
              OldStatus = ScoreData.Status;
            if ((Requester.status == 200) || (Requester.status == 304))
              if (ScoreData.XmlType == 'Fixed') {
                ManageFixedData (Requester.responseXML);
                ScoreData.XmlType = (ScoreData.OpenStats == 0) ? 'Score' : 'Stats';
              }
              else ManageResult (Requester.responseXML);
          }
          finally {
            if ((OldStatus == 0) && (ScoreData.Status != 0)) {
              ScoreData.XmlType = 'Fixed';
              ScoreData.Timer = setTimeout ('UpdateLoop ()', 1);
            }
            else ScoreData.Timer = setTimeout ('UpdateLoop ()', ScoreData.Period);
          }
          return true;
        }
      }

    Requester.send (null);
  }
  catch (e) {
    ScoreData.Timer = setTimeout ('UpdateLoop ()', ScoreData.Period);
  }
  return true;
}



// Starting the update loop. Can be made only when the page is fully loaded.
//
function StartUpdateLoop () {
  if (typeof AddLoadEvent == 'undefined') {
    setTimeout ('StartUpdateLoop ();', 100);
    return false;
  }
  AddLoadEvent (UpdateLoop);
  return true;
}



// Starting all the things: initialize ScoreData and starts the update lood.
//  - TournCode is the tournament code.
//  - NoMatch is the match number.
//  - Period is the refresh period, in seconds.
//
function StartLiveScore (TournCode, NoMatch, Period) {
  InitScoreData (TournCode, NoMatch, Period);
  StartUpdateLoop ();
  return true;
}
