#!/usr/bin/perl

use strict;
use warnings;

use YAML qw/LoadFile DumpFile/;

use Games::Tournament::Swiss::Config;

my $swiss = Games::Tournament::Swiss::Config->new;

my $league = LoadFile "./league.yaml";
die 'round.yaml already exists' if -e 'round.yaml';
my $roles = $league->{roles} || [qw/Black White/];
my $scores = $league->{scores} ||
	{ win => 1, loss => 0, draw => 0.5, absent => 0, bye => 1 };
my $firstRound = $league->{firstround} || 1;
my $algorithm = $league->{algorithm} || 'Games::Tournament::Swiss::Procedure::FIDE';

my $firstround = $swiss->frisk($firstRound);
$scores = $swiss->frisk($scores);
$roles = $swiss->frisk($roles);
$algorithm = $swiss->frisk($algorithm);

$Games::Tournament::Swiss::Config::firstround = $firstround;
%Games::Tournament::Swiss::Config::scores = %$scores;
@Games::Tournament::Swiss::Config::roles = @$roles;
$Games::Tournament::Swiss::Config::algorithm = $algorithm;

require Games::Tournament::Swiss;
require Games::Tournament::Contestant::Swiss;
require Games::Tournament::Card;

my $tourney;
my $table;
my $players;
my $games;

my @rounds;
for my $file ( glob ('./*') )
{
    push @rounds, $1 if -d $file and $file =~ m/\/(\d+)$/ and
							    glob( "./$file/*" );
}
my $timethrough;
for my $round ( @rounds )
{
    next unless glob("./$round/*");
    $tourney = LoadFile "./$round/tourney.yaml";
    $players = LoadFile qq{./$round/player.yaml};
    $games   = LoadFile "./$round/matches.yaml";
    if ( $tourney->unmarkedCards(@$games) ) {
        my $results = LoadFile("./scores/$round.yaml");
        for my $game (@$games) {
            my %result;
            my $total;
            my @contestants = map { $_->id } values %{ $game->{contestants} };
            for my $role ( @$roles, 'Bye' ) {
                my $player = $game->contestants->{$role};
                next
                  unless $player
                  and $player->isa('Games::Tournament::Contestant');
                my $result = $results->{ $player->id };
                $total += $result;
                $result{$role} =
                    $role eq 'Bye' ? $player
                  : $result == $scores->{win}    ? 'Win'
                  : $result == $scores->{draw}   ? "Draw"
                  : $result == $scores->{loss}   ? "Loss"
                  : $result == $scores->{absent} ? 'Absent'
                  : "Error";
            }
            die
"total scores in round $round game with players @contestants not $total"
              if $total != $scores->{win} + $scores->{loss};
            $game->result( \%result );
        }
    }
    $tourney->collectCards(@$games);
    for my $player (@$players) {
        my $id = $player->id;
        $table->{$id}->{id} = $id;
        my $game     = $player->findCard(@$games);
        my $opponent = $player->myOpponent($game)
          || Games::Tournament::Contestant->new( name => "Bye", id => "0" );
        my $result = $game->myResult($player);
        if ( $result eq 'Bye' ) { $result = 'W'; }
        else { $result =~ s/^(.).*$/$1/; }

        # my $results = $table->{$id}->{results} or die
        # "Player ${id}'s $table->{$id}->{results} result in round $round?";
        my @results = $round == 1 ? () : @{ $table->{$id}->{results} };
        push @results, $opponent->id . ":" . $result;

        # $results .= $opponent->id . ":" . $result . ' ';
        $table->{$id}->{results} = \@results;
    }
    $timethrough++;
}

my $playerN = 0;
my $allRoundPlayers = $tourney->entrants;
my @rankedplayers = $tourney->rank(@$allRoundPlayers);

local $" = "     ";
print "
		Round @{[$#rounds+1]} Crosstable
-------------------------------------------------------------------------
Rank No  Name       Rating Total @rounds
";
local $" = " ";

for my $player ( @rankedplayers )
{
	my $id = $player->id;
	my $place = ++$playerN;
	my $results = $table->{$id}->{results};
	# my $allRoundPlayer = $tourney->ided($id);
	# my $score = $allRoundPlayer->score;
	my @results = ($player->id, $player->name, $player->rating, $player->score) or die "$player->{id}'s results?";
	no warnings;
	format STDOUT =
@<< @<< @<<<<<<<<<<< @<<<< @<<< @<<<< @<<<< @<<<< @<<<< @<<<< @<<<< @<<<< @<<<<
$place, $player->id, $player->name, $player->rating, $player->score, @$results
.
	write;
	use warnings;
}

__END__

=head1 NAME

crosstable - Mark cards with results of the matches

=head1 SYNOPSIS

markCards

--help            This help message

--man            A man page

=head1 DESCRIPTION

B<markCards> tallies results from $scores/$round.yaml, marking the Games::Tournament::Card cards from matches.yaml with them. It then serializes the cards back into matches.yaml. The unmarked cards are preserved in matches.yaml.bak.

The configuration file, ../league.yaml, holds the value of $scores, and $round is the directory name in which the command is run and where matches.yaml and player.yaml, a file of serialized player objects, exist. (The name must be a round number.)

=cut

# vim: set ts=8 sts=4 sw=4 noet:
