<?php
require_once("Class/File/interface.php");

//Un object au sens technologie est définit par un tableau : array($branche, $tech);

class FileTechnologies extends FileCommun implements File
{
    public function objectInFile($object)
    {
        foreach ($this->files as $keyF => $file) {
            foreach ($file as $keyE => $element) {
                if ($element[0] == $object) {
                    return array($keyF, $keyE);
                }
            }
        }
        return false;
    }

    public function nbObjectInFile($branche, $tech = null)
    {
        $c = 0;
        foreach ($this->files as $file) {
            $c += count(array_keys($file, array($branche, $tech)));
        }
        return $c;
    }

    public function addObjet($branche, $tech, surface $planete)
    {
        //On vérifie que l'on ne dépasse pas la taille maximale de la file
        if (!$this->checkMaxSize($planete)) {
            throw new ExceptionHB(4, 1);
        }

        //On vérifie qu'il n'y ait pas une recherche de la même technologie
        if ($this->nbObjectInFile($branche, $tech) >= 1) {
            throw new ExceptionHB(4, 7);
        }

        //On vérifie que la technologie ne soit pas déjà développée
        if (dTechnologies::idToBit($tech) & $planete->technologies[$branche]) {
            throw new ExceptionHB(4, 7);
        }

        //Validation des conditions de construction
        if (!dTechnologies::needed(array($branche, $tech), $planete)) {
            throw new ExceptionHB(4, 2);
        }

        //On recherche le lieu ayant le moins de construction en cours
        $lieu = $this->findShorter();

        //On rafraîchit le temps de la file si aucun objet n'est en file d'attente
        $this->refreshTime($lieu);

        //On vérifie qu'il y ait assez de ressources sur la planète
        if ($planete->checkAndRetireRessources(dTechnologies::metal($branche, $tech, $planete), dTechnologies::cristal($branche, $tech, $planete), dTechnologies::hydrogene($branche, $tech, $planete), dTechnologies::credits($branche, $tech, $planete))) {
            $this->files[$lieu][] = array($branche, $tech);
            $planete->addModif("file_tech");
            return true;
        } else {
            throw new ExceptionHB(4, 4);
        }
    }

    public function addDemolition($object, $nombre = 1, surface $planete)
    {
        trigger_error("Pas de démolition possible pour les technologies");
    }

    public function delObjet($id, $nombre = 1, $lieu, surface $planete)
    {
        //Vérification de l'existance de l'objet en file d'attente
        if (empty($this->files[$lieu][$id])) {
            throw new ExceptionHB(4, 5);
        }

        //On récupère la branche et l'id de la technologie
        $branche = $this->files[$lieu][$id][0];
        $tech = $this->files[$lieu][$id][1];

        //On met à jour le temps si on vient d'annuler la première recherche en lice
        if ($tech == $this->findFirstKey($lieu)) {
            $this->times[$lieu] = time();
        }

        $planete->addModif("file_tech");

        //On redonne 70% des ressources au joueur si c'est la première construction dans la file d'attente
        if ($id == 0) {
            $planete->addRessources(dTechnologies::metal($branche, $tech, $planete)*0.7, dTechnologies::cristal($branche, $tech, $planete)*0.7, dTechnologies::hydrogene($branche, $tech, $planete)*0.7, dTechnologies::credits($branche, $tech, $planete)*0.7);
        } else {
            $planete->addRessources(dTechnologies::metal($branche, $tech, $planete), dTechnologies::cristal($branche, $tech, $planete), dTechnologies::hydrogene($branche, $tech, $planete), dTechnologies::credits($branche, $tech, $planete));
        }

        //Effacement de la file
        unset($this->files[$lieu][$id]);

        return true;
    }

    public function ready(surface $planete)
    {
        //On parcourt la liste des lieux de recherche
        foreach ($this->files as $keyF => $file) {
            //On vérifie qu'il y a bien des éléments dans cette file d'attente
            if (count($file) == 0) {
                continue;
            }

            //On parcourt la file
            foreach ($file as $keyE => $element) {
                $tempsEcoule = time() - $this->times[$keyF];

                $tempsNecessaire = dTechnologies::temps($element[0], $element[1], $planete);

                //Si le temps écoulé est suffisant
                if ($tempsEcoule >= $tempsNecessaire) {
                    //On ajoute un niveau au batiment
                    $planete->technologies[$element[0]] = $planete->technologies[$element[0]] | dTechnologies::idToBit($element[1]);

                    //On efface l'entrée de la file et on met à jour le temps de la file
                    unset($this->files[$keyF][$keyE]);
                    $this->times[$keyF] += $tempsNecessaire;

                    //On demande la mise à jour des champs modifiés
                    $planete->addModifUser(array("technologies", $element[0]));
                    $planete->addModif("file_tech");

                    //On ajoute les points
                    $planete->addPoints(dTechnologies::metal($element[0], $element[0], $planete), dTechnologies::cristal($element[0], $element[1], $planete), dTechnologies::hydrogene($element[0], $element[1], $planete), dTechnologies::credits($element[0], $element[1], $planete));
                }
                //Si le temps écoulé n'est pas suffisant pour ce batiment, on annule tous les suivants
                else {
                    break;
                }
            }
        }
    }


    public function printFile(surface $planete, $lieu = null)
    {
        $out = array();
        foreach ($this->files as $keyF => $file) {
            if (isset($lieu) && $lieu != $keyF) {
                continue;
            }

            $prems = true;
            foreach ($file as $keyE => $element) {
                $temps = dTechnologies::temps($element[0], $element[1], $planete);
                if ($prems) {
                    $temps -= time() - $this->times[$keyF];
                }
                $out[$keyF][$keyE] = array($element[0], $element[1], ceil($temps), $prems);

                $prems = false;
            }
        }
        return $out;
    }
}
