<?php
/**
 * Functions for Permissions Role Database Table
 *
 * @package    Trainingssystem_Plugin
 * @subpackage Trainingssystem_Plugin/includes
 * @author     Max Sternitzke
 */
class Trainingssystem_Plugin_Database_Permission_Role_Daoimple implements Trainingssystem_Plugin_Database_Permission_Role_Dao {

    public static $dbprefix = TRAININGSSYSTEM_PLUGIN_DB_PERMISSION_ROLE;

    public function __construct(){
        $this->iniDB();
    }

    public function iniDB(){
        global $wpdb;

        $table_name = $wpdb->prefix . self::$dbprefix;

        $charset_collate = $wpdb->get_charset_collate();

        $tableversionsstr =[
            "CREATE TABLE IF NOT EXISTS $table_name (
                `ID` varchar(128) NOT NULL,
                `title` varchar(256) NOT NULL,
                `description` text NOT NULL,
                `priority` int(20) NOT NULL DEFAULT 0,
                PRIMARY KEY (`ID`)
              )$charset_collate;"
        ];
        Trainingssystem_Plugin_Database_Coach_impl::updateDBTable(self::$dbprefix,$table_name, $tableversionsstr);
    }

    /**
     * database updating beim plugin update
     *
     * @since    1.0.0
     */
	public function updating(){

    }

    /**
     * Fügt eine neue Rolle in die Datenbank ein
     * 
     * @param id
     * @param name
     * @param description
     * @param prio
     * 
     * @return boolean success
     */
    public function insertRole($id, $title, $description, $prio = null) {
        global $wpdb;
        $table_name_data = $wpdb->prefix . self::$dbprefix;
        if($prio == null) {
            $prio = $this->getNextPrio();
        }

        $sql = $wpdb->insert($table_name_data,
                                array(
                                    "ID" => $id,
                                    "title" => $title,
                                    "description" => $description,
                                    "priority" => $prio,
                                ),
                                array("%s", "%s", "%s", "%d")
                            );
        return $sql !== false;
    }

    /**
     * Fügt eine neue Rolle aus einem Trainingssystem_Plugin_Database_Permission_Role-Objekt in die Datenbank ein
     * 
     * @param Trainingssystem_Plugin_Database_Permission_Role Rolle
     * 
     * @return boolean success
     */
    public function insertRoleObject(Trainingssystem_Plugin_Database_Permission_Role $role) {
        return $this->insertRole($role->getId(), $role->getTitle(), $role->getDescription(), null);
    }

    /**
     * Gibt alle Rollen als Array von Trainingssystem_Plugin_Database_Permission_Role Objekten zurück
     * 
     * @return Array
     */
    public function getAllRoles() {
        global $wpdb;
        $table_name = $wpdb->prefix . self::$dbprefix;

        $data = $wpdb->get_results("SELECT ID, title, description, priority FROM $table_name ORDER BY priority, title ASC", OBJECT);
        $result = [];
        $i = 0;

        if($data != null) {
            foreach ($data as $row){

                $result[$i] = new Trainingssystem_Plugin_Database_Permission_Role($row->ID, $row->title, $row->description, $row->priority);
                $result[$i]->setPermissions(Trainingssystem_Plugin_Database::getInstance()->PermissionRole2Function->getPermissions($row->ID));
                $i++;
            }
        }
        return $result;
    }

    /**
     * Gibt alle Rollen als Array mit Key ID und Value Titel zurück
     * 
     * @return Array[ID] = Titel
     */
    public function getIdTitleRoles() {
        $allroles = $this->getAllRoles();

        $ret = array();
        foreach($allroles as $role) {
            $ret[$role->getId()] = $role->getTitle();
        }

        return $ret;
    }

    /**
     * Löscht eine Rolle und die zugehörigen Funktion-Role-Verbindungen aus der Datenbank
     * 
     * @param String role_id
     * 
     * @return boolean success
     */
    public function deleteRole($role_id) {
        global $wpdb;

        if(Trainingssystem_Plugin_Database::getInstance()->PermissionRole2Function->deleteByRole($role_id)) {
            
            $table_name = $wpdb->prefix . self::$dbprefix;
    
            $sql = $wpdb->prepare("DELETE FROM $table_name WHERE ID = %s", $role_id);
    
            return $wpdb->query($sql) !== false;
        }
        return false;
    }

    /**
     * Verschiebt die Priorität der Rolle role_id nach links oder rechts
     * 
     * @param String role_id
     * @param String priority_direction left (priority up, lower number) or right (priority down, higher number)
     * 
     * @return boolean success
     */
    public function updatePriority($role_id, $priority_direction) {
        

        $allroles = $this->getAllRoles();
        $index = -1;

        for($i = 0; $i < count($allroles); $i++) {

            if(strcmp($allroles[$i]->getId(), $role_id) === 0) {
                $index = $i;
                break;
            }
        }

        if($index == -1) {
            return false;
        }

        if($priority_direction == "left" && $index > 0 && $index < count($allroles)) {

            if(!$this->savePriority($allroles[$index-1]->getId(), $allroles[$index-1]->getPriority()+1)) {
                return false;
            }
            if(!$this->savePriority($allroles[$index]->getId(), $allroles[$index]->getPriority()-1)) {
                return false;
            }

        } else if($priority_direction == "right" && $index >= 0 && $index < count($allroles)-1) {

            if(!$this->savePriority($allroles[$index+1]->getId(), $allroles[$index+1]->getPriority()-1)) {
                return false;
            }
            if(!$this->savePriority($allroles[$index]->getId(), $allroles[$index]->getPriority()+1)) {
                return false;
            }
        }
        return true;
    }

    /**
     * Aktualisiert Titel und Beschreibung einer Rolle
     * 
     * @param String role_id
     * @param String role_title
     * @param String role_desc
     * 
     * @return boolean success
     */
    public function updateRole($role_id, $role_title, $role_desc) {
        global $wpdb;
        $table_name = $wpdb->prefix . self::$dbprefix;

        $sql = $wpdb->update($table_name,
            array(
                "title" => $role_title,
                "description" => $role_desc
            ),
            array(
                "ID" => $role_id
            ),
            array(
                "%s", "%s"
            ),
            array(
                "%s"
            )
        );

        return $sql !== false;
    }

    /**
     * Aktualisiert Titel und Beschreibung einer Rolle
     * 
     * @param Trainingssystem_Plugin_Database_Permission_Role Rolle
     * 
     * @return boolean success
     */
    public function updateFunctionObject(Trainingssystem_Plugin_Database_Permission_Role $role) {
        return $this->updateRole($role->getId(), $role->getTitle(), $role->getDescription());
    }

    /**
     * Speichert die Priorität einer vorhandenen Rolle in der Datenbank ab
     * 
     * @param String role_id
     * @param Integer priority
     * 
     * @return boolean success
     */
    private function savePriority($role_id, $priority) {
        global $wpdb;
        $table_name = $wpdb->prefix . self::$dbprefix;

        $sql = $wpdb->prepare("UPDATE $table_name SET priority = %d WHERE ID = %s", $priority, $role_id);

        return $wpdb->query($sql) !== false;
    }

    /**
     * Gibt die nächste Priorität zurück an dem die Rolle eingefügt werden kann
     * 
     * @return maxprio
     */
    private function getNextPrio() {
        global $wpdb;
        $table_name = $wpdb->prefix . self::$dbprefix;

        $prio = $wpdb->get_var("SELECT MAX(priority) as maxprio FROM $table_name");
        if($prio != null) {
            return $prio+1;
        }
        return 0;
    }

    /**
     * Clears the table
     * 
     * @return boolean success
     */
    public function clearTable() {
        global $wpdb;
        $table_name = $wpdb->prefix . self::$dbprefix;

        $sql = "DELETE FROM $table_name";

        return $wpdb->query($sql) !== false;
    }
}
