<?php
class GridAction extends wtActions
{
    protected $o_ObjClass;
    protected $a_MethodsDefault;
    protected $a_AssignFilter;
    protected $a_ConditionFilter;
    protected $a_ConditionFilterPr;
    protected $a_OrderDefault;
    protected $a_Order;
    protected $i_NumRecordsShow;
    
    protected $a_ResultSelect;
    protected $a_ResultArray;
    protected $page;
    protected $totalPage;
    protected $totalRecords;
    
    protected $a_RowToShow = array();
    
    protected $b_InnerJoin = false;
    protected $a_AddInnerJoin = array();
    
    protected $b_ControlArray = true;
    
    protected $s_MethodNameSelect;
    protected $s_MethodCustomSelect;
    
    public function setClassFind( $o_Class )
    {
        $this->o_ObjClass = $o_Class;
    }
    
    public function addMethodDefault( $s_NameMethod, $s_Value )
    {
        $this->a_MethodsDefault[$s_NameMethod] = $s_Value;
    }
    
    public function addAssignFilter( $s_NameParam )
    {
        $this->a_AssignFilter[] = $s_NameParam;
    }
    
    public function addConditionFilter( $s_NameParam, $s_NameField, $s_Condition, $s_ValueFormat = null )
    {
		
        $this->a_ConditionFilter[] = array(
                                                "NameParam"   => $s_NameParam, 
                                                "NameField"   => $s_NameField,
                                                "Condition"   => $s_Condition,
                                                "ValueFormat" => $s_ValueFormat
                                          );
    }
    
    public function addConditionFilterPr( $s_NameMethod, $v_ValueReturn )
    {
        $this->a_ConditionFilterPr[$s_NameMethod] = $v_ValueReturn;
    }
    
    /**
     * Set
     *
     * $b_TypeOrd -> true  ASC
     * $b_TypeOrd -> false DESC
     * 
     * @param String $s_NameField
     * @param Boolean $b_TypeOrd
     */
    public function addOrderDefault( $s_NameField, $b_TypeOrd )
    {
        $this->a_OrderDefault[$s_NameField] = $b_TypeOrd;
    }
    
    public function addOrder( $s_NameVar, $s_NameField )
    {
        $this->a_Order[$s_NameVar] = $s_NameField;
    }
    
    public function setNumberRecordsShow( $i_Num )
    {
        $this->i_NumRecordsShow = $i_Num;
    }
    
    public function getResultSelect()
    {
        if( !$this->a_ResultSelect )
            return array();
        else 
            return $this->a_ResultSelect;
    }
    
    public function getPage()
    {
        return $this->page;
    }
    
    public function getTotalPage()
    {
        return $this->totalPage;
    }
    
    public function getTotalRecords()
    {
        return $this->totalRecords;
    }
    
    public function addRowsToShow()
    {
        $this->a_RowToShow = func_get_args();
    }
    
    public function getResultArray()
    {
        return $this->a_ResultArray;
    }
    
    public function addInnerJoin( $o_ObjectInner, $s_NameFieldId, $s_NameFieldShow )
    {
        $this->b_InnerJoin = true;
        $this->a_AddInnerJoin[$s_NameFieldId] = array( "Object" => $o_ObjectInner, "NameField" => $s_NameFieldShow );
    }
    
    public function setControlArray( $v )
    {
        $this->b_ControlArray = $v;
    }
    
    public function setMethodSelectCustom( $s_MethodNameSelect )
    {
        $this->s_MethodNameSelect = $s_MethodNameSelect;
    }
    
    public function setMethodSelectCustomRs( $s_MethodNameSelect )
    {
        $this->s_MethodCustomSelect = $s_MethodNameSelect;
    }
    
