package ScoreBoard;
use strict;
use Carp;

use IO::File;

################# Configuration part ###################
#This configuration will be used by all instances of the module.

my $points_per_kill = 1;
my $points_for_suicide = -1;

#Now the weapon translation hash
my %trans = ( "ak47" => "AK-47",
              "grenade" => "Granat",
              "deagle" => "Dessert Eagle",
              
            );

############## end of configuration part ###############

sub new {
  my $proto = shift;
  my $class = ref($proto) || $proto;
  my $self = {};
  bless ($self, $class);
  $self->_initialize(@_);
  return $self;
}

sub _initialize {
  my $self = shift;
  $self->{in_dir} = shift;
  $self->reset();
}

sub buildStats
{
  my($self, $handle) = @_;
 
  my($killer, $victim, $weapon);
  my($user, $time, $date);
  
  while($_ = <$handle>)
  {
    if( /: \"([^<]*)([^ ]*)\" killed \"([^<]*)([^ ]*)\" with ([^ ]*)\n/ and do 
      { $killer = $1; 
        $victim = $3;
        $weapon = $5;}    
      )
    {
      ${$self->{score}}{$killer} += $points_per_kill;
      ${$self->{weapon}}{$killer}->{$weapon}++;
      ${$self->{killed}}{$killer}->{$victim}++;
      ${$self->{killed_by}}{$victim}->{$killer}++;
    } elsif(/: \"([^<]*)([^ ]*)\" killed self with ([^ ]*)\n/ and do 
          { $killer = $1;
            $weapon = $3;
          }
      ) {
      ${$self->{score}}{$killer} += $points_per_kill;
      ${$self->{weapon}}{$killer}->{$weapon}++;
    } elsif( (/: \"([^<]*)([^ ]*)\" has entered the game/
                and do {
                         $user = $1;
                       }
              ) 
              ||
              (/: \"([^<]*)([^ ]*)\" changed name to \"([ ]*)([^<]*)([^ ]*)\"/
                and do {
                         $user = $4;
                       }                
              )
            )
    {
      if(!${$self->{score}}{$user})
      {
        ${$self->{score}}{$user} = 0;
      }
    }
  }
}

sub printKills
{
  my($self) = @_;
  
  print "Kills per user:\n";
  
  foreach my $user (keys %{$self->{score}})
  {
    print "\t$user\n";
    print map "$_: ${$self->{killed}}{$user}->{$_}\n", keys %{${$self->{killed}}{$user}};
  }
}

sub saveKills
{
  my($self, $dirname) = @_;
  
  my $FILE = new IO::File;

  mkdir $dirname, 0777;
  
  foreach my $user (keys %{$self->{score}})
  {
    open($FILE, ">$dirname/$user.kills") or die "Cannot open $dirname for writing";  
    print $FILE map "$_: ${$self->{killed}}{$user}->{$_}\n", keys %{${$self->{killed}}{$user}};
    close($FILE);
  }
}

sub reset
{
  my($self) = @_;
  %{$self->{score}} = ();
  %{$self->{weapon}} = ();
  @{$self->{order}} = ();
  $self->{sorted} = 0;
  %{$self->{killed}} = ();
  %{$self->{killed_by}} = ();
}

sub start
{
  my($self) = @_;

  my $dir = $self->{in_dir};
  
  opendir DIR, $dir;

  my @files = grep {/.log$/} readdir(DIR);
  @files = reverse @files;
  my $FILE = new IO::File;

  while($_ = pop(@files))
  {
    open($FILE, "$dir/$_") || die "Can't open log file";

    buildStats($self, $FILE);
    
    close $FILE;
  }
  
  closedir DIR;
}

sub printScores
{
  my($self) = @_;
  print "\n\nSCOREBOARD:\n";
  if($self->{sorted})
  {
    print map "$_: ${$self->{score}}{$_}\n", @{$self->{order}};
  } else {
    print map "$_: ${$self->{score}}{$_}\n", keys %{$self->{score}};
  }
}

sub saveScores
{
  my($self, $filename) = @_;

  my $SCORE = new IO::File;
  open($SCORE, ">$filename") or die "Cannot open $filename for writing";

  if($self->{sorted})
  {
    print $SCORE (map "$_: ${$self->{score}}{$_}\n", @{$self->{order}});
  } else {
    print $SCORE (map "$_: ${$self->{score}}{$_}\n", keys %{$self->{score}});
  }

  close $SCORE;
}

sub transWeapon
{
  my($weapon) = @_;
  my $return = $weapon;

  if($trans{$weapon})
  {
    $return = $trans{$weapon};
  }
  
  return $return;
}

sub printWeaponScores
{
  my($self) = @_;
  print "\nWeapon List:\n";
  foreach my $user (keys %{$self->{weapon}})
  {
    print "$user:\n";
    if(${$self->{weapon}}{$user}->{order}) 
    {
      print map "\t" . transWeapon($_) . ": ${$self->{weapon}}{$user}->{$_}\n", @{${$self->{weapon}}{$user}->{order}};
    } else {
      print map "\t" . transWeapon($_) . ": ${$self->{weapon}}{$user}->{$_}\n", keys %{${$self->{weapon}}{$user}};
    }
  }
}

sub saveWeaponScores
{
  my($self, $filename) = @_;
 
  my $FILE = new IO::File;
  
  open $FILE, ">$filename" or die "Cannot open $filename for writing";
  
  foreach my $user (keys %{$self->{weapon}})
  {
    print $FILE "\t$user:\n";
    if(${$self->{weapon}}{$user}->{order}) 
    {
      print $FILE map "" . transWeapon($_) . ":${$self->{weapon}}{$user}->{$_}\n", @{${$self->{weapon}}{$user}->{order}};
    } else {
      print $FILE map "" . transWeapon($_) . ":${$self->{weapon}}{$user}->{$_}\n", keys %{${$self->{weapon}}{$user}};
    }
  }
  
  close $FILE;
}

sub sortScores
{
  my($self) = @_;
  @{$self->{order}} = sort { ${$self->{score}}{$b} <=> ${$self->{score}}{$a} } keys %{$self->{score}};
  $self->{sorted} = 1;
}

sub sortWeaponScores
{
  my($self) = @_;
  foreach my $user (keys %{$self->{weapon}})
  {
    my @worder = ();
    @worder = sort { ${$self->{weapon}}{$user}->{$b} <=> ${$self->{weapon}}{$user}->{$a} } keys %{${$self->{weapon}}{$user}};
    ${$self->{weapon}} {$user}->{order} = \@worder;
  }  
}

1;