<?php
/**
 * Arquivo de declaração da classe TelaDAO.
 */
class TelaDAO
{
    private $conexao;

    /**
     * Método construtor.
     */
    public function __construct()
    {
        $this->conexao = Conexao::getInstancia();
    }

    /**
     * Método para retornar a quantidade de telas, conforme condição informada.
     *
     * @param  string $condicao
     * @param  array  $parametros
     * @return string
     */
    public function contador($condicao = '', $parametros = array())
    {
        $condicao = Util::verificaCampo($condicao, 'AND');

        $txtSql = "SELECT count(id) as quantidade FROM cp_tela WHERE excluido IS NULL $condicao";

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $this->conexao->setParametros($sql, $parametros);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $resultado = $sql->fetchColumn();
        $sql->closeCursor();

        return (int) $resultado;
    }

    /**
     * Método para retornar o ultimo id.
     *
     * @return string
     */
    public function ultimoId()
    {
        $txtSql = 'SELECT max(id) as max FROM cp_tela';

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $resultado = $sql->fetchColumn();
        $sql->closeCursor();

        return (int) $resultado;
    }

    /**
     * Método para retornar a última ordem.
     *
     * @return integer
     */
    public function ultimaOrdem()
    {
        $txtSql = 'SELECT MAX(ordem) AS max FROM cp_tela WHERE excluido IS NULL';

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $resultado = $sql->fetchColumn();
        $sql->closeCursor();

        return (int) $resultado;
    }

    /**
     * Método para inserir.
     *
     * @param  Tela   $obj
     */
    public function inserir(Tela $obj)
    {
        $ordem = self::ultimaOrdem() + 1;

        $txtSql = 'INSERT INTO cp_tela (nome, slug, ordem) VALUES (:nome, :slug, :ordem)';

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $sql->bindValue(':nome', $obj->nome, PDO::PARAM_STR);
            $sql->bindValue(':slug', $obj->slug, PDO::PARAM_STR);
            $sql->bindValue(':ordem', $ordem, PDO::PARAM_STR);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $lastId = $sql->rowCount() > 0 ? (int) $this->conexao->getConexao()->lastInsertId() : null;
        $sql->closeCursor();

        $objPerfil = Perfil::listar('id > 1', array());
        if (count($objPerfil) > 0) {
            foreach ($objPerfil as $perfil) {
                $inserePermissao = Permissao::inserePerfilTela($perfil->id, $lastId);
            }
        }

        return $lastId;
    }

    /**
     * Editar dados.
     *
     * @param  Tela   $obj
     */
    public function editar(Tela $obj)
    {
        $txtSql = 'UPDATE cp_tela SET nome = :nome, slug = :slug WHERE id = :id';

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $sql->bindValue(':nome', $obj->nome, PDO::PARAM_STR);
            $sql->bindValue(':slug', $obj->slug, PDO::PARAM_STR);
            $sql->bindValue(':id', $obj->id, PDO::PARAM_INT);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $sql->closeCursor();
    }

    /**
     * Método para excluir.
     *
     * @param  int $id
     */
    public function excluir($id = 0)
    {
        $txtSql = 'UPDATE cp_tela SET excluido = now() WHERE id = :id';

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $sql->bindValue(':id', $id, PDO::PARAM_INT);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $resultado = $sql->rowCount() > 0 ? true : false;
        $sql->closeCursor();

        return $resultado;
    }

    /**
     * Método para listar os objetos.
     *
     * @param  string $condicao
     * @param  array  $parametros
     * @param  string $order
     * @param  string $limit
     * @param  string $offset
     */
    public function listar($condicao = '', $parametros = array(), $order = '', $limit = '', $offset = '')
    {
        $condicao = Util::verificaCampo($condicao, 'AND');
        $order = Util::verificaCampo($order, 'ORDER BY');
        $limit = Util::verificaCampo($limit, 'LIMIT');
        $offset = Util::verificaCampo($offset, 'OFFSET');

        $txtSql = "SELECT id, nome, slug, ordem, exibir_menu FROM cp_tela WHERE ((excluido IS NULL) OR (excluido = 0)) $condicao $order $limit $offset";

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $this->conexao->setParametros($sql, $parametros);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $resultado = $sql->fetchAll(PDO::FETCH_ASSOC);
        $sql->closeCursor();

        if (!$resultado) {
            return null;
        }

        foreach ($resultado as $res) {
            $arrObjeto[] = $this->classObject($res);
        }

        return $arrObjeto;
    }

    /**
     * Método para buscar.
     *
     * @param  string $valor
     * @param  string $campo
     * @return object
     */
    public function buscar($valor = '', $campo = 'id')
    {
        $txtSql = "SELECT * FROM cp_tela WHERE {$campo} = :valor AND ((excluido IS NULL) OR (excluido = 0))";

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $sql->bindValue(':valor', $valor, PDO::PARAM_STR);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $resultado = $sql->fetch(PDO::FETCH_ASSOC);
        $sql->closeCursor();

        if (!$resultado) {
            return null;
        }

        return $this->classObject($resultado);
    }

    /**
     * Método para mudar o status.
     *
     * @param  int $id
     */
    public function mudaStatus($id = 0)
    {
        $txtSql = 'SELECT exibir_menu FROM cp_tela WHERE id = :id;
                UPDATE cp_tela SET exibir_menu = (exibir_menu ^ 1) WHERE id = :id;';

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $sql->bindValue(':id', $id, PDO::PARAM_INT);
            $sql->execute();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }

        $resultado = $sql->fetchColumn();
        $sql->closeCursor();

        return (int) !$resultado;
    }

    /**
     * Método para alterar a ordem.
     *
     * @param  int $id
     * @param  int $ordem
     */
    public function mudaOrdem($id = 0, $ordem = 0)
    {
        $txtSql = 'UPDATE cp_tela SET ordem = :ordem WHERE id = :id';

        try {
            $sql = $this->conexao->getConexao()->prepare($txtSql);
            $sql->bindValue(':ordem', $ordem, PDO::PARAM_INT);
            $sql->bindValue(':id', $id, PDO::PARAM_INT);
            $sql->execute();
            $sql->closeCursor();
        } catch (PDOException $ex) {
            throw new BancoExcecao($ex->getMessage(), $txtSql, __FILE__, __CLASS__, __METHOD__, __LINE__);
        }
    }

    /**
     * Objeto da classe.
     *
     * @param  array  $resultado
     * @return object
     */
    private function classObject($resultado = array())
    {
        $obj = null;
        $obj = new Tela();
        isset($resultado['id']) ? $obj->id = $resultado['id'] : '';
        isset($resultado['nome']) ? $obj->nome = $resultado['nome'] : '';
        isset($resultado['slug']) ? $obj->slug = $resultado['slug'] : '';
        isset($resultado['ordem']) ? $obj->ordem = $resultado['ordem'] : '';
        isset($resultado['exibir_menu']) ? $obj->exibirMenu = $resultado['exibir_menu'] : '';

        return $obj;
    }
}