    public function initialize()
    {
        $block = $this->getRequestParameter( 'block' );
        $page  = $this->getRequestParameter( 'page' );
        $sidx  = $this->getRequestParameter( 'sidx' );
        $sord  = $this->getRequestParameter( 'sord' );
        
        $o_ObjClass = $this->o_ObjClass;
        
        //SE INICIA CON EL PARAMETRO POR DEFECTO
        if( $this->a_MethodsDefault )
        {
            foreach ( $this->a_MethodsDefault as $s_NameMethod => $v_Value )
            {
                if ( strpos( $s_NameMethod, "." ) !== false && strpos( $s_NameMethod, "SELECT" ) === false ) 
                {
                    if ( !isset( $v_Value['Condition'] ) ) 
                    {
                        $a_NameMethod = explode( ".", $s_NameMethod );
                        $s_NameMethod = $a_NameMethod[1];
                    }
                }

                if( is_array( $v_Value ) )
                {
                    $o_ObjClass->addCondition( $s_NameMethod, $v_Value['Condition'], $v_Value['Value'], false );
                }
                else 
                {
                    $s_NameMethod = "set".$s_NameMethod;
                    if( method_exists( $o_ObjClass, $s_NameMethod ) )
                    {
                        $o_ObjClass->$s_NameMethod( $v_Value );
                    }
                    else 
                    {
                        $s_NameClass = get_class( $o_ObjClass );
                        throw new Exception( "El metodo no existe para realizar el set para el Filtro por Defecto ( $s_NameClass )( $s_NameMethod )." );
                    }
                }
            }
        }
        ///////////////////////////////////////
        //AHORA SE REALIZA EL FILTRO NORMAL
        if( $this->a_AssignFilter )
        {
            foreach ( $this->a_AssignFilter as $i_Key => $s_NameParam )
            {
                $s_NameMethod = "set".$s_NameParam;
                if( method_exists( $o_ObjClass, $s_NameMethod ) )
                {
                    if( $this->getRequestParameter( $s_NameParam ) != "" ){ $o_ObjClass->$s_NameMethod( $this->getRequestParameter( $s_NameParam ) ); }
                }
                else 
                {
                    $s_NameClass = get_class( $o_ObjClass );
                    throw new Exception( "El metodo no existe para realizar el set para el Filtro Normal ( $s_NameClass )( $s_NameMethod )." );
                }
            }
        }
        ///////////////////////////////////////
        //AHORA SE REALIZA EL FILTRO PERSONALIZADO
        if( $this->a_ConditionFilter )
        {
			foreach ( $this->a_ConditionFilter as $i_Key => $a_Filters )
            {
                if( $this->getRequestParameter( $a_Filters['NameParam'] ) != "")
                {
                    if( $a_Filters['ValueFormat'] )
                    {
                        switch ( $a_Filters['ValueFormat'] )
                        {
                            case ( strpos( $a_Filters['ValueFormat'], "%s" ) !== false ) :
                                $o_ObjClass->addCondition( $a_Filters['NameField'], $a_Filters['Condition'], str_replace( "%s", $this->getRequestParameter( $a_Filters['NameParam'] ), $a_Filters['ValueFormat'] ) );
								
                            break;
                            case "d-m-Y":
                                $o_ObjClass->addCondition( $a_Filters['NameField'], $a_Filters['Condition'], UtilDate::recuperarFechaMysql( $this->getRequestParameter( $a_Filters['NameParam'] ) ) );
                            break;
                            case ($a_Filters['ValueFormat']=="00:00:00" || $a_Filters['ValueFormat']=="23:59:59" ):
                                $o_ObjClass->addCondition( $a_Filters['NameField'], $a_Filters['Condition'], $this->getRequestParameter( $a_Filters['NameParam'] )." ".$a_Filters['ValueFormat'] );
                            break;
                            case ( strpos( $a_Filters['ValueFormat'], "SELECT" ) !== false ) :
                                $o_ObjClass->addCondition( $a_Filters['NameField'], $a_Filters['Condition'], $a_Filters['ValueFormat'], false );
                            break;
                        }
                    }
                    else 
                    {
						$o_ObjClass->addCondition( $a_Filters['NameField'], $a_Filters['Condition'], $this->getRequestParameter( $a_Filters['NameParam'] ) );
                    }
                }
            }
        }
        ///////////////////////////////////////
        //AHORA SE VE EL ORDENAMIENTO
        //AQUI LO IMPORTANTE ES QUE ESTE ACTIVADO:
        //multiSort   : true,
        //sortable    : true,
        //EN DETALLES:
        //sortable: true, sorttype: 'text'
        if( $this->getRequestParameter( 'sidx' ) )
        {
            $a_lst = explode( ",", $sidx );
            foreach ( $a_lst as $i_key => $s_str )
            {
                $s_str2 = ltrim( $s_str );
                $a_str3 = explode( " ", $s_str2 );
                if( count( $a_lst ) == ( $i_key + 1 ) )
                {
                    array_pop( $a_str3 );
                    array_push( $a_str3, $sord );
                }
                $a_OrdCampos[] = $a_str3;
            }
            foreach ( $a_OrdCampos as $i_Key => $a_CampTipo )
            {
                foreach ( $this->a_Order as $s_NameVar => $s_NameField )
                {
                    if( $a_CampTipo[0] == $s_NameVar )
                    {
                        if( $a_CampTipo[1] == "asc" )
                        {
                        	$o_ObjClass->addOrderBy( $s_NameField, true ); 
                        } 
                        else 
                        {
                        	$o_ObjClass->addOrderBy( $s_NameField, false ); 
                        }
                    }
                }
            }
        }
        else 
        {
            if( $this->a_OrderDefault )
            {
                foreach ( $this->a_OrderDefault as $s_NameField => $b_Value )
                {
                    $o_ObjClass->addOrderBy( $s_NameField, $b_Value );
                }
            }
        }
        ///////////////////////////////////////
        //PAGINACION
        if( $this->s_MethodNameSelect ) 
        {
            //NOMBRE DEL METODO PERSONALIZADO - PARA EXCEL, EXPORTACIONES, GRID PERSONALIZADOS
            $s_MethodNameSelect = $this->s_MethodNameSelect;
            return $o_ObjClass->$s_MethodNameSelect();
        }
        
        $tamanioPag = $this->i_NumRecordsShow;
        if( !$page ) $page = 1;
        $limitInf   = ( $page - 1 ) * $tamanioPag;
		
        if( $this->s_MethodCustomSelect )
        {
            $s_MethodNameSelect1 = $this->s_MethodCustomSelect;
            $s_MethodNameSelect2 = $this->s_MethodCustomSelect."NumRows";
            $this->a_ResultSelect = $o_ObjClass->$s_MethodNameSelect1( $limitInf, $tamanioPag );
            $i_NumReg   = $o_ObjClass->$s_MethodNameSelect2();
        }
        else 
        {
            $this->a_ResultSelect = $o_ObjClass->select( $limitInf, $tamanioPag );
            $i_NumReg   = $o_ObjClass->selectNumRows();
        }
        
        $o_navigation = new navigation();
        $o_navigation->setPaginaActual( $page );
        $o_navigation->setTamanioPagina( $tamanioPag );
        $o_navigation->setTotalRegistros( $i_NumReg );
        
        $i_TotalPagina = $o_navigation->getTotalPagina();
            
        $this->page         = $page;
        $this->totalPage    = $i_TotalPagina;
        $this->totalRecords = $i_NumReg;
        ///////////////////////////////////////SE TERMINA LA PAGINACION
        $a_Rs = array();
        $i_Cnt = 0;
        if( $this->b_ControlArray )
        {
            //SE RECUPERA LA DATA
            if ( count( $this->a_RowToShow ) == 0 )
            {
                throw new Exception( "Debe de registar Campos para mostrar." );
            }
            if( $this->a_ResultSelect )
            {
                foreach ( $this->a_ResultSelect as $iKey => $o_ObjClassBN )
                {
                    $b_Continue = true;
                    if( $this->a_ConditionFilterPr )
                    {
                        foreach ( $this->a_ConditionFilterPr as $s_NameMethodPr => $v_ValuePr )
                        {
                            if( method_exists( $o_ObjClassBN, $s_NameMethodPr ) )
                            {
                                $v_ResultPr = $o_ObjClassBN->$s_NameMethodPr();
                                if( $v_ValuePr !== $v_ResultPr )
                                {
                                    $b_Continue = false;
                                }
                            }
                        }
                    }
                    if( !$b_Continue )
                    {
                        continue;
                    }
                    $a_Add = array();
                    foreach ( $this->a_RowToShow as $i_Key2 => $s_NameField )
                    {
                        $s_NameMethod = "get".$s_NameField;
                        if( method_exists( $o_ObjClassBN, $s_NameMethod ) )
                        {
                            $a_Add[$s_NameField] =  $o_ObjClassBN->$s_NameMethod() ;
                        }
                        else 
                        {
                            $s_NameClass = get_class( $o_ObjClass );
                            throw new Exception( "El metodo no existe para realizar el get y recuperar la data ( $s_NameClass )( $s_NameMethod )." );
                        }
                        if( $this->b_InnerJoin )
                        {
                            if( isset( $this->a_AddInnerJoin[$s_NameField] ) )
                            {
                                $o_FieldInner  = $this->a_AddInnerJoin[$s_NameField]['NameField'];
                                $o_ObjectInner = $this->a_AddInnerJoin[$s_NameField]['Object'];
                                if( trim( $o_ObjClassBN->$s_NameMethod() ) != "" )
                                {
                                    $o_ObjectBN    = $o_ObjectInner->selectByPK( $o_ObjClassBN->$s_NameMethod() );
                                    if( $o_ObjectBN )
                                    {
                                        $s_NameMethod2 = "get".$o_FieldInner;
                                        $a_Add[$s_NameField] =  $o_ObjectBN->$s_NameMethod2() ;
                                    }
                                    else 
                                    {
                                        $s_NameClass = get_class( $o_ObjectInner );
                                        throw new Exception( "El objeto Inner ( $s_NameClass ) no retorno el valor requerido, el campo( {$s_NameMethod} ) con el valor( {$o_ObjClassBN->$s_NameMethod()} ) no existe." );
                                    }
                                }
                                else 
                                {
                                    $a_Add[$s_NameField] = "";
                                }
                            }
                        }
                    }
                    $a_Rs[$i_Cnt] = $a_Add;
                    $i_Cnt++;
                }
            }
        }
        $this->a_ResultArray = $a_Rs;
        //pr( $a_Rs );
        ///////////////////////////////////////
    }
}