#!/usr/bin/perl

# Copyright (C) 2009 John J. Chew, III <jjchew@math.utoronto.ca>
# All Rights Reserved

package TSH::Command::EXPORTRATINGS;

use strict;
use warnings;

use TSH::Log;
use TSH::Utility;

our (@ISA) = qw(TSH::Command);

=pod

=head1 NAME

TSH::Command::EXPORTRATINGS - implement the C<tsh> EXPORTRATINGS command

=head1 SYNOPSIS

  my $command = new TSH::Command::EXPORTRATINGS;
  my $argsp = $command->ArgumentTypes();
  my $helptext = $command->Help();
  my (@names) = $command->Names();
  $command->Run($tournament, @parsed_arguments);
  
=head1 ABSTRACT

TSH::Command::EXPORTRATINGS is a subclass of TSH::Command.

=cut

=head1 DESCRIPTION

=over 4

=cut

sub initialise ($$$$);
sub new ($);
sub Run ($$@);

=item $parserp->initialise()

Used internally to (re)initialise the object.

=cut

sub initialise ($$$$) {
  my $this = shift;
  my $path = shift;
  my $namesp = shift;
  my $argtypesp = shift;

  $this->{'help'} = <<'EOF';
Use this command to export a new rating list including the results of this event.
EOF
  $this->{'names'} = [qw(exportratings)];
  $this->{'argtypes'} = [qw()];
# print "names=@$namesp argtypes=@$argtypesp\n";

  return $this;
  }

sub new ($) { return TSH::Utility::new(@_); }

=item $command->Run($tournament, @parsed_args)

Should run the command in the context of the given
tournament with the specified parsed arguments.

=cut

sub Run ($$@) { 
  my $this = shift;
  my $tournament = $this->{'x_tournament'} = shift;
  my $processor = $this->Processor();
  my $config = $tournament->Config();
  my (@divisions) = $tournament->Divisions();

  $tournament->LoadRatings() or return 0;
  $this->Processor()->Flush();
  unless ($config->Value('max_rounds')) {
    $tournament->TellUser('ecfgreq', 'max_rounds');
    return 0;
    }
  # store data that needs to be updated in the following hash
  my %new_data;
  for my $dp (@divisions) { 
    $dp->ComputeRatings($config->Value('max_rounds')-1);
    my $rating_list = $dp->RatingList();
    my $rating_system = $dp->RatingSystem();
    for my $p ($dp->Players()) { 
      my (@names) 
        = $rating_system->CanonicaliseName($rating_list, uc $p->Name());
      my (@ratings) = split(/\+/, $p->NewRating(-1));
      my $games = $p->GamesPlayed();
#     local($") = '!'; print "G:@names:@ratings:@games\n";
      my $rating_term_count = $rating_system->RatingTermCount();
      for my $i (0..$#names) {
	my $key = $names[$i];
	$key =~ s/,//;
	$new_data{$rating_list}{$key} = { 
	  'games' => $games,
	  'rating' => join('+', @ratings[$i*$rating_term_count..
	    ($i+1)*$rating_term_count-1]),
	  };
        }
      }
    }
  while (my ($rating_list, $rl_new_data) = each %new_data) {
    $this->UpdateRatingList($rating_list, $rl_new_data);
    }
  }

sub UpdateRatingList ($$$) {
  my $this = shift;
  my $rating_list = shift;
  my $rl_new_data = shift;

  my $processor = $this->Processor();
  my $tournament = $this->{'x_tournament'};
  my $config = $tournament->Config();

  my $ofh;
  my $ofn = $config->MakeLibPath("ratings/$rating_list/current.txt");
  my $nfh;
  my $nfn = $config->MakeLibPath("ratings/$rating_list/new.txt");
  if (!open $ofh, '<:encoding(isolatin1)', $ofn) {
    $tournament->TellUser('euseropen', $nfn, $!);
    next;
    }
  if (!open $nfh, '>:encoding(isolatin1)', $nfn) {
    $tournament->TellUser('euseropen', $nfn, $!);
    next;
    }
  my (@fields) = qw(name rating rank expiry games);
  while (<$ofh>) {
    chomp;
    if ($. == 1 && !/\d/) {
      @fields = split(/\t/);
      print $nfh "$_\n";
      next;
      }
    my %data;
    @data{@fields} = split(/\t/);
    $data{'name'} =~ s/,//;
    if (my $p = $rl_new_data->{uc $data{'name'}}) {
      $data{'rating'} = $p->{'rating'};
      $data{'games'} += $p->{'games'};
      print "OLD:$data{'name'}:$p->{'rating'}:$p->{'games'}\n";
      print $nfh join("\t", @data{@fields}), "\n";
      delete $rl_new_data->{uc $data{'name'}};
      }
    else {
      print $nfh "$_\n";
      }
    }
  for my $key (sort keys %$rl_new_data) {
    my $p = $rl_new_data->{$key};
#   warn $key;
    print "NEW:$key:$p->{'rating'}:$p->{'games'}\n";
    my (%data) = (
      'name' => $key,
      'rating' => $p->{'rating'},
      'rank' => 0,
      'expiry' => 0,
      'games' => $p->{'games'},
      );
    print $nfh join("\t", @data{@fields}), "\n";
    }
  close $nfh;
  close $ofh;
  $tournament->TellUser('iexratok', $nfn);
  }

=back

=cut

=head1 BUGS

None known.

=cut


1;

