<?php
require_once(dirname(__FILE__).'/autoload.php');
protegeArquivo(basename(__FILE__));

abstract class banco{
    //propriedades
    public $servidor       = DBHOST;
    public $usuario        = DBUSER;
    public $senha          = DBPASS;
    public $nomebanco      = DBNAME;
    public $conexao        = NULL;
    public $dataset        = NULL;
    public $linhasafetadas = -1;
    public $saldi;
    
    public function saldo()
    {
         return $this->saldi;
    }
    public function credito($valor)
    {
        $this->saldi = $valor + 15;
    }
    
    //métodos
    public function __construct(){
        $this->conecta();
    }
    
    public function __destruct(){
        if($this->conexao != NULL):
            mysqli_close($this->conexao);
        endif;
    }
    
    public function conecta()
    {
        // Estabelece conexão com MySQLi
        $this->conexao = mysqli_connect($this->servidor, $this->usuario, $this->senha);
        if (!$this->conexao) {
            $this->trataerro(__FILE__, __FUNCTION__, mysqli_connect_errno(), mysqli_connect_error(), TRUE);
        }
        
        // Seleciona o banco de dados
        if (!mysqli_select_db($this->conexao, $this->nomebanco)) {
            $this->trataerro(__FILE__, __FUNCTION__, mysqli_errno($this->conexao), mysqli_error($this->conexao), TRUE);
        }
        
        // Configura charset UTF-8
        mysqli_query($this->conexao, "SET NAMES 'utf8'");
        mysqli_query($this->conexao, "SET character_set_connection=utf8");
        mysqli_query($this->conexao, "SET character_set_client=utf8");
        mysqli_query($this->conexao, "SET character_set_results=utf8");
    }
    
    public function inserir($objeto){
        $sql = "INSERT INTO ".$objeto->tabela." (";
        for($i=0; $i<count($objeto->campos_valores); $i++):
            $sql .= key($objeto->campos_valores);
            if($i < (count($objeto->campos_valores)-1)):
                $sql .= ", ";
            else:
                $sql .= ") ";
            endif;
            next($objeto->campos_valores);
        endfor;
        reset($objeto->campos_valores);
        $sql .= "VALUES (";
        for($i=0; $i<count($objeto->campos_valores); $i++):
            $sql .= is_numeric($objeto->campos_valores[key($objeto->campos_valores)]) ?
                $objeto->campos_valores[key($objeto->campos_valores)] :
                "'".$objeto->campos_valores[key($objeto->campos_valores)]."'";
            if($i < (count($objeto->campos_valores)-1)):
                $sql .= ", ";
            else:
                $sql .= ") ";
            endif;
            next($objeto->campos_valores);
        endfor;
        
        return $this->executaSQLID($sql);
    }
    
    public function inserirEspecial($objeto){
        $sql = $objeto->campos_valores;
        return $this->executaSQLID($sql);
    }
    
    public function grava_registro_com_retorno($objeto){
        $sql = $objeto;
        return $this->executaSQL($objeto);
    }
    
    public function atualizar($objeto){
        $sql = "Update ".$objeto->tabela." set ";
        for($i=0; $i<count($objeto->campos_valores); $i++):
            $capturaCampo = key($objeto->campos_valores);
            $sql .= key($objeto->campos_valores)."=";
            if($capturaCampo != 'fic_lote'):
                $sql .= is_numeric($objeto->campos_valores[key($objeto->campos_valores)]) ?
                            $objeto->campos_valores[key($objeto->campos_valores)] :
                            "'".$objeto->campos_valores[key($objeto->campos_valores)]."'";
            else:
                $sql .= "'".$objeto->campos_valores[key($objeto->campos_valores)]."'";
            endif;
            if($i < (count($objeto->campos_valores)-1)):
                $sql .= ", ";
            else:
                $sql .= " ";
            endif;
            next($objeto->campos_valores);
        endfor;
        $sql .= "WHERE ".$objeto->campopk."=";
        $sql .= is_numeric($objeto->valorpk) ? $objeto->valorpk : "'".$objeto->valorpk."'";
        return $this->executaSQL($sql);
    }
    
    public function atualizarEspecial($objeto){
        $sql = "Update ".$objeto->tabela." set ";
        for($i=0; $i<count($objeto->campos_valores); $i++):
            $sql .= key($objeto->campos_valores)."=";
            $sql .= is_numeric($objeto->campos_valores[key($objeto->campos_valores)]) ?
                $objeto->campos_valores[key($objeto->campos_valores)] :
                "'".$objeto->campos_valores[key($objeto->campos_valores)]."'";
            if($i < (count($objeto->campos_valores)-1)):
                $sql .= ", ";
            else:
                $sql .= " ";
            endif;
            next($objeto->campos_valores);
        endfor;
        $sql .= $objeto->extras_select;
        return $this->executaSQL($sql);
    }
    
