/**
  * Sets up controls for pages 2/3 of the wizard
  * @param Match $match
  * @param Team $batting_team
  * @param Collection $batting_data
  * @param Team $bowling_team
  * @param Collection $bowling_data
  * @param int $total
  * @param int $wickets_taken
  * @return void
  */
 private function CreateScorecardControls(Match $match, Team $batting_team, Collection $batting_data, Team $bowling_team, Collection $bowling_data, $total, $wickets_taken)
 {
     require_once "xhtml/tables/xhtml-table.class.php";
     $batting_table = new XhtmlTable();
     $batting_table->SetCaption($batting_team->GetName() . "'s batting");
     $batting_table->SetCssClass("scorecard scorecardEditor batting");
     $out_by_header = new XhtmlCell(true, '<span class="small">Fielder</span><span class="large">Caught<span class="wrapping-hair-space"> </span>/<span class="wrapping-hair-space"> </span><span class="nowrap">run-out by</span></span>');
     $out_by_header->SetCssClass("dismissedBy");
     $bowler_header = new XhtmlCell(true, "Bowler");
     $bowler_header->SetCssClass("bowler");
     $score_header = new XhtmlCell(true, "Runs");
     $score_header->SetCssClass("numeric");
     $balls_header = new XhtmlCell(true, "Balls");
     $balls_header->SetCssClass("numeric");
     $batting_headings = new XhtmlRow(array("Batsman", "How out", $out_by_header, $bowler_header, $score_header, $balls_header));
     $batting_headings->SetIsHeader(true);
     $batting_table->AddRow($batting_headings);
     $batting_data->ResetCounter();
     $byes = null;
     $wides = null;
     $no_balls = null;
     $bonus = null;
     # Loop = max players + 4, because if you have a full scorecard you have to keep looping to get the 4 extras players
     for ($i = 1; $i <= $match->GetMaximumPlayersPerTeam() + 4; $i++) {
         $batting = $batting_data->MoveNext() ? $batting_data->GetItem() : null;
         /* @var $batting Batting */
         # Grab the scores for extras players to use later
         if (!is_null($batting)) {
             switch ($batting->GetPlayer()->GetPlayerRole()) {
                 case Player::BYES:
                     $byes = $batting->GetRuns();
                     break;
                 case Player::WIDES:
                     $wides = $batting->GetRuns();
                     break;
                 case Player::NO_BALLS:
                     $no_balls = $batting->GetRuns();
                     break;
                 case Player::BONUS_RUNS:
                     $bonus = $batting->GetRuns();
                     break;
             }
         }
         # Don't write a table row for the last four loops, we'll do that next because they're different
         if ($i <= $match->GetMaximumPlayersPerTeam()) {
             $player = new TextBox("batName{$i}", (is_null($batting) or !$batting->GetPlayer()->GetPlayerRole() == Player::PLAYER) ? "" : $batting->GetPlayer()->GetName(), $this->IsValidSubmit());
             $player->SetMaxLength(100);
             $player->AddAttribute("autocomplete", "off");
             $player->AddCssClass("player batsman team" . $batting_team->GetId());
             $how = new XhtmlSelect("batHowOut{$i}", null, $this->IsValidSubmit());
             $how->SetCssClass("howOut");
             $how->AddOptions(array(Batting::DID_NOT_BAT => Batting::Text(Batting::DID_NOT_BAT), Batting::NOT_OUT => Batting::Text(Batting::NOT_OUT), Batting::CAUGHT => Batting::Text(Batting::CAUGHT), Batting::BOWLED => Batting::Text(Batting::BOWLED), Batting::CAUGHT_AND_BOWLED => str_replace(" and ", "/", Batting::Text(Batting::CAUGHT_AND_BOWLED)), Batting::RUN_OUT => Batting::Text(Batting::RUN_OUT), Batting::BODY_BEFORE_WICKET => "bbw", Batting::HIT_BALL_TWICE => Batting::Text(Batting::HIT_BALL_TWICE), Batting::TIMED_OUT => Batting::Text(Batting::TIMED_OUT), Batting::RETIRED_HURT => Batting::Text(Batting::RETIRED_HURT), Batting::RETIRED => Batting::Text(Batting::RETIRED), Batting::UNKNOWN_DISMISSAL => Batting::Text(Batting::UNKNOWN_DISMISSAL)), null);
             if (!is_null($batting) and $batting->GetPlayer()->GetPlayerRole() == Player::PLAYER and $this->IsValidSubmit()) {
                 $how->SelectOption($batting->GetHowOut());
             }
             $out_by = new TextBox("batOutBy{$i}", (is_null($batting) or is_null($batting->GetDismissedBy()) or !$batting->GetDismissedBy()->GetPlayerRole() == Player::PLAYER) ? "" : $batting->GetDismissedBy()->GetName(), $this->IsValidSubmit());
             $out_by->SetMaxLength(100);
             $out_by->AddAttribute("autocomplete", "off");
             $out_by->AddCssClass("player team" . $bowling_team->GetId());
             $bowled_by = new TextBox("batBowledBy{$i}", (is_null($batting) or is_null($batting->GetBowler()) or !$batting->GetBowler()->GetPlayerRole() == Player::PLAYER) ? "" : $batting->GetBowler()->GetName(), $this->IsValidSubmit());
             $bowled_by->SetMaxLength(100);
             $bowled_by->AddAttribute("autocomplete", "off");
             $bowled_by->AddCssClass("player team" . $bowling_team->GetId());
             $runs = new TextBox("batRuns{$i}", (is_null($batting) or $batting->GetPlayer()->GetPlayerRole() != Player::PLAYER) ? "" : $batting->GetRuns(), $this->IsValidSubmit());
             $runs->SetCssClass("numeric runs");
             $runs->AddAttribute("type", "number");
             $runs->AddAttribute("min", "0");
             $runs->AddAttribute("autocomplete", "off");
             $balls = new TextBox("batBalls{$i}", (is_null($batting) or $batting->GetPlayer()->GetPlayerRole() != Player::PLAYER) ? "" : $batting->GetBallsFaced(), $this->IsValidSubmit());
             $balls->SetCssClass("numeric balls");
             $balls->AddAttribute("type", "number");
             $balls->AddAttribute("min", "0");
             $balls->AddAttribute("autocomplete", "off");
             $batting_row = new XhtmlRow(array($player, $how, $out_by, $bowled_by, $runs, $balls));
             $batting_row->GetFirstCell()->SetCssClass("batsman");
             $batting_table->AddRow($batting_row);
         }
     }
     $batting_table->AddRow($this->CreateExtrasRow("batByes", "Byes", "extras", "numeric runs", $byes));
     $batting_table->AddRow($this->CreateExtrasRow("batWides", "Wides", "extras", "numeric runs", $wides));
     $batting_table->AddRow($this->CreateExtrasRow("batNoBalls", "No balls", "extras", "numeric runs", $no_balls));
     $batting_table->AddRow($this->CreateExtrasRow("batBonus", "Bonus or penalty runs", "extras", "numeric runs", $bonus));
     $batting_table->AddRow($this->CreateExtrasRow("batTotal", "Total", "totals", "numeric", $total));
     $batting_table->AddRow($this->CreateWicketsRow($match, $wickets_taken));
     $this->AddControl($batting_table);
     $total_batsmen = new TextBox("batRows", $match->GetMaximumPlayersPerTeam(), $this->IsValidSubmit());
     $total_batsmen->SetMode(TextBoxMode::Hidden());
     $this->AddControl($total_batsmen);
     $bowling_table = new XhtmlTable();
     $bowling_table->SetCaption($bowling_team->GetName() . "'s bowling, over-by-over");
     $bowling_table->SetCssClass("scorecard scorecardEditor bowling-scorecard bowling");
     $over_header = new XhtmlCell(true, 'Balls bowled <span class="qualifier">(excluding extras)</span>');
     $over_header->SetCssClass("numeric balls");
     $wides_header = new XhtmlCell(true, "Wides");
     $wides_header->SetCssClass("numeric");
     $no_balls_header = new XhtmlCell(true, "No balls");
     $no_balls_header->SetCssClass("numeric");
     $runs_header = new XhtmlCell(true, "Over total");
     $runs_header->SetCssClass("numeric");
     $bowling_headings = new XhtmlRow(array("Bowler", $over_header, $wides_header, $no_balls_header, $runs_header));
     $bowling_headings->SetIsHeader(true);
     $bowling_table->AddRow($bowling_headings);
     $bowling_data->ResetCounter();
     for ($i = 1; $i <= $match->GetOvers(); $i++) {
         $bowling = $bowling_data->MoveNext() ? $bowling_data->GetItem() : null;
         /* @var $bowling Over */
         $blank_row = (is_null($bowling) or is_null($bowling->GetOverNumber()));
         // don't list records generated from batting card to record wickets taken
         $player = new TextBox("bowlerName{$i}", $blank_row ? "" : $bowling->GetPlayer()->GetName(), $this->IsValidSubmit());
         $player->SetMaxLength(100);
         $player->AddAttribute("autocomplete", "off");
         $player->AddCssClass("player team" . $bowling_team->GetId());
         $balls = new TextBox("bowlerBalls{$i}", $blank_row ? "" : $bowling->GetBalls(), $this->IsValidSubmit());
         $balls->AddAttribute("autocomplete", "off");
         $balls->AddAttribute("type", "number");
         $balls->AddAttribute("min", "0");
         $balls->AddAttribute("max", "10");
         $balls->SetCssClass("numeric balls");
         $wides = new TextBox("bowlerWides{$i}", $blank_row ? "" : $bowling->GetWides(), $this->IsValidSubmit());
         $wides->AddAttribute("autocomplete", "off");
         $wides->AddAttribute("type", "number");
         $wides->AddAttribute("min", "0");
         $wides->SetCssClass("numeric wides");
         $no_balls = new TextBox("bowlerNoBalls{$i}", $blank_row ? "" : $bowling->GetNoBalls(), $this->IsValidSubmit());
         $no_balls->AddAttribute("autocomplete", "off");
         $no_balls->AddAttribute("type", "number");
         $no_balls->AddAttribute("min", "0");
         $no_balls->SetCssClass("numeric no-balls");
         $runs = new TextBox("bowlerRuns{$i}", $blank_row ? "" : $bowling->GetRunsInOver(), $this->IsValidSubmit());
         $runs->AddAttribute("autocomplete", "off");
         $runs->AddAttribute("type", "number");
         $runs->AddAttribute("min", "0");
         $runs->SetCssClass("numeric runs");
         $bowling_row = new XhtmlRow(array($player, $balls, $wides, $no_balls, $runs));
         $bowling_row->GetFirstCell()->SetCssClass("bowler");
         $bowling_table->AddRow($bowling_row);
     }
     $this->AddControl($bowling_table);
     $total_overs = new TextBox("bowlerRows", $match->GetOvers(), $this->IsValidSubmit());
     $total_overs->SetMode(TextBoxMode::Hidden());
     $this->AddControl($total_overs);
     if ($match->GetLastAudit() != null) {
         require_once "data/audit-control.class.php";
         $this->AddControl(new AuditControl($match->GetLastAudit(), "match"));
     }
     $home_batted_first = "";
     if (!is_null($match->Result()->GetHomeBattedFirst())) {
         $home_batted_first = (int) $match->Result()->GetHomeBattedFirst();
     }
     $teams = new TextBox("teams", $home_batted_first . ScorecardEditControl::DATA_SEPARATOR . $match->GetHomeTeamId() . ScorecardEditControl::DATA_SEPARATOR . $match->GetHomeTeam()->GetName() . ScorecardEditControl::DATA_SEPARATOR . $match->GetAwayTeamId() . ScorecardEditControl::DATA_SEPARATOR . $match->GetAwayTeam()->GetName() . ScorecardEditControl::DATA_SEPARATOR . $match->GetTitle());
     $teams->SetMode(TextBoxMode::Hidden());
     $this->AddControl($teams);
 }
 /**
  * Sets up controls for page 4 of the wizard
  * @param Match $match
  * @return void
  */
 private function CreateHighlightsControls(Match $match)
 {
     $b_got_teams = !(is_null($match->GetHomeTeam()) || is_null($match->GetAwayTeam()));
     // Move CSS class to div element
     $match_outer_1 = new XhtmlElement('div');
     $match_outer_1->SetCssClass('matchResultEdit panel');
     $match_outer_2 = new XhtmlElement('div');
     $match_box = new XhtmlElement('div');
     $this->AddControl($match_outer_1);
     $match_outer_1->AddControl($match_outer_2);
     $match_outer_2->AddControl($match_box);
     $o_title_inner_1 = new XhtmlElement('span', "Match highlights");
     $o_title_inner_2 = new XhtmlElement('span', $o_title_inner_1);
     $o_title_inner_3 = new XhtmlElement('span', $o_title_inner_2);
     $o_heading = new XhtmlElement('h2', $o_title_inner_3);
     $match_box->AddControl($o_heading);
     # Who's playing?
     $o_home_name = new TextBox($this->GetNamingPrefix() . 'Home');
     $o_away_name = new TextBox($this->GetNamingPrefix() . 'Away');
     $o_home_name->SetMode(TextBoxMode::Hidden());
     $o_away_name->SetMode(TextBoxMode::Hidden());
     if (!is_null($match->GetHomeTeam())) {
         $o_home_name->SetText($match->GetHomeTeam()->GetId() . MatchHighlightsEditControl::DATA_SEPARATOR . $match->GetHomeTeam()->GetName());
     }
     if (!is_null($match->GetAwayTeam())) {
         $o_away_name->SetText($match->GetAwayTeam()->GetId() . MatchHighlightsEditControl::DATA_SEPARATOR . $match->GetAwayTeam()->GetName());
     }
     $this->AddControl($o_home_name);
     $this->AddControl($o_away_name);
     # When? (for validator message only)
     $when = new TextBox($this->GetNamingPrefix() . 'Date', $match->GetStartTime());
     $when->SetMode(TextBoxMode::Hidden());
     $this->AddControl($when);
     # Who won?
     $o_winner = new XhtmlSelect($this->GetNamingPrefix() . 'Result');
     $o_winner->AddControl(new XhtmlOption("Don't know", ''));
     $result_types = array(MatchResult::HOME_WIN, MatchResult::AWAY_WIN, MatchResult::TIE, MatchResult::ABANDONED);
     foreach ($result_types as $result_type) {
         if ($b_got_teams) {
             $o_winner->AddControl(new XhtmlOption($this->NameTeams(MatchResult::Text($result_type), $match->GetHomeTeam(), $match->GetAwayTeam()), $result_type));
         } else {
             $o_winner->AddControl(new XhtmlOption(MatchResult::Text($result_type), $result_type));
         }
     }
     if ($this->IsValidSubmit()) {
         if ($match->Result()->GetResultType() == MatchResult::UNKNOWN and !is_null($match->Result()->GetHomeRuns()) and !is_null($match->Result()->GetAwayRuns())) {
             # If match result is not known but we can guess from the entered scores, select it
             if ($match->Result()->GetHomeRuns() > $match->Result()->GetAwayRuns()) {
                 $o_winner->SelectOption(MatchResult::HOME_WIN);
             } else {
                 if ($match->Result()->GetHomeRuns() < $match->Result()->GetAwayRuns()) {
                     $o_winner->SelectOption(MatchResult::AWAY_WIN);
                 } else {
                     if ($match->Result()->GetHomeRuns() == $match->Result()->GetAwayRuns()) {
                         $o_winner->SelectOption(MatchResult::TIE);
                     }
                 }
             }
         } else {
             $o_winner->SelectOption($match->Result()->GetResultType());
         }
     }
     $o_win_part = new FormPart('Who won?', $o_winner);
     $match_box->AddControl($o_win_part);
     # Get current player of match
     $player = $match->Result()->GetPlayerOfTheMatch();
     $home_player = $match->Result()->GetPlayerOfTheMatchHome();
     $away_player = $match->Result()->GetPlayerOfTheMatchAway();
     $current_pom = MatchHighlightsEditControl::PLAYER_OF_THE_MATCH_NONE;
     if ($player instanceof Player) {
         $current_pom = MatchHighlightsEditControl::PLAYER_OF_THE_MATCH_OVERALL;
     } else {
         if ($home_player instanceof Player or $away_player instanceof Player) {
             $current_pom = MatchHighlightsEditControl::PLAYER_OF_THE_MATCH_HOME_AND_AWAY;
         }
     }
     # Choose from different types of player of the match
     require_once 'xhtml/forms/radio-button.class.php';
     $pom_container = new XhtmlElement('fieldset', new XhtmlElement('legend', 'Player of the match', 'formLabel'));
     $pom_container->SetCssClass('formPart');
     $pom_options = new XhtmlElement('div', null, 'formControl radioButtonList');
     $pom_options->SetXhtmlId($this->GetNamingPrefix() . "PlayerOptions");
     $pom_container->AddControl($pom_options);
     $match_box->AddControl($pom_container);
     $pom_options->AddControl(new RadioButton($this->GetNamingPrefix() . 'POM' . MatchHighlightsEditControl::PLAYER_OF_THE_MATCH_NONE, $this->GetNamingPrefix() . 'POM', "none chosen", MatchHighlightsEditControl::PLAYER_OF_THE_MATCH_NONE, $current_pom == MatchHighlightsEditControl::PLAYER_OF_THE_MATCH_NONE, $this->IsValidSubmit()));
     $pom_options->AddControl(new RadioButton($this->GetNamingPrefix() . 'POM' . MatchHighlightsEditControl::PLAYER_OF_THE_MATCH_OVERALL, $this->GetNamingPrefix() . 'POM', "yes, one chosen", MatchHighlightsEditControl::PLAYER_OF_THE_MATCH_OVERALL, $current_pom == MatchHighlightsEditControl::PLAYER_OF_THE_MATCH_OVERALL, $this->IsValidSubmit()));
     $pom_options->AddControl(new RadioButton($this->GetNamingPrefix() . 'POM' . MatchHighlightsEditControl::PLAYER_OF_THE_MATCH_HOME_AND_AWAY, $this->GetNamingPrefix() . 'POM', "yes, one from each team", MatchHighlightsEditControl::PLAYER_OF_THE_MATCH_HOME_AND_AWAY, $current_pom == MatchHighlightsEditControl::PLAYER_OF_THE_MATCH_HOME_AND_AWAY, $this->IsValidSubmit()));
     # Controls for entering a single player of the match
     $player_name = new TextBox($this->GetNamingPrefix() . 'Player', $player instanceof Player ? $player->GetName() : '', $this->IsValidSubmit());
     $player_name->SetMaxLength(100);
     $player_name->AddCssClass("player");
     $player_name->AddCssClass("team" . $match->GetHomeTeamId());
     $player_name->AddCssClass("team" . $match->GetAwayTeamId());
     $player_name->AddAttribute("autocomplete", "off");
     $player_box = new XhtmlElement("div", $player_name);
     $player_team = new XhtmlSelect($this->GetNamingPrefix() . "PlayerTeam", " playing for", $this->IsValidSubmit());
     $player_team->SetCssClass("playerTeam");
     # for JS
     $player_team->AddControl(new XhtmlOption("Don't know", ""));
     $player_team->AddControl(new XhtmlOption($match->GetHomeTeam()->GetName(), $match->GetHomeTeamId()));
     $player_team->AddControl(new XhtmlOption($match->GetAwayTeam()->GetName(), $match->GetAwayTeamId()));
     if ($player instanceof Player) {
         $player_team->SelectOption($player->Team()->GetId());
     }
     $player_box->AddControl($player_team);
     $player_part = new FormPart("Player's name", $player_box);
     $player_part->SetXhtmlId($this->GetNamingPrefix() . "OnePlayer");
     $player_part->GetLabel()->AddAttribute("for", $player_name->GetXhtmlId());
     $match_box->AddControl($player_part);
     # Controls for entering home and away players of the match
     $home_box = new TextBox($this->GetNamingPrefix() . 'PlayerHome', $home_player instanceof Player ? $home_player->GetName() : '', $this->IsValidSubmit());
     $home_box->SetMaxLength(100);
     $home_box->AddCssClass("player");
     $home_box->AddCssClass("team" . $match->GetHomeTeamId());
     $home_box->AddAttribute("autocomplete", "off");
     $home_part = new FormPart($this->NameTeams('Home player', $match->GetHomeTeam(), $match->GetAwayTeam()), $home_box);
     $home_part->SetCssClass("formPart multiPlayer");
     $match_box->AddControl($home_part);
     $away_box = new TextBox($this->GetNamingPrefix() . 'PlayerAway', $away_player instanceof Player ? $away_player->GetName() : '', $this->IsValidSubmit());
     $away_box->SetMaxLength(100);
     $away_box->AddCssClass("player");
     $away_box->AddCssClass("team" . $match->GetAwayTeamId());
     $away_box->AddAttribute("autocomplete", "off");
     $away_part = new FormPart($this->NameTeams('Away player', $match->GetHomeTeam(), $match->GetAwayTeam()), $away_box);
     $away_part->SetCssClass("formPart multiPlayer");
     $match_box->AddControl($away_part);
     # Any comments?
     $comments = new TextBox($this->GetNamingPrefix() . 'Comments', '', $this->IsValidSubmit());
     $comments->SetMode(TextBoxMode::MultiLine());
     $comments->AddAttribute('class', 'matchReport');
     $comments_label = new XhtmlElement('label');
     $comments_label->AddAttribute('for', $comments->GetXhtmlId());
     $comments_label->AddCssClass('matchReport');
     $comments_label->AddControl('Add a match report:');
     $match_box->AddControl($comments_label);
     $match_box->AddControl($comments);
     if ($match->GetLastAudit() != null) {
         require_once "data/audit-control.class.php";
         $match_box->AddControl(new AuditControl($match->GetLastAudit(), "match"));
     }
     $this->SetButtonText('Save match');
 }
 /**
  * Configures, and repopulates on postback, a dropdown list to manage one property of a related data item
  *
  * @param XhtmlSelect $select
  * @param string $s_validated_value
  * @param string $s_name
  * @param int $i_row_count
  * @param int $i_total_rows
  * @param bool $b_required
  * @param string $s_default_value
  * @return XhtmlSelect
  */
 protected function ConfigureSelect($select, $s_validated_value, $s_name, $i_row_count, $i_total_rows, $b_required = false, $s_default_value = '')
 {
     # Establish current status
     $b_is_add_row = is_null($i_row_count);
     $b_repopulate_add_row = (!$this->IsValid() or $this->DeleteClicked() or $this->IsUnrelatedInternalPostback());
     $select->SetXhtmlId($this->GetNamingPrefix() . $s_name . $i_row_count);
     if ($b_required) {
         $select->SetCssClass('required');
     }
     # If this is the row used to add a new related item...
     # Add a blank option only if data is not required, or there's no obvious default
     if ($b_is_add_row and (!$b_required or !strlen($s_default_value))) {
         $select->SetBlankFirst(true);
     }
     # If there is a default, set it
     if ($b_is_add_row and !$this->IsPostback() and strlen($s_default_value)) {
         $select->SelectOption($s_default_value);
     }
     # But if it's an existing row and data is required, there's no blank option...
     if (!$b_is_add_row and !$b_required) {
         $select->SetBlankFirst(true);
     }
     # If this is the row used to add a new related item...
     if ($b_is_add_row) {
         # ...if we repopulate, it'll be with the exact value posted,
         # as validation has either failed or not occurred
         if ($b_repopulate_add_row and isset($_POST[$select->GetXhtmlId()])) {
             $select->SelectOption($_POST[$select->GetXhtmlId()]);
         }
     } else {
         if ($this->IsValid()) {
             if ($this->AddClicked() and $i_row_count == $this->i_row_added) {
                 # If a new row was posted, is valid, and is now displayed here, need to get the posted value from the add row
                 $s_select_in_add_row = substr($select->GetXhtmlId(), 0, strlen($select->GetXhtmlId()) - strlen($i_row_count));
                 $select->SelectOption($_POST[$s_select_in_add_row]);
             } else {
                 # Even though the editor as a whole is valid, this row wasn't validated
                 # so just restore the previous value
                 if (isset($_POST[$select->GetXhtmlId()])) {
                     $select->SelectOption($_POST[$select->GetXhtmlId()]);
                 } else {
                     # Won't be in $_POST when page is first loaded
                     $select->SelectOption($s_validated_value);
                 }
             }
         } else {
             # Repopulate with the exact value posted, as validation has failed
             $select->SelectOption($_POST[$select->GetXhtmlId()]);
         }
     }
     # Return dropdown so that other things can be done to it - eg add a CSS class
     return $select;
 }