<?php #lib/20_routes.php

namespace Links;

abstract class Link {
	protected static $instances = [];
	protected $leftIndex = [];
	protected $rightIndex = [];
	
	public static function Get() {
		$class = get_called_class();
		if (!isset($instances[$class])) {
			self::$instances[$class] = new $class();
		}
		return self::$instances[$class];
	}
	
	private function __construct() {}
	
	public function Table() {return $this->names["table"];}
	public function Short() {return $this->names["short"];}
	public function TableWithShort() {return $this->names["table"]." ".$this->names["short"];}
	public function OtherResourceClass($callerClass) {
		$callFromRight = $callerClass=="Resources\\".$this->definitions["right"]["resourceClass"];
		return $this->definitions[$callFromRight ? "left" : "right"]["resourceClass"];
	}
	
	public function Refs($id, $from, $callerList) {
		if ($from==$this->definitions["right"]["ident"]) {
			// We come from right
			if (!isset($this->rightIndex[$id])) {
				$this->load("left", $id, $this->rightIndex, $callerList);
			}
			return $this->rightIndex[$id];
		} else {
			// We come from left
			if (!isset($this->leftIndex[$id])) {
				$this->load("right", $id, $this->leftIndex, $callerList);
			}
			return $this->leftIndex[$id];
	} }
	
	protected function load($to, $id, &$index, $callerList) {
		$index[$id] = [];
		$from = "left" == $to ? "right" : "left";
		$fromField = $this->definitions[$from]["ident"];
		$toField = $this->definitions[$to]["ident"];
		$toClass = "\\Resources\\".$this->definitions[$to]["resourceClass"];
		
		$qry = "SELECT ".$toField." FROM ".$this->Table()." WHERE ".$fromField." = ?";
		
		if ($stmt = \DB::Get()->prepare($qry)) {
		  if (!is_null($id)) {
				$stmt->bind_param("s", $id);
			}
      if ($stmt->execute()) {
      	$res = $stmt->get_result();
      	while ($row = $res->fetch_assoc()) {
	      	$index[$id][] = $toClass::Get()->Ref($row[$toField], $callerList);
    		}
    		return;
    } }
    \Response::Get()->DbError();
	}
	
	public function Unset($leftid, $rightid) {
		$qry = "DELETE FROM ".$this->Table()." WHERE ".$this->definitions["left"]["ident"]." = ? AND ".$this->definitions["right"]["ident"]." = ?";
		if ($stmt = \DB::Get()->prepare($qry)) {
			$stmt->bind_param("ss", $leftid, $rightid);
      if ($stmt->execute()) {
        if (1==$stmt->affected_rows) {
          return true;
        } else if (0==$stmt->affected_rows) {
        	\Response::Get()->Message("Fehler: Es wurde nichts entfernt!");
        } else {
        	\Response::Get()->Message("Fehler: Es wurden mehrere Einträge entfernt!");
    } } }
    \Response::Get()->DbError();
    return false;
	}
	
	public function Set($leftid, $rightid) {
		$qry = "INSERT INTO ".$this->Table()." (".$this->definitions["left"]["ident"].",".$this->definitions["right"]["ident"].") VALUES (?, ?)";
		if ($stmt = \DB::Get()->prepare($qry)) {
     	$stmt->bind_param("ss", $leftid, $rightid);
      if ($stmt->execute()) {
        return true;
    } }
    \Response::Get()->DbError();
    return false;
  }
}
