package Kostky::Server;
use strict;
use warnings;
use IO::Socket;

our $SKORE_VITEZE = 5; #počet bodů nutných k vítězství

#konstruktor
sub new {
    my($self) = @_;
    my $f = {};
    bless $f;

    my $hrac = IO::Socket::INET->new(
        Proto     => "tcp",
        LocalPort => 9006,
        LocalAddr => "localhost",
        Listen    => 2,
        Reuse     => 1
    ) or die "Nelze vytvorit socket! $!";

    $f->{"hrac"} = $hrac;
    $f->{"skore1"} = 0;
    $f->{"skore2"} = 0;

    return $f;
}

sub spust {
    my $self = shift;
    my $cislo_tahu = 0;
    my $vzdaleny;
    my($klient1, $klient2);
    my $vitez;
    my $porazeny;
    my $nick;
    my $pid;

    while(1){
        for(my $i=1; $i<=2; $i++){
            $vzdaleny = $self->{"hrac"}->accept();
            $vzdaleny->autoflush(1);
            print $vzdaleny "1\n";
            chomp($nick = <$vzdaleny>);
            do_logu("-", "$nick pripojen");
            $self->{"vzdaleny$i"} = $vzdaleny;
            $self->{"nick$i"} = $nick;
        }
        next unless $pid = fork;

        do_logu($pid, "V teto hre hraji ".$self->{"nick1"}." a ".$self->{"nick2"});

        #hlavni smyčka serveru - dokud není znám vítěz, nebude konec
        while(($vitez = $self->konec) == -1) {
            $cislo_tahu++;

            #rozhodneme kdo začne v tomto tahu
            if((rand(2)>1 ? 1 : 0)==0){
                ($self->{"vzdaleny1"}, $self->{"vzdaleny2"}, $self->{"nick1"}, $self->{"nick2"}) = ($self->{"vzdaleny2"}, $self->{"vzdaleny1"}, $self->{"nick2"}, $self->{"nick1"});
            }

            $klient1 = $self->{"vzdaleny1"};
            $klient2 = $self->{"vzdaleny2"};

            #oznámíme to hráčům
            print $klient1 "1\n";#hráč1 začíná
            print $klient2 "2\n";#hráč1 čeká

            do_logu($pid, "Cekame, az hodi ".$self->{"nick1"});
            my $hod = <$klient1>;
            my $vysledek_hodu1 = int(rand(6))+1;

            print $klient1 "$vysledek_hodu1\n";
            print $klient2 "$vysledek_hodu1\n";
            do_logu($pid, $self->{"nick1"}." hodil $vysledek_hodu1");


            do_logu($pid, "Cekame, az hodi ".$self->{"nick2"});
            $hod = <$klient2>;
            my $vysledek_hodu2 = int(rand(6))+1;

            print $klient2 "$vysledek_hodu2\n";
            print $klient1 "$vysledek_hodu2\n";
            do_logu($pid, $self->{"nick2"}." hodil $vysledek_hodu2");

            #aktualizujeme skore
            $self->{"skore1"}++ if $vysledek_hodu1>$vysledek_hodu2;
            $self->{"skore2"}++ if $vysledek_hodu1<$vysledek_hodu2;
    
            print $klient1 $self->{"nick1"}." vs. ".$self->{"nick2"}." ".$self->{"skore1"}."-".$self->{"skore2"}."\n";
            print $klient2 $self->{"nick1"}." vs. ".$self->{"nick2"}." ".$self->{"skore1"}."-".$self->{"skore2"}."\n";
            do_logu($pid, $self->{"nick1"}." vs. ".$self->{"nick2"}." ".$self->{"skore1"}."-".$self->{"skore2"});
        }
        #pošleme zprávu o vítězství nebo prohře
        $porazeny = $vitez==1?2:1;
        print {$self->{"vzdaleny$vitez"}} "-1\n";
        print {$self->{"vzdaleny$porazeny"}} "-2\n";
    }
    exit;
}

sub do_logu {
    my($pid, $zprava)=@_;
    my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
    print "$pid $hour:$min:$sec $zprava\n";
}

#určuje, zda je konec hry a jak hra skončila
sub konec {
    my($self) = @_;
    my $vitez;

    return 1 if $self->{"skore1"}==$SKORE_VITEZE;
    return 2 if $self->{"skore2"}==$SKORE_VITEZE;
    return -1; #neni vitez
}

1;
