function showBody($eventId)
{
    #----------------------------------------------------------------------
    #--- Get the data
    $rows = dbQuery("\n    SELECT    personId, personName, min(value1+value2+value3) minSum, count(*) means, 0 minSum2, 0 means2\n    FROM      Results\n    WHERE     eventId = '{$eventId}' and (value1>0)+(value2>0)+(value3>0) = 3\n    GROUP BY  personId\n    ORDER BY  minSum, personName\n  ");
    $also2 = $eventId == '444bf' || $eventId == '555bf';
    if ($also2) {
        $rows = array_merge($rows, dbQuery("\n      SELECT    personId, personName, 0 minSum, 0 means, min(greatest(0,value1)+greatest(0,value2)+greatest(0,value3)) minSum2, count(*) means2\n      FROM      Results\n      WHERE     eventId = '{$eventId}' and (value1>0)+(value2>0)+(value3>0) = 2\n      GROUP BY  personId\n      ORDER BY  minSum2, personName\n    "));
    }
    #--- Output the table header
    TableBegin('results', 7);
    TableHeader(array('Pos', 'Name', 'Best Mean', 'Means', $also2 ? 'Best 2-Mean' : '', $also2 ? '2-Means' : '', ''), array('class="r"', 'class="p"', 'class="r"', 'class="r"', 'class="r"', 'class="r"', 'class="f"'));
    #--- Output the table contents
    $listed = array();
    $pos = 0;
    foreach ($rows as $row) {
        list($personId, $personName, $minSum, $means, $minSum2, $means2) = $row;
        if (!isset($listed[$personId])) {
            $mean = formatValue(round($minSum / 3));
            $mean2 = formatValue(round($minSum2 / 2));
            TableRow(array(++$pos, personLink($personId, $personName), $mean, $means, $mean2, $means2, ''));
        }
        $listed[$personId] = true;
    }
    #--- Output the table end
    TableEnd();
}
function showRegionalRecordsSeparate()
{
    #----------------------------------------------------------------------
    global $chosenRegionId;
    require 'regions_get_current_records.php';
    tableBegin('results', 6);
    tableCaption(false, "Single");
    tableHeader(explode('|', 'Event|Result|Person|Citizen of|Competition|'), array(1 => "class='R2'", 5 => 'class="f"'));
    foreach ($results as $result) {
        extract($result);
        if ($type == 'Single') {
            $isNewEvent = !isset($currentEventId) || $eventId != $currentEventId;
            $currentEventId = $eventId;
            tableRow(array($isNewEvent ? eventLink($eventId, $eventCellName) : '', $isNewEvent ? formatValue($value, $format) : '', personLink($personId, $personName), $countryName, competitionLink($competitionId, $competitionName), ''));
        }
    }
    tableCaption(false, "Average");
    tableHeader(explode('|', 'Event|Result|Person|Citizen of|Competition|Result Details'), array(1 => "class='R2'", 5 => 'class="f"'));
    $currentEventId = '';
    foreach ($results as $result) {
        extract($result);
        if ($type == 'Average') {
            $isNewEvent = $eventId != $currentEventId;
            $currentEventId = $eventId;
            tableRow(array($isNewEvent ? eventLink($eventId, $eventCellName) : '', $isNewEvent ? formatValue($value, $format) : '', personLink($personId, $personName), $countryName, competitionLink($competitionId, $competitionName), formatAverageSources(true, $result, $format)));
        }
    }
    tableEnd();
}
function showCompetitionResultsByPerson($resultsTable = 'Results')
{
    #----------------------------------------------------------------------
    global $chosenByPerson, $chosenAllResults, $chosenTop3, $chosenWinners;
    global $chosenCompetitionId;
    #--- Get the results.
    $competitionResults = getCompetitionResults($resultsTable);
    startTimer();
    tableBegin('results', 8);
    foreach ($competitionResults as $result) {
        extract($result);
        $isNewPerson = !isset($previousPersonId) || $personId != $previousPersonId;
        $isNewEvent = !isset($previousEventId) || $eventId != $previousEventId || $isNewPerson;
        #--- Welcome new persons.
        if ($isNewPerson) {
            if (isset($previousPersonId)) {
                tableRowBlank();
            }
            $bo3_as_mo3 = $formatId == '3' && ($eventId == '333bf' || $eventId == '333fm' || $eventId == '333ft');
            $headerAverage = $formatId == 'a' || $formatId == 'm' || $bo3_as_mo3 ? 'Average' : '';
            $headerAllResults = $formatId != '1' ? 'Result Details' : '';
            tableCaptionNew(false, $personId, spaced(array(personLink($personId, $personName), $countryName)));
            tableHeader(explode('|', "Event|Round|Place|Best||{$headerAverage}||{$headerAllResults}"), array(2 => 'class="r"', 3 => 'class="R"', 5 => 'class="R"', 7 => 'class="f"'));
        }
        #--- One result row.
        tableRowStyled($isNewEvent ? '' : 'color:#AAA', array($isNewEvent ? eventLink($eventId, $eventCellName) : '', $roundCellName, $isNewEvent ? "<b>{$pos}</b>" : $pos, formatValue($best, $valueFormat), $regionalSingleRecord, formatValue($average, $valueFormat), $regionalAverageRecord, formatAverageSources($formatId != '1', $result, $valueFormat)));
        $previousPersonId = $personId;
        $previousEventId = $eventId;
    }
    tableEnd();
    stopTimer("printing the huge table");
}
function showMatchingPersons()
{
    #----------------------------------------------------------------------
    global $chosenPatternHtml, $chosenPatternMysql, $chosenEventId, $chosenRegionId;
    #--- If nothing chosen yet, display a help message.
    if (!$chosenPatternHtml && !$chosenEventId && !$chosenRegionId) {
        echo "<div style='width:85%; margin:auto; font-size:1.00em; font-weight:bold'><p>For the name field search, enter any name or name parts and don't worry about letter variations. For example, 'or joe' (enter without the quotes) will among others also find Jo&euml;l van Noort.</p></div>";
        return;
    }
    #--- The pattern should contain at least 2 non-whitespace characters.
    if (!preg_match('/\\S.*\\S/', $chosenPatternHtml)) {
        noticeBox3(-1, "Please Enter at least 2 characters.");
        echo "<div style='width:85%; margin:auto; font-size:1.00em; font-weight:bold'><p>For the name field search, enter any name or name parts and don't worry about letter variations. For example, 'or joe' (enter without the quotes) will among others also find Jo&euml;l van Noort.</p></div>";
        return;
    }
    #--- Otherwise, build up a query to search for people.
    global $wcadb_conn;
    $params = array(0 => '');
    $parts = array();
    $rawPattern = getRawParamThisShouldBeAnException('pattern');
    #--- Build the nameCondition (all searched parts must occur).
    $nameCondition = "";
    foreach (explode(' ', $rawPattern) as $namePart) {
        $parts[$namePart] = '%' . $namePart . '%';
        $params[0] .= 's';
        $params[] =& $parts[$namePart];
        $likeId = '';
        if (ctype_alnum($namePart)) {
            $params[0] .= 's';
            $params[] =& $parts[$namePart];
            $likeId = ' OR person.id LIKE ?';
        }
        $nameCondition .= ' AND (person.name LIKE ?' . $likeId . ')';
    }
    #--- Build the eventCondition (if any).
    if ($chosenEventId) {
        $eventConditionPart1 = ', (SELECT DISTINCT personId FROM ConciseSingleResults WHERE 1 ' . eventCondition() . ') result';
        $eventConditionPart2 = 'AND person.id = result.personId';
    } else {
        $eventConditionPart1 = '';
        $eventConditionPart2 = '';
    }
    #--- Do the query!
    $query = 'SELECT DISTINCT person.id AS personId, person.name AS personName, country.name AS countryName
            FROM Persons AS person, Countries AS country' . $eventConditionPart1 . ' WHERE ' . randomDebug() . $nameCondition . regionCondition('') . ' AND country.id = person.countryId' . $eventConditionPart2 . ' ORDER BY personName, countryName, personId';
    $persons = $wcadb_conn->boundQuery($query, $params);
    $count = count($persons);
    $ext = $count != 1 ? 's' : '';
    tableBegin('results', 3);
    tableCaption(false, spaced(array("{$count} person{$ext} matching:", eventName($chosenEventId), chosenRegionName($chosenRegionId), $chosenPatternHtml ? "\"{$chosenPatternHtml}\"" : '')));
    tableHeader(explode('|', 'Person|WCA id|Citizen of'), array(2 => 'class="f"'));
    foreach ($persons as $person) {
        extract($person);
        tableRow(array(personLink($personId, $personName), $personId, $countryName));
    }
    tableEnd();
}
function showResults()
{
    #----------------------------------------------------------------------
    global $chosenEventId, $chosenRegionId, $chosenYears, $chosenShow, $chosenSingle, $chosenAverage;
    #--- Try the cache
    tryCache('event', $chosenEventId, preg_replace('/ /', '', $chosenRegionId), $chosenYears, preg_replace('/ /', '', $chosenShow), $chosenSingle, $chosenAverage);
    #------------------------------
    # Prepare stuff for the query.
    #------------------------------
    $eventCondition = eventCondition();
    $yearCondition = yearCondition();
    $regionCondition = regionCondition('result');
    $limitCondition = '';
    if (preg_match('/^10+/', $chosenShow, $matches)) {
        $limitNumber = $matches[0];
        $limitCondition = 'LIMIT ' . 2 * $limitNumber;
    }
    $valueSource = $chosenAverage ? 'average' : 'best';
    $valueName = $chosenAverage ? 'Average' : 'Single';
    #------------------------------
    # Get results from database.
    #------------------------------
    if ($chosenShow == 'By Region') {
        require 'includes/events_regions.php';
        return;
    }
    if ($chosenShow == '100 Results' || $chosenShow == '1000 Results') {
        require 'includes/events_results.php';
    } else {
        require 'includes/events_persons.php';
    }
    #------------------------------
    # Show the table.
    #------------------------------
    startTimer();
    $event = getEvent($chosenEventId);
    tableBegin('results', 6);
    tableCaption(true, spaced(array($event['name'], chosenRegionName(), $chosenYears, $chosenShow)));
    $headerSources = $chosenAverage ? 'Result Details' : '';
    tableHeader(explode('|', "Rank|Person|Result|Citizen of|Competition|{$headerSources}"), array(0 => "class='r'", 2 => "class='R2'", 5 => 'class="f"'));
    $ctr = 0;
    foreach ($results as $result) {
        extract($result);
        $ctr++;
        $no = isset($previousValue) && $value == $previousValue ? '&nbsp;' : $ctr;
        if ($limitCondition && $no > $limitNumber) {
            break;
        }
        tableRow(array($no, personLink($personId, $personName), formatValue($value, $event['format']), htmlEntities($countryName), competitionLink($competitionId, $competitionName), formatAverageSources($chosenAverage, $result, $event['format'])));
        $previousValue = $value;
    }
    tableEnd();
    stopTimer("printing the table");
}
function showRegionalRecordsHistory()
{
    #----------------------------------------------------------------------
    global $chosenRegionId, $chosenHistory, $chosenMixHist;
    #--- Compute the region condition and the normal record name.
    if (preg_match('/^(world)?$/i', $chosenRegionId)) {
        $regionCondition = "AND recordName = 'WR'";
        $normalRecordName = '';
    } elseif (preg_match('/^_/', $chosenRegionId)) {
        $tmp = dbQuery("SELECT recordName FROM Continents WHERE id = '{$chosenRegionId}'");
        $normalRecordName = $tmp[0][0];
        $regionCondition = "AND recordName in ('WR', '{$normalRecordName}' ) AND continentId = '{$chosenRegionId}'";
    } else {
        $regionCondition = "AND (recordName <> '') AND (result.countryId = '{$chosenRegionId}')";
        $normalRecordName = 'NR';
    }
    #--- Order: normal history or mixed?
    $order = $chosenHistory ? 'event.rank, type, value, year desc, month desc, day desc, roundId desc' : 'year desc, month desc, day desc, roundId desc, event.rank, type, value';
    #--- Get the results.
    $results = dbQuery("\n    SELECT\n      year, month, day,\n\n      event.id         eventId,\n      event.name       eventName,\n      event.cellName   eventCellName,\n\n      result.type      type,\n      result.value     value,\n      event.format     valueFormat,\n                       recordName,\n\n      result.personId   personId,\n      result.personName personName,\n\n      country.name     countryName,\n\n      competition.id   competitionId,\n      competition.cellName competitionName,\n\n      value1, value2, value3, value4, value5\n    FROM\n      (SELECT Results.*, 1 type, best    value, regionalSingleRecord  recordName FROM Results WHERE regionalSingleRecord<>'' UNION\n       SELECT Results.*, 2 type, average value, regionalAverageRecord recordName FROM Results WHERE regionalAverageRecord<>'') result,\n      Events event,\n      Competitions competition,\n      Countries country\n    WHERE " . randomDebug() . "\n      AND event.id = eventId\n      AND event.rank < 1000\n      AND competition.id = competitionId\n      AND country.id = result.countryId\n      {$regionCondition}\n      " . eventCondition() . yearCondition() . "\n    ORDER BY\n      {$order}\n  ");
    #--- Start the table
    if ($chosenHistory) {
        tableBegin('results', 7);
    } else {
        tableBegin('results', 9);
        tableHeader(explode('|', 'Date circa|Event|What|Single|Average|Person|Citizen of|Competition|Result Details'), array(3 => 'class="R2"', 4 => 'class="R2"', 8 => 'class="f"'));
    }
    #--- Process the results.
    $currentEventId = false;
    foreach ($results as $result) {
        extract($result);
        #--- Announce the event (only for normal history, not mixed)
        if ($chosenHistory && $eventId != $currentEventId) {
            $currentEventId = $eventId;
            tableCaptionNew(false, $eventId, eventLink($eventId, $eventName));
            tableHeader(explode('|', '|Single|Average|Person|Citizen of|Competition|Result Details'), array(1 => 'class="R2"', 2 => 'class="R2"', 6 => 'class="f"'));
        }
        #--- Determine how to display the record name.
        if ($recordName != $normalRecordName) {
            $recordName = "<span style='color:#f93;font-weight:bold'>{$recordName}</span>";
        }
        #--- Prepare the table row.
        $data = array($recordName, $type == 1 ? formatValue($value, $valueFormat) : '', $type == 2 ? formatValue($value, $valueFormat) : '', personLink($personId, $personName), $countryName, competitionLink($competitionId, $competitionName), formatAverageSources($type == 2, $result, $valueFormat));
        if ($chosenMixHist) {
            array_unshift($data, sprintf('%4d-%02d-%02d', $year, $month, $day), eventLink($eventId, $eventCellName));
        }
        #--- Show the table row.
        tableRow($data);
    }
    tableEnd();
}
function showRegionalRecordsSlim()
{
    #----------------------------------------------------------------------
    global $chosenYears;
    require 'regions_get_current_records.php';
    tableBegin('results', 6);
    $caption = spaced(array(chosenRegionName(), $chosenYears));
    if ($caption) {
        tableCaption(true, $caption);
    } else {
        tableRowBlank();
    }
    tableHeader(explode('|', 'Person|Single|Event|Average|Person|Result Details'), array(1 => "class='R2'", 2 => "class='c'", 3 => "class='R2'", 5 => 'class="f"'));
    #--- Process events.
    foreach (structureBy($results, 'eventId') as $eventResults) {
        $structure = structureBy($eventResults, 'type');
        $singles = $structure[0];
        $averages = isset($structure[1]) ? $structure[1] : array();
        $wasShownSinglePerson = $wasShownAveragePerson = array();
        #--- Process records for this event.
        $first = true;
        while ($singles || $averages) {
            #--- Get next single.
            $s = array_shift($singles);
            if (isset($wasShownSinglePerson[$s['personId']])) {
                $s = false;
            }
            $wasShownSinglePerson[$s['personId']] = true;
            #--- Get next average.
            $a = array_shift($averages);
            if (isset($wasShownAveragePerson[$a['personId']])) {
                $a = false;
            }
            $wasShownAveragePerson[$a['personId']] = true;
            if ($s || $a) {
                tableRow(array($s ? personLink($s['personId'], $s['personName']) : '', $first ? formatValue($s['value'], $s['format']) : '', $first ? eventLink($s['eventId'], $s['eventCellName']) : '', $first ? formatValue($a['value'], $a['format']) : '', $a ? personLink($a['personId'], $a['personName']) : '', $a ? formatAverageSources(true, $a, $a['format']) : ''));
            }
            $first = false;
        }
    }
    tableEnd();
}
function showRegionalRecordsMixed()
{
    #----------------------------------------------------------------------
    global $chosenRegionId, $chosenYears;
    require 'regions_get_current_records.php';
    tableBegin('results', 6);
    tableCaption(false, spaced(array(chosenRegionName(), $chosenYears)));
    tableHeader(explode('|', 'Type|Result|Person|Citizen of|Competition|Result Details'), array(1 => "class='R2'", 5 => 'class="f"'));
    foreach ($results as $result) {
        extract($result);
        $isNewEvent = !isset($currentEventId) || $eventId != $currentEventId;
        $currentEventId = $eventId;
        $isNewType = $isNewEvent || !isset($currentType) || $type != $currentType;
        $currentType = $type;
        if ($isNewEvent) {
            tableCaption(false, eventLink($eventId, $eventName));
        }
        tableRow(array($isNewType ? $type : '', $isNewType ? formatValue($value, $format) : '', personLink($personId, $personName), $countryName, competitionLink($competitionId, $competitionName), formatAverageSources($type == 'Average', $result, $format)));
    }
    tableEnd();
}
function checkSimilarResults()
{
    #----------------------------------------------------------------------
    global $competitionCondition, $chosenWhich;
    echo "<hr /><p>Checking <b>" . $chosenWhich . " similar results</b>... (wait for the result message box at the end)</p>\n";
    #--- Get all similar results (except old-new multiblind)
    $rows = pdo_query("\n      SELECT\n          Results.competitionId AS competitionId,\n          Results.personId AS personIdA, Results.personName AS personNameA, Results.eventId AS eventIdA, Results.roundId AS roundIdA,\n          h.personId AS personIdB, h.personName AS personNameB, h.eventId AS eventIdB, h.roundId AS roundIdB,\n          Results.value1 AS value1A, Results.value2 AS value2A, Results.value3 AS value3A, Results.value4 AS value4A, Results.value5 AS value5A,\n          h.value1 AS value1B, h.value2 AS value2B, h.value3 AS value3B, h.value4 AS value4B, h.value5 AS value5B\n      FROM Results\n      JOIN (\n          SELECT competitionId, eventId, roundId, personId, personName, value1, value2, value3, value4, value5\n          FROM Results " . ($competitionCondition ? "JOIN Competitions ON Competitions.id = competitionId " : "") . "WHERE best > 0 " . ($competitionCondition ? $competitionCondition : "") . " AND value3 <> 0\n              AND eventId <> '333mbo'\n      ) h ON Results.competitionId = h.competitionId\n          AND Results.eventId <> '333mbo'\n          AND Results.personId < h.personId\n          AND (\n              (Results.value1 = h.value1 AND h.value1 > 0) +\n              (Results.value2 = h.value2 AND h.value2 > 0) +\n              (Results.value3 = h.value3 AND h.value3 > 0) +\n              (Results.value4 = h.value4 AND h.value4 > 0) +\n              (Results.value5 = h.value5 AND h.value5 > 0) > 2\n              )\n  ");
    tableBegin('results', 4);
    foreach ($rows as $row) {
        $competition = getCompetition($row['competitionId']);
        $competitionName = $competition['cellName'];
        tableCaption(false, competitionLink($row['competitionId'], $competitionName));
        tableHeader(explode('|', "Person|Event|Round|Result Details"), array(3 => 'class="f"'));
        foreach (array('A', 'B') as $letter) {
            $otherLetter = chr(65 + 66 - ord($letter));
            $resultStr = '';
            for ($i = 1; $i <= 5; $i++) {
                $value = $row['value' . $i . $letter];
                if (!$value) {
                    break;
                }
                $resultStr .= "<span class='label label-" . ($value == $row['value' . $i . $otherLetter] ? "danger" : "success") . "'>" . formatValue($value, valueFormat($row['eventId' . $letter])) . "</span> ";
            }
            tableRow(array(personLink($row['personId' . $letter], $row['personName' . $letter]), eventCellName($row['eventId' . $letter]), roundCellName($row['roundId' . $letter]), $resultStr));
        }
    }
    tableEnd();
    #--- Tell the result.
    $date = wcaDate();
    noticeBox2(count($rows) == 0, "No similar results were found.<br />{$date}", "Similar results were found.<br />{$date}");
}
function showQualifications($competitionId, $eventId, $roundId1, $roundId2)
{
    #----------------------------------------------------------------------
    global $competitionResults1, $competitionResults2, $personsBothRounds;
    getQualifications($competitionId, $eventId, $roundId1, $roundId2);
    tableBegin('results', 8);
    #--- Display competitors only in round 2
    foreach ($competitionResults2 as $key => $result) {
        if (in_array($result['personId'], $personsBothRounds)) {
            continue;
        }
        extract($result);
        #--- Header
        if (!$captionShowed) {
            $anchors = "{$eventId} " . "{$eventId}_{$roundId}";
            $eventHtml = eventLink($eventId, $eventName);
            $caption = spaced(array($eventHtml, $roundName, $formatName));
            tableCaptionNew(false, $anchors, $caption);
            $headerAverage = $formatId == 'a' || $formatId == 'm' ? 'Average' : '';
            $headerAllResults = $formatId != '1' ? 'Result Details' : '';
            tableHeader(explode('|', "Person|Place|Best|{$headerAverage}|Place|Best|{$headerAverage}|"), array(1 => 'class="r"', 2 => 'class="R"', 3 => 'class="R"', 4 => 'class="r"', 5 => 'class="R"', 6 => 'class="R"', 7 => 'class="f"'));
            $captionShowed = true;
        }
        #--- One result row.
        tableRow(array(personLink($personId, $personName), '', '', '', $pos, formatValue($best, $valueFormat), formatValue($average, $valueFormat), ''));
        unset($competitionResults2[$key]);
        // Little speed-up for the second part
    }
    #--- Display the rest
    foreach ($competitionResults1 as $result) {
        extract($result);
        $inRound2 = false;
        foreach ($competitionResults2 as $key => $result2) {
            if ($result2['personId'] == $personId) {
                extract($result2, EXTR_PREFIX_ALL, 'r2');
                unset($competitionResults2[$key]);
                $inRound2 = true;
                $nbQuals += 1;
                break;
            }
        }
        #--- Header
        if (!$captionShowed) {
            $anchors = "{$eventId} " . "{$eventId}_{$roundId}";
            $eventHtml = eventLink($eventId, $eventName);
            $caption = spaced(array($eventHtml, $roundName, $formatName));
            tableCaptionNew(false, $anchors, $caption);
            $headerAverage = $formatId == 'a' || $formatId == 'm' ? 'Average' : '';
            $headerAllResults = $formatId != '1' ? 'Result Details' : '';
            tableHeader(explode('|', "Person|Place|Best|{$headerAverage}|Place|Best|{$headerAverage}|"), array(1 => 'class="r"', 2 => 'class="R"', 3 => 'class="R"', 4 => 'class="r"', 5 => 'class="R"', 6 => 'class="R"', 7 => 'class="f"'));
            $captionShowed = true;
        }
        $offerToDelete = $inRound2 && 4 * $nbQuals > 3 * count($competitionResults1);
        #--- One result row.
        tableRow(array(personLink($personId, $personName), $pos, formatValue($best, $valueFormat), formatValue($average, $valueFormat), $inRound2 ? $r2_pos : "", $inRound2 ? formatValue($r2_best, $r2_valueFormat) : "", $inRound2 ? formatValue($r2_average, $r2_valueFormat) : "", $offerToDelete ? "<input type='checkbox' name='deleteres{$r2_id}' value='1' /> Delete" : ""));
    }
    tableEnd();
}
function computeRegionalRecordMarkers($valueId, $valueName)
{
    #----------------------------------------------------------------------
    global $chosenAnything, $chosenCompetitionId, $differencesWereFound, $previousRecord, $pendingCompetitions, $startDate;
    # -----------------------------
    # Description of the main idea:
    # -----------------------------
    # Get all results that are potential regional records. Process them one
    # event at a time. Inside, process them one competition at a time, in
    # chronological order of start date. Each competition's results are only
    # compared against records of strictly previous competitions, not against
    # parallel competitions. For this, there are these main arrays:
    #
    # - $previousRecord[regionId] is a running collection of each region's record,
    #   covering all competitions *before* the current one.
    #
    # - $record[regionId] is based on $previousRecord and is used and updated
    #   inside the current competition.
    #
    # - $pendingCompetitions[regionId] holds $record of competitions already
    #   processed but not merged into $previousRecord. When a new competition is
    #   encountered, we merge those that ended before the new one into $previousRecord.
    #
    # - $baseRecord[eventId][regionId] is for when a user chose a specific
    #   competition to check. Then we quickly ask the database for the current
    #   region records from before that competition. This could be used for
    #   giving the user a year-option as well, but we don't have that (yet?).
    # -----------------------------
    #--- If a competition was chosen, we need all records from before it
    if ($chosenCompetitionId) {
        $startDate = getCompetitionValue($chosenCompetitionId, "year*10000 + month*100 + day");
        $results = dbQueryHandle("\n      SELECT eventId, result.countryId, continentId, min({$valueId}) value, event.format valueFormat\n      FROM Results result, Competitions competition, Countries country, Events event\n      WHERE {$valueId} > 0\n        AND competition.id = result.competitionId\n        AND country.id     = result.countryId\n        AND event.id       = result.eventId\n        AND year*10000 + if(endMonth,endMonth,month)*100 + if(endDay,endDay,day) < {$startDate}\n      GROUP BY eventId, countryId");
        while ($row = mysql_fetch_row($results)) {
            list($eventId, $countryId, $continentId, $value, $valueFormat) = $row;
            if (isSuccessValue($value, $valueFormat)) {
                foreach (array($countryId, $continentId, 'World') as $regionId) {
                    if (!isset($baseRecord[$eventId][$regionId]) || $value < $baseRecord[$eventId][$regionId]) {
                        $baseRecord[$eventId][$regionId] = $value;
                    }
                }
            }
        }
        mysql_free_result($results);
    } else {
        $competitions = dbQuery("\n      SELECT id, year*10000 + if(endMonth,endMonth,month)*100 + if(endDay,endDay,day) endDate\n      FROM   Competitions competition");
        foreach ($competitions as $competition) {
            $endDate[$competition['id']] = $competition['endDate'];
        }
    }
    #--- The IDs of relevant results (those already marked as region record and those that could be)
    $queryRelevantIds = "\n   (SELECT id FROM Results WHERE regional{$valueName}Record<>'' " . eventCondition() . competitionCondition() . ")\n   UNION\n   (SELECT id\n    FROM\n      Results result,\n      (SELECT eventId, competitionId, roundId, countryId, min({$valueId}) value\n       FROM Results\n       WHERE {$valueId} > 0\n       " . eventCondition() . competitionCondition() . "\n       GROUP BY eventId, competitionId, roundId, countryId) helper\n    WHERE result.eventId       = helper.eventId\n      AND result.competitionId = helper.competitionId\n      AND result.roundId       = helper.roundId\n      AND result.countryId     = helper.countryId\n      AND result.{$valueId}      = helper.value)";
    #--- Get the results, ordered appropriately
    $results = dbQueryHandle("\n    SELECT\n      year*10000 + month*100 + day startDate,\n      result.id resultId,\n      result.eventId,\n      result.competitionId,\n      result.roundId,\n      result.personId,\n      result.personName,\n      result.countryId,\n      result.regional{$valueName}Record storedMarker,\n      {$valueId} value,\n      continentId,\n      continent.recordName continentalRecordName,\n      event.format valueFormat\n    FROM\n      ({$queryRelevantIds}) relevantIds,\n      Results      result,\n      Competitions competition,\n      Countries    country,\n      Continents   continent,\n      Events       event,\n      Rounds       round\n    WHERE 1\n      AND result.id      = relevantIds.id\n      AND competition.id = result.competitionId\n      AND round.id       = result.roundId\n      AND country.id     = result.countryId\n      AND continent.id   = country.continentId\n      AND event.id       = result.eventId\n    ORDER BY event.rank, startDate, competitionId, round.rank, {$valueId}\n  ");
    #--- For displaying the dates, fetch all competitions
    $allCompetitions = array();
    foreach (dbQuery("SELECT * FROM Competitions") as $row) {
        $allCompetitions[$row['id']] = $row;
    }
    #--- Process each result.
    $currentEventId = $announcedEventId = $announcedRoundId = $announcedCompoId = NULL;
    while ($row = mysql_fetch_row($results)) {
        list($startDate, $resultId, $eventId, $competitionId, $roundId, $personId, $personName, $countryId, $storedMarker, $value, $continentId, $continentalRecordName, $valueFormat) = $row;
        #--- Handle failures of multi-attempts.
        if (!isSuccessValue($value, $valueFormat)) {
            continue;
        }
        #--- At new events, reset everything
        if ($eventId != $currentEventId) {
            $currentEventId = $eventId;
            $currentCompetitionId = false;
            $record = $previousRecord = isset($baseRecord[$eventId]) ? $baseRecord[$eventId] : array();
            $pendingCompetitions = array();
        }
        #--- Handle new competitions.
        if ($competitionId != $currentCompetitionId) {
            #--- Add the records of the previously current competition to the set of pending competition records
            if ($currentCompetitionId) {
                $pendingCompetitions[] = array($endDate[$currentCompetitionId], $record);
            }
            #--- Note the current competition
            $currentCompetitionId = $competitionId;
            #--- Prepare the records this competition will be based on
            $pendingCompetitions = array_filter($pendingCompetitions, "handlePendingCompetition");
            $record = $previousRecord;
        }
        #--- Calculate whether it's a new region record and update the records.
        $calcedMarker = '';
        if (!isset($record[$countryId]) || $value <= $record[$countryId]) {
            $calcedMarker = 'NR';
            $record[$countryId] = $value;
            if (!isset($record[$continentId]) || $value <= $record[$continentId]) {
                $calcedMarker = $continentalRecordName;
                $record[$continentId] = $value;
                if (!isset($record['World']) || $value <= $record['World']) {
                    $calcedMarker = 'WR';
                    $record['World'] = $value;
                }
            }
        }
        #--- If stored or calculated marker say it's some regional record at all...
        if ($storedMarker || $calcedMarker) {
            #--- Do stored and calculated agree? Choose colors and update list of differences.
            $same = $storedMarker == $calcedMarker;
            $storedColor = $same ? '999' : 'F00';
            $calcedColor = $same ? '999' : '0E0';
            if (!$same) {
                $selectedIds[] = $resultId;
                $differencesWereFound = true;
            }
            #--- If no filter was chosen, only show differences.
            if (!$chosenAnything && $same) {
                continue;
            }
            #--- Highlight regions if the calculated marker thinks it's a record for them.
            $countryName = $countryId;
            $continentName = substr($continentId, 1);
            $worldName = 'World';
            if ($calcedMarker) {
                $countryName = "<b>{$countryName}</b>";
            }
            if ($calcedMarker && $calcedMarker != 'NR') {
                $continentName = "<b>{$continentName}</b>";
            }
            if ($calcedMarker == 'WR') {
                $worldName = "<b>{$worldName}</b>";
            }
            #--- Recognize new events/rounds/competitions.
            $announceEvent = $eventId != $announcedEventId;
            $announcedEventId = $eventId;
            $announceRound = $roundId != $announcedRoundId;
            $announcedRoundId = $roundId;
            $announceCompo = $competitionId != $announcedCompoId;
            $announcedCompoId = $competitionId;
            #--- If new event, announce it.
            if ($announceEvent) {
                tableCaption(false, "{$eventId} {$valueName}");
                tableHeader(explode('|', 'Date|Competition|Round|Person|Event|Country|Continent|World|Value|Stored|Computed|Agree'), array(7 => "class='R2'"));
            }
            #--- If new round/competition inside an event, add a separator row.
            if (($announceRound || $announceCompo) && !$announceEvent) {
                tableRowEmpty();
            }
            #--- Prepare the checkbox.
            $checkbox = "<input type='checkbox' name='update{$valueName}{$resultId}' value='{$calcedMarker}' />";
            #--- Show the result.
            tableRow(array(competitionDate($allCompetitions[$competitionId]), competitionLink($competitionId, $competitionId), $roundId, personLink($personId, $personName), $eventId, $countryName, $continentName, $worldName, formatValue($value, $valueFormat), "<span style='font-weight:bold;color:#{$storedColor}'>{$storedMarker}</span>", "<span style='font-weight:bold;color:#{$calcedColor}'>{$calcedMarker}</span>", $same ? '' : $checkbox));
        }
    }
    mysql_free_result($results);
}
    }
    $result['regionName'] = 'World';
    if ($value == $bestValueOfWorld) {
        $bestOfWorld[] = $result;
    }
}
#----------------------------------------------------------------------
#   Print the table.
#----------------------------------------------------------------------
startTimer();
$regionName = preg_replace('/^_/', '', $chosenRegionId);
$eventName = eventName($chosenEventId);
$headerSources = $chosenAverage ? 'Result Details' : '';
tableBegin('results', 5);
tableCaption(true, spaced(array($eventName, $chosenShow, $regionName, $chosenYears)));
tableHeader(explode('|', "Region|Result|Person|Competition|{$headerSources}"), array(0 => 'class="L"', 1 => "class='R2'", 4 => 'class="f"'));
if (isset($bestOfCountry)) {
    $all = array_merge($bestOfWorld, array(0), $bestOfContinent, array(0), $bestOfCountry);
    foreach ($all as $row) {
        if (!$row) {
            tableRowEmpty();
            continue;
        }
        extract($row);
        $isNewRegion = !isset($previousRegionName) || $regionName != $previousRegionName;
        $previousRegionName = $regionName;
        tableRow(array($isNewRegion ? $regionName : '', $isNewRegion ? formatValue($value, $valueFormat) : '', personLink($personId, $personName), competitionLink($competitionId, $competitionName), formatAverageSources($chosenAverage, $row, $valueFormat)));
    }
}
tableEnd();
stopTimer("printing the table");
function showPsychSheet($eventId)
{
    #----------------------------------------------------------------------
    global $chosenCompetitionId;
    echo "<h1>Psych Sheet</h1><br />";
    #--- What's first, single or average?
    $order = count(dbQuery("SELECT * FROM Results WHERE eventId='{$eventId}' AND formatId in ('a','m') LIMIT 1")) ? array('Average', 'Single') : array('Single', 'Average');
    #--- Get singles, averages and preregs.
    $score1 = array();
    foreach (dbQuery("SELECT personId, best, worldRank FROM Ranks{$order[0]} WHERE eventId='{$eventId}'") as $row) {
        $score1[$row['personId']] = array($row['best'], $row['worldRank']);
    }
    $score2 = array();
    foreach (dbQuery("SELECT personId, best, worldRank FROM Ranks{$order[1]} WHERE eventId='{$eventId}'") as $row) {
        $score2[$row['personId']] = array($row['best'], $row['worldRank']);
    }
    $preregs = dbQuery("\n    SELECT personId, name, countryId\n    FROM   Preregs\n    WHERE  competitionId = '{$chosenCompetitionId}'\n      AND  status = 'a'\n      AND  eventIds rlike '[[:<:]]{$eventId}[[:>:]]'\n  ");
    #--- Add singles, averages and a comparison key to the preregs.
    foreach ($preregs as &$prereg) {
        extract($prereg);
        $prereg['score1'] = isset($score1[$personId]) ? $score1[$personId] : array(0, 0);
        # PHP suuuucks
        $prereg['score2'] = isset($score2[$personId]) ? $score2[$personId] : array(0, 0);
        $s1 = isset($score1[$personId]) ? $score1[$personId][1] : 999999999;
        $s2 = isset($score2[$personId]) ? $score2[$personId][1] : 999999999;
        $prereg['cmpKey'] = sprintf('%09d%09d', $s1, $s2);
    }
    unset($prereg);
    # Because otherwise PHP is a weirdo and messes up the table-foreach below.
    #--- Sort the preregs.
    usort($preregs, function ($a, $b) {
        return strcmp($a['cmpKey'], $b['cmpKey']);
    });
    #--- Show the preregs table.
    tableBegin('results', 8);
    tableCaption(false, eventName($eventId));
    tableHeader(explode('|', "Rank|Person|Citizen of|Best {$order[0]}|WR|Best {$order[1]}|WR|"), array(0 => 'class="r"', 3 => 'class="R"', 4 => 'class="R"', 5 => 'class="r"', 6 => 'class="r"', 7 => 'class="f"'));
    $ctr = 0;
    $lastCmpKey = '';
    foreach ($preregs as $prereg) {
        extract($prereg);
        $ctr++;
        $rank = $cmpKey > $lastCmpKey ? $ctr : '';
        $lastCmpKey = $cmpKey;
        tableRow(array($rank, $personId ? personLink($personId, $name) : $name, $countryId, formatValue($score1[0], valueFormat($eventId)), $score1[1], formatValue($score2[0], valueFormat($eventId)), $score2[1], ''));
    }
    tableEnd();
}
function showResults()
{
    #----------------------------------------------------------------------
    global $chosenRegionId, $chosenSingle, $chosenAverage;
    #------------------------------
    # Prepare stuff for the query.
    #------------------------------
    $regionCondition = regionCondition('result');
    $limitCondition = 'LIMIT 120';
    $valueSource = $chosenAverage ? 'average' : 'best';
    $valueName = $chosenAverage ? 'Average' : 'Single';
    #------------------------------
    # Get results from database.
    #------------------------------
    $limitNumber = 300;
    $ranks = getRanks($valueName, $chosenRegionId);
    list($rows, $header) = sumOfRanks($valueName, getAllEventIds(), $ranks, $limitNumber + 20);
    $header = preg_replace('/ +/', '|', preg_replace('/\\[\\w+\\]/', '', "Rank {$header} "));
    foreach (dbQuery("SELECT id, name FROM Persons WHERE subId=1") as $person) {
        $personName[$person[0]] = $person[1];
    }
    #------------------------------
    # Show the table.
    #------------------------------
    $numColumns = count($rows[0]) + 2;
    $headerAttributes = array(0 => "class='r'", 2 => "class='R2'", $numColumns - 1 => 'class="f"');
    for ($i = 3; $i < $numColumns - 1; $i++) {
        $headerAttributes[$i] = "class='r'";
    }
    tableBegin('results', $numColumns);
    tableCaption(true, chosenRegionName(true));
    #  tableHeader( explode( '|', $header), $headerAttributes );
    $ctr = $previousSumOfRanks = 0;
    $showHeader = true;
    foreach ($rows as $row) {
        $showHeader |= $ctr % 20 == 0;
        list($personId, $sumOfRanks) = $row;
        $ctr++;
        $no = $sumOfRanks == $previousSumOfRanks ? '' : $ctr;
        if ($limitCondition && $no > $limitNumber) {
            break;
        }
        if ($showHeader && $no) {
            tableHeader(explode('|', $header), $headerAttributes);
            $showHeader = false;
        }
        for ($i = 2; $i < $numColumns - 2; $i++) {
            if (preg_match('/^(10|[1-9])$/', $row[$i])) {
                $row[$i] = "<span style='color:#0D0'>{$row[$i]}</span>";
            }
        }
        $row[0] = personLink($row[0], $personName[$row[0]]);
        $row[] = '';
        array_unshift($row, $no);
        tableRow($row);
        $previousSumOfRanks = $sumOfRanks;
    }
    tableEnd();
}
function addList($list, $legacyId)
{
    #----------------------------------------------------------------------
    $competitions = readDatabaseTableWithId('Competitions');
    list($id, $title, $subtitle, $columnDefs, $rows) = $list;
    $info = isset($list[5]) ? $list[5] : '';
    #--- From column definitions like "[P] Person [N] Appearances [T] | [P] Person [N] Appearances"
    #--- extract classes and names like:
    #--- ('P', 'N', 'T', 'P', 'N', 'f')
    #--- ('Person', 'Appearances, '&nbsp; &nbsp; | &nbsp; &nbsp;', 'Person', 'Appearances', '&nbsp;')
    $columnDefs = "{$columnDefs} [f] &nbsp;";
    $columnDefs = preg_replace('/\\|/', ' &nbsp; &nbsp; | &nbsp; &nbsp; ', $columnDefs);
    preg_match_all('/\\[(\\w+)\\]\\s*([^[]*[^[ ])/', $columnDefs, $matches);
    $columnClasses = $matches[1];
    $columnNames = $matches[2];
    $ctr = 0;
    foreach ($columnClasses as $class) {
        if ($class == 'P') {
        } elseif ($class == 'E') {
        } elseif ($class == 'C') {
        } elseif ($class == 't') {
        } elseif ($class == 'T') {
            $attributes[$ctr] = 'class="L"';
        } elseif ($class == 'N') {
            $attributes[$ctr] = 'class="R2"';
        } elseif ($class == 'n') {
            $attributes[$ctr] = 'class="r"';
        } elseif ($class == 'R') {
            $attributes[$ctr] = 'class="R2"';
        } elseif ($class == 'r') {
            $attributes[$ctr] = 'class="r"';
        } elseif ($class == 'f') {
            $attributes[$ctr] = 'class="f"';
        } else {
            showErrorMessage("Unknown column type <b>'</b>{$class}<b>'</b>");
        }
        $ctr++;
    }
    if ($subtitle) {
        $subtitle = "<span style='color:#999'>({$subtitle})</span>";
    }
    if ($info) {
        $info = htmlEntities($info, ENT_QUOTES);
        $info = "(<a title='{$info}' style='color:#FC0' onclick='alert(\"{$info}\")'>info</a>)";
    }
    $columnCount = count($columnNames);
    echo "<div id='{$id}'>\n";
    TableBegin('results', $columnCount);
    TableCaptionNew(false, $legacyId, "{$title} {$subtitle} {$info}");
    TableHeader($columnNames, $attributes);
    #--- Display the table.
    $rowCtr = 0;
    foreach ($rows as $row) {
        $values = array();
        $numbers = '';
        #    array_unshift( $row, 0 );
        #    foreach( $row as $key => $value ){
        foreach (range(0, $columnCount - 2) as $i) {
            $value = $row[$i];
            $Class = ucfirst($columnClasses[$i]);
            if ($Class == 'P' && $value) {
                $value = personLink($value, extractRomanName(currentPersonName($value)));
            }
            if ($Class == 'E') {
                $value = eventLink($value, eventCellName($value));
            }
            if ($Class == 'C') {
                $value = competitionLink($value, $competitions[$value]['cellName']);
            }
            if ($Class == 'R') {
                $value = formatValue($value, isset($row['eventId']) ? valueFormat($row['eventId']) : 'time');
            }
            $values[] = $value;
            if ($Class == 'N') {
                $numbers .= "{$value}|";
            }
        }
        #--- Add the rank.
        $rowCtr++;
        $rank = isset($prevNumbers) && $numbers == $prevNumbers ? '' : $rowCtr;
        ###  $rank = $rowCtr;
        $prevNumbers = $numbers;
        #    $values[0] = $rank;
        #--- Add the filler column cell.
        $values[] = '';
        #--- Show the row.
        TableRow($values);
    }
    TableEnd();
    echo "</div>\n";
}