<?php

namespace MGModule\DNSManager2\mgLibs\models;
use MGModule\DNSManager2 as main;

/**
 * Description of abstractModel
 *
 * @author Michal Czech <michael@modulesgarden.com>
 */
abstract class repository {    
    protected $_filters = array();
    protected $_limit = null;
    protected $_offest = 0;
    protected $_order = array();
    protected $_search = array();
    
    abstract function getModelClass();
    
    /** @return repository */
    static function factory() {
        $class = get_called_class();
        return new $class();
    }
    
    public function fieldDeclaration(){
        return forward_static_call(array($this->getModelClass(),'fieldDeclaration'));
    }
    
    public function tableName(){
        return forward_static_call(array($this->getModelClass(),'tableName'));
    }
    
    public function limit($limit)
    {
        $this->_limit = $limit;
    }
    
    public function offset($offset)
    {
        $this->_offest = $offset;
    }
    
    public function search($value, $columns = false) {
        if($columns === false) $columns = $this->fieldDeclaration();
        foreach($columns as $column) {
            $this->addSearch($column, $value);
        }
    }
    
    public function addSearch($column, $value) {
        $uid = $column.uniqid();
        $this->_search[] = array(
            'or' => true,
            'customQuery' => "`$column` LIKE :$uid ",
            'params' => array(
                $uid => "%$value%",
            ),
        );
    }
    
    public function addAndSearch(array $columns,array $values)
    {
        foreach($columns as $key => $col)
        {
            $uid = $col.uniqid();
            $this->_search[] = array(
                'or' => false,
                'customQuery' => "`$col` LIKE :$uid ",
                'params' => array(
                    $uid => "%$values[$key]%",
                ),
            );
        }
    }
    
    public function setFiltersBeforeQuery()
    {
        if(empty($this->_search))
        {
            return;
        }    
        
        $search = main\mgLibs\MySQL\query::parseConditions($this->_search, $values);

        $this->_filters[] = array(
            'customQuery' => '( ' . $search . ' ) ',
            'params' => $values,
        );
    }
    
    public function setFilter($filter, $value) {
        $this->_filters[$filter] = $value;
        return $this;
    }
    
    public function removeFilter($filter) {
        unset($this->_filters[$filter]);
    }
    
    public function removeFilters() {
        $this->_filters = array();
    }
    
    public function sortBy($field,$vect){
        $column = forward_static_call(array($this->getModelClass(),'getProperyColumn'),$field);
        $this->_order[$column] = $vect;
    }
    
    /**
     * 
     * @return orm
     */
    function get(){
        $this->setFiltersBeforeQuery();
        $result = main\mgLibs\MySQL\query::select(
            self::fieldDeclaration()
            , self::tableName()
            , $this->_filters
            , $this->_order
            , $this->_limit
            , $this->_offest
        );

        $output = array();
        
        $class = $this->getModelClass();


        while($row = $result->fetch())
        {
            $output[] = new $class($row['id'],$row);
        }
        
        return $output;
    }

    function getGrouped(){
        $this->setFiltersBeforeQuery();
        $result = main\mgLibs\MySQL\query::select(
            self::fieldDeclaration()
            , self::tableName()
            , $this->_filters
            , $this->_order
            , $this->_limit
            , $this->_offest
        );
        return $result->fetchAll(\PDO::FETCH_GROUP|\PDO::FETCH_UNIQUE|\PDO::FETCH_ASSOC);

    }



    function count(){
        $this->setFiltersBeforeQuery();
        $fields = $this->fieldDeclaration();
        $first = key($fields);
        
        if(is_numeric($first))
        {
            $first = $fields[$first];
        }
        
        return main\mgLibs\MySQL\query::count(
            $first
            , self::tableName()
            , $this->_filters
            , array()
            , $this->_limit
            , $this->_offest
        );
    }
    
    function delete(){
        $this->setFiltersBeforeQuery();
        return main\mgLibs\MySQL\query::delete(
            self::tableName()
            , $this->_filters
        );
    }
    
    function one() {
        $this->limit(1);
        $arr = $this->get();
        return empty($arr)?false:array_pop($arr);
    }
}
