<?php namespace Eae\Database\Eloquent\Collection;

use Illuminate\Database\Eloquent\Collection as EloquentCollection;
use Eae\Exception\LocaException;


class BaseCollection extends EloquentCollection{         
    public function hasItem($fieldName, $value){
        $result = $this->getByFieldName($fieldName, $value);
        return !empty($result);
    } 
    
    public function hasNoItem($fieldName, $value){
        $result = $this->filter(function($model) use ($fieldName, $value) {
            return $model->$fieldName != $value;
        })->first();
        return !empty($result);
    } 
    
    public function getByFieldName($fieldName, $value){
        $result = $this->filter(function($model) use ($fieldName, $value) {
            if(is_array($value)){
                return in_array($model->$fieldName, $value);    
            }else{
                return $model->$fieldName == $value;
            }
        })->first();
        
        return $result;    
    }
    
    public function loadCustomRelations($customRelations){
        if(is_array($customRelations)){
            foreach($customRelations as $customRelation){
                $this->loadCustomRelations($customRelation);    
            }
            return $this;
        } 
        
        if(!is_string($customRelations)){
            throw new LocaException("The custom relation must be a string");    
        }
        
        if (count($this->items) > 0){
            $ids = array_map(function($m) { return $m->getKey(); }, $this->items);
            
            $model = $this->first();
            if(!$model->isCustomRelationLoaded($customRelations)){
                $queryMethod = $model->getCustomRelationQueryMethodName($customRelations);
                $query = $model->$queryMethod($ids);
                $relatedModels = $query->get();
               
                $collectionType = get_class($relatedModels);
                
                $dictionary = $this->_buildDictionary($relatedModels);
                
                foreach ($this->items as $model)
                {
                    $key = $model->getKey();
                    if (isset($dictionary[$key])){
                        $value = new $collectionType($dictionary[$key]);
                        $model->setCustomRelation($customRelations, $value);
                    }else{
                        $model->setCustomRelation($customRelations, null);    
                    }
                } 
            }   
        } 
        
        return $this;   
    } 
    
    protected function _buildDictionary($results)
    {
        $dictionary = array();

        $foreign = "CustomFK";

        // First we will create a dictionary of models keyed by the foreign key of the
        // relationship as this will allow us to quickly access all of the related
        // models without having to do nested looping which will be quite slow.
        foreach ($results as $result)
        {
            $dictionary[$result->{$foreign}][] = $result;
        }

        return $dictionary;
    } 
}