<?php

    require_once($path["entity"] . "Entity.php");
    require_once($path["entity"] . "K_Unit.php");
    require_once($path["entity"] . "Unit.php");

    /**
     * Extension of {@see K_Unit} that also stores information about owned
     * monsters.
     */
    class Monster_Fusion extends K_Unit{

        /**
         * All owned {@see Monster}s of this type.
         */
        public $owned = [];

        /**
         * Constructor.
         *
         * Searches the database and retrieves the information about the
         * fusion, populating it and it's items.
         *
         * @param SQLite3 $db Connection to the database.
         * @param int $id Monster id.
         */
        public function __construct($db, $id, $uid){
            global $path;
            parent::__construct($db, $id, false);
            $s = "
              SELECT unit.id AS id
              FROM
                unit,
                k_unit
              WHERE
                k_unit.id = unit.unit AND
                unit.uid = '$uid' AND
                (
                  k_unit.id = $id OR
                  k_unit.awakens_from = $id OR
                  k_unit.awakens_to = $id
                );
            ";
            $q = $this->db->query($s);
            while ($r = $q->fetchArray(SQLITE3_ASSOC)){
                array_push($this->owned, new Unit($this->db, $r["id"], false));
            }
        }
    }


    /**
     * Fusion.
     *
     * Represents an object from the table 'fusion'.
     */
    class Fusion extends Entity{

        /**
         * {@see K_Unit} to fuse.
         */
        public $product;

        /**
         * {@see K_Unit} to fuse (awakened).
         */
        public $product_awaken;

        /**
         * {@see K_Unit} to fuse (awakened).
         */
        public $product_unawaken;

        /**
         * Fusions required to create ingredients.
         */
        public $fusion = [];

        /**
         * List of unfuseable {@see K_Unit} material.
         */
        public $ingredient = [];

        /**
         * List of unfuseable {@see K_Unit} material (awakened).
         */
        public $ingredient_unawaken = [];

        /**
         * Stars of the monster to fuse.
         */
        public $stars;

        /**
         * Fusion cost.
         */
        public $cost;

        /**
         * Constructor.
         *
         * Searches the database and retrieves the information about the
         * fusion, populating it and it's items.
         *
         * @param SQLite3 $db Connection to the database.
         * @param int $id Product monster id.
         * @param int $uid User id (optional)
         */
        public function __construct($db, $id, $uid = null){
            global $path;
            parent::__construct($db);
            $s = "
              SELECT DISTINCT
                product,
                stars,
                cost
              FROM k_fusion
              WHERE
                product = $id OR
                product = (SELECT awakens_to FROM k_unit WHERE id = $id) OR
                product = (SELECT awakens_from FROM k_unit WHERE id = $id);
            ";
            $q = $this->db->query($s);
            $r = $q->fetchArray(SQLITE3_ASSOC);
            $this->product = new Monster_Fusion($this->db, $r["product"], $uid);
            $this->product_awaken = new Monster_Fusion($this->db, $this->product->awakens_to, $uid);
            $this->stars = $r["stars"];
            $this->cost = $r["cost"];
            $s_f = "
              SELECT DISTINCT ingredient
              FROM k_fusion
              WHERE
                product = " . $this->product->id . " AND
                ingredient IN (
                  SELECT DISTINCT k_unit.id
                  FROM
                    k_fusion,
                    k_unit
                  WHERE
                    k_fusion.product = k_unit.awakens_from OR
                    k_fusion.product = k_unit.awakens_to OR
                    k_fusion.product = k_unit.id
                );
            ";
            $q_f = $this->db->query($s_f);
            while ($r_f = $q_f->fetchArray(SQLITE3_ASSOC)){
                array_push($this->fusion, new Fusion($this->db, $r_f["ingredient"], $uid));
            }
            $s_m =
              "SELECT  " .
              "  id, " .
              "  awakens_from " .
              "FROM k_unit " .
              "WHERE id IN ( " .
              "  SELECT DISTINCT " .
              "    ingredient " .
              "  FROM k_fusion " .
              "  WHERE  " .
              "    product = " . $this->product->id . " AND " .
              "    ingredient NOT IN (  " .
              "      SELECT DISTINCT k_unit.id  " .
              "      FROM  " .
              "        k_fusion,  " .
              "        k_unit  " .
              "      WHERE " .
              "        k_fusion.product = k_unit.awakens_from OR " .
              "        k_fusion.product = k_unit.awakens_to OR " .
              "        k_fusion.product = k_unit.id " .
              "    ) " .
              "  ); ";
            $q_m = $this->db->query($s_m);
            while ($r_m = $q_m->fetchArray(SQLITE3_ASSOC)){
                $m = new Monster_Fusion($this->db, $r_m["id"], $uid);
                array_push($this->ingredient, $m);
                $m = new Monster_Fusion($this->db, $r_m["awakens_from"], $uid);
                $m->load_essences();
                array_push($this->ingredient_unawaken, $m);
            }
        }
    }
?>
