<?php

namespace Tanzsport;

use Model\Collection;

class FreiesturnierergebnisTabelle
{

    /**
     * @var Collection
     */
    private $mannschaften;
    /**
     * @var array
     */
    private $turniere;

    /**
     * @var array
     */
    public $kopfzeilen;
    /**
     * @var array
     */
    public $zeilen;

    /**
     * @var array
     */
    public $benutzteKennzeichen;

    /**
     * @var bool
     */
    public $benutztUnterVorbehalt = false;

    /**
     * @var bool
     */
    public $benutztAnnulliert = false;

    /**
     * @var bool
     */
    public $benutztDisqualifiziert = false;

    /**
     * @var bool
     */
    public $istGestartet = false;

    /**
     * @var bool
     */
    public $benutztGF = false;

    /**
     * @var bool
     */
    public $benutztKF = false;

    /**
     * @var bool
     */
    public $benutztZR = false;

    /**
     * @var bool
     */
    public $benutztVR = false;

    public function __construct(Collection $mannschaften, array $turniere)
    {
        $this->mannschaften = $mannschaften;
        $this->turniere = $turniere;
        $this->kopfzeilen = array();
        $this->zeilen = array();
        $this->benutzteKennzeichen = array();

        foreach ($this->mannschaften as $i => $mannschaft) {
            $row = new \stdClass();
            $row->pz = 0;
            $row->platz_skating = $mannschaft->platz > 0 ? intval($mannschaft->platz) : null;
            $row->skating = $row->platz_skating ? true : false;
            $row->startnr = $mannschaft->startnr;
            $row->verein = $mannschaft->verein_name;
            $row->team = $mannschaft->team_name;
            $row->aufstieg = $mannschaft->aufstieg;
            if ($mannschaft->aufstieg) {
                if (!in_array($mannschaft->aufstieg, $this->benutzteKennzeichen)) {
                    $this->benutzteKennzeichen[] = $mannschaft->aufstieg;
                }
            }
            $row->ergebnisse = array();
            $this->zeilen[$mannschaft->id] = $row;
        }

        foreach ($this->turniere as $i => $turnier) {
            $kopfzeile = new \stdClass();
            $kopfzeile->ort = $turnier->ort;
            $kopfzeile->datum = $turnier->datumAsObject;
            $kopfzeile->vorbehalt = $turnier->ergebnis_vorbehalt;
            if ($kopfzeile->vorbehalt) {
                $this->benutztUnterVorbehalt = true;
            }
            $kopfzeile->annulliert = $turnier->ergebnis_annulliert;
            if ($kopfzeile->annulliert) {
                $this->benutztAnnulliert = true;
            }
            $this->kopfzeilen[] = $kopfzeile;

            if ($turnier->ergebnis_published && !$turnier->ergebnis_annulliert) {
                $this->istGestartet = true;
                $ergebnis = deserialize($turnier->ergebnis, true);
                foreach ($ergebnis as $j => $ergebnisFuerMannschaft) {
                    $zeile = $this->findMannschaftRow($ergebnisFuerMannschaft['mannschaft']);
                    if ($zeile) {
                        $ergebnisFuerZeile = new \stdClass();
                        $ergebnisFuerZeile->pz = $ergebnisFuerMannschaft['pz'];
                        $ergebnisFuerZeile->runde = $ergebnisFuerMannschaft['runde'];
                        if (in_array($ergebnisFuerZeile->runde, array(Ergebnisarchiv::RUNDE_GF, Ergebnisarchiv::RUNDE_KF))) {
                            $ergebnisFuerZeile->wertung = $ergebnisFuerMannschaft['wertung'];
                        }
                        if ($ergebnisFuerMannschaft['disqualifiziert']) {
                            $ergebnisFuerZeile->disqualifiziert = true;
                            $this->benutztDisqualifiziert = true;
                        }
                        $ergebnisFuerZeile->annulliert = $turnier->ergebnis_annulliert;
                        if (!$turnier->ergebnis_annulliert) {
                            $zeile->pz += floatval($ergebnisFuerMannschaft['pz']);
                        }
                        $zeile->ergebnisse[] = $ergebnisFuerZeile;
                        if ($ergebnisFuerZeile->runde == Ergebnisarchiv::RUNDE_GF) {
                            $this->benutztGF = true;
                        }
                        if ($ergebnisFuerZeile->runde == Ergebnisarchiv::RUNDE_KF) {
                            $this->benutztKF = true;
                        }
                        if ($ergebnisFuerZeile->runde == Ergebnisarchiv::RUNDE_ZR) {
                            $this->benutztZR = true;
                        }
                        if ($ergebnisFuerZeile->runde == Ergebnisarchiv::RUNDE_VR) {
                            $this->benutztVR = true;
                        }
                    }
                }
            } else {
                foreach ($this->zeilen as $zeile) {
                    $zeile->ergebnisse[] = false;
                }
            }
        }

        foreach ($this->zeilen as $i => $zeile) {
            if ($zeile) {
                $mannschaftenPlatziert = $this->countPzLowerThan($zeile->pz);
                $zeile->platz = $mannschaftenPlatziert + 1;
                if ($zeile->platz_skating === null) {
                    $zeile->platz_skating = $zeile->platz;
                }
            }
        }
        uasort($this->zeilen, array($this, 'sortRows'));

    }

    public function zeigeLegende()
    {
        return $this->benutztDisqualifiziert || $this->benutztUnterVorbehalt || $this->benutztAnnulliert || $this->benutztGF || $this->benutztKF || $this->benutztZR || $this->benutztVR;
    }

    private function countPzLowerThan($pz)
    {
        $count = 0;
        foreach ($this->zeilen as $i => $zeile) {
            if ($zeile && $zeile->pz < $pz) {
                $count++;
            }
        }
        return $count;
    }

    private function findMannschaftRow($mannschaftId)
    {
        foreach ($this->zeilen as $id => $row) {
            if ($mannschaftId == $id) {
                return $row;
            }
        }
    }

    public function sortRows($a, $b)
    {
        if ($a->platz_skating == $b->platz_skating) {
            return $a->starnr < $b->startnr ? -1 : 1;
        } else {
            return $a->platz_skating < $b->platz_skating ? -1 : 1;
        }
    }
}