    public function deletar($objeto){
        $sql = "DELETE FROM ".$objeto->tabela;
        $sql .= " WHERE ".$objeto->campopk."=";
        $sql .= is_numeric($objeto->valorpk) ? $objeto->valorpk : "'".$objeto->valorpk."'";
        return $this->executaSQL($sql);
    }
    
    public function deletarRegistros($objeto){
        $sql = "DELETE FROM  ".$objeto->tabela;
        if($objeto->extras_select != NULL):
            $sql .= " ".$objeto->extras_select;
        endif;
        return $this->executaSQL($sql);
    }
    
    public function selecionaTudo($objeto){
        $sql = "SELECT * FROM ".$objeto->tabela;
        if($objeto->extras_select != NULL):
            $sql .= " ".$objeto->extras_select;
        endif;
        return $this->executaSQL($sql);
    }
    
public function selecionaCampos($objeto){
    // Se não houver campos especificados, seleciona todos
    if (empty($objeto->campos_valores)) {
        $sql = "SELECT * ";
    } else {
        $campos = array_keys($objeto->campos_valores);
        $sql = "SELECT " . implode(", ", $campos) . " ";
    }
    
    $sql .= "FROM " . $objeto->tabela;
    if (!empty($objeto->extras_select)) {
        $sql .= " " . $objeto->extras_select;
    }
	error_log("SQL gerado: " . $sql);
    return $this->executaSQL($sql);
}
    
    public function selecionaCamposEspecial($objeto){
        if($objeto->extras_select != NULL):
            $sql = $objeto->extras_select;
        endif;
        return $this->executaSQL($sql);
    }
    
    public function executaSQL($sql = NULL){

	echo 'Executando SQL: ' . $sql . "\n"; // Log do SQL para depuração
        if($sql != NULL):
            $query = mysqli_query($this->conexao, $sql);
            if (!$query) {
                $this->trataerro(__FILE__, __FUNCTION__, mysqli_errno($this->conexao), mysqli_error($this->conexao), FALSE);
                return false;
            }
            $this->linhasafetadas = mysqli_affected_rows($this->conexao);
            if(substr(trim(strtolower($sql)), 0, 6) == 'select'):
                $this->dataset = $query;
                return $query;
            else:
                return $this->linhasafetadas;
            endif;
        else:
            $this->trataerro(__FILE__, __FUNCTION__, NULL, 'Comando SQL nao informado na rotina', FALSE);
        endif;
        // Nota: O commit automático é padrão no MySQLi, então a linha abaixo é redundante
        // mysqli_query($this->conexao, 'commit');
    }
    
    public function executaSQLID($sql = NULL){
        if($sql != NULL):
            $query = mysqli_query($this->conexao, $sql);
            if (!$query) {
                $this->trataerro(__FILE__, __FUNCTION__, mysqli_errno($this->conexao), mysqli_error($this->conexao), FALSE);
                return false;
            }
            $this->linhasafetadas = mysqli_insert_id($this->conexao);
            if(substr(trim(strtolower($sql)), 0, 6) == 'select'):
                $this->dataset = $query;
                return $query;
            else:
                return $this->linhasafetadas;
            endif;
        else:
            $this->trataerro(__FILE__, __FUNCTION__, NULL, 'Comando SQL nao informado na rotina', FALSE);
        endif;
    }
    
    public function retornaDados($tipo = NULL){
        switch (strtolower($tipo)):
            case "array":
                return mysqli_fetch_array($this->dataset);
                break;
            case "assoc":
                return mysqli_fetch_assoc($this->dataset);
                break;
            case "object":
                return mysqli_fetch_object($this->dataset);
                break;
            default:
                return mysqli_fetch_object($this->dataset);
                break;
        endswitch;
    }
    
    public function trataerro($arquivo = NULL, $rotina = NULL, $numerro = NULL, $msgerro = NULL, $geraexcept = FALSE){
        if($arquivo == NULL) $arquivo = "nao informado";
        if($rotina == NULL) $rotina = "nao informada";
        if($numerro == NULL && $this->conexao) $numerro = mysqli_errno($this->conexao);
        if($msgerro == NULL && $this->conexao) $msgerro = mysqli_error($this->conexao);
        $resultado =   'Ocorreu um erro com os seguintes detalhes_1:<br />
                        <strong>Arquivo:</strong> '.$arquivo.'<br />
                        <strong>Rotina:</strong> '.$rotina.'<br />
                        <strong>Codigo:</strong> '.$numerro.'<br />
                        <strong>Mensagem:</strong> '.$msgerro;
        if($geraexcept == FALSE):
            echo($resultado);
        else:
            die($resultado);
        endif;
    }
}
?>