<?php

namespace Modules;

// class TOC
class TOC {

    private $selector;
    private $folder;
    private $layout;
    private $caller_dir;
    private $body;
    private $key = "";
    private $elements = array();
    public $entries = array();
    private $filters = array();


    
    // $conf: array(
    //         $selector,
    //         $folder,
    //         ...
    //        )
    function __construct($conf,$caller_dir,$body) {
        $f3 = \Base::instance();
        //var_dump($conf);
        // read configuration
        if (is_array($conf)) {
            $this->selector = array_shift($conf);
            $folder = trim(array_shift($conf));
            $this->folder = strncmp("/", $folder, 1)
                          ? $caller_dir.$folder
                          : $f3->get('CONTENT').substr($folder,1);
            if (substr_compare($this->folder, "/", -1, 1)) {
                $this->folder .= "/";
            }
            if (count($conf)) {
                $this->layout = array_shift($conf);
            }
            if (count($conf)) {
                $this->key = array_shift($conf);
            }
        }
        $this->caller_dir = $caller_dir;
        $this->body = is_array($body) ? $body : array($body);

        $this->prepare_filters();
        
        $this->prepare_elements();
        //echo $this->folder."<br>";
    }

    function __toString() {
        return implode("\n",$this->entries);
    }
    
    function dispatch() {
        switch ($this->selector) {
        case 'event':
        case 'events':
            $this->load('\Modules\CEvent');
            break;
        case 'location':
        case 'locations':
            $this->load('\Modules\CLocation');
            break;
        case 'member':
        case 'members':
            $this->load('\Modules\CMember');
            break;
        case 'concert':
        case 'concerts':
            $this->load('\Modules\CConcert');
            break;
        }
    }

    function prepare_filters() {

        // Filters on Key value pairs
        $pattern = "/(.+)=(.+)/";
        foreach ($this->body as $k=>$v) {
            if(preg_match($pattern,$v,$matches)) {
                unset($this->body[$k]);
                if(strncmp("!",$matches[1],1)) {
                    $this->filters['must_have'][]=array($matches[1]=>$matches[2]);
                } else {
                    $this->filters['must_not_have'][]=array(substr($matches[1],1)=>$matches[2]);
                }
            }
        }

        
    }

    function apply_filters() {
        foreach($this->elements as $k=>$v) {
            $show = true;
            if (count($this->filters['must_have'])) {
                $show = false;
                foreach ($this->filters['must_have'] as $l=>$w) {
                    $ke = array_keys($w);
                    $key = $ke[0];
                                            
                    if (array_key_exists($key,$v)) {
                        if (is_object($v[$key]) && !strncmp("@",$w[$key],1)) {
                            $show = (in_array(substr($w[$key],1), $v[$key]->ids))
                                  ? true
                                  : $show
                                  ;
                        } else {
                            $show = (trim($v[$key])==trim($w[$key]))
                                  ? true
                                  : $show
                                  ;
                        }
                    }
                }
            }
            if (count($this->filters['must_not_have'])) {
                foreach ($this->filters['must_not_have'] as $l=>$w) {
                    $ke = array_keys($w);
                    $key = $ke[0];

                    if (array_key_exists($key,$v)) {
                        $show = (trim($v[$key])==trim($w[$key])) ? false : $show;
                    }
                }
            }

            switch ($show) {
            case true:
                break;
            case false:
                unset($this->elements[$k]);
                break;
            }
        }
        
    }
    
    function prepare_elements() {
        if(is_dir($this->folder)) {
            $ls=scandir($this->folder);
            
            if ($this->body) {
                //var_dump($this->body);
                foreach ($this->body as $f) {
                    $f = trim($f);
                    if (in_array($f,$ls)
                        && is_dir($this->folder.$f)) {
                        $this->elements[$this->folder.$f."/"] = true;
                    }
                }
            } else {
                foreach($ls as $k=>$f) {
                    if (!strncmp($f,'.',1)) continue;
                    if (!is_dir($this->folder.$f)) continue;
                    $this->elements[$this->folder.$f."/"] = true;
                }
            }
            
        }

        foreach ($this->elements as $key=>$value) {
            $folder = new FilesInFolders($key);
            $folder->prepare_files();
            $this->elements[$key] = $folder->read_config();
        }
        // can be moves before 
        $this->apply_filters();
    }

    function string_to_key($in) {
        return md5($in);
    }

    function load($class) {
        
        foreach ($this->elements as $k=>$v) {
            $config=array('path'=>$k);
            $this->entries[$k] = new $class($v,$config);
            if ($this->layout) {
                if ($this->layout != 'collect') {
                    //var_dump($this->entries[$k]);
                    $this->entries[$k]->set_layout($this->layout);
                }
            }
        }
        
        if ($this->layout == 'collect' && $this->key != "") {
            $new = array();
            foreach ($this->entries as $k=>$en) {
                if (array_key_exists($this->key,$en->keys)) {
                    $key_orig = $en->keys[$this->key];
                }
                $key_new = self::string_to_key($en->values[$key_orig]);
                if (!array_key_exists($key_new, $new)) {
                    $new[$key_new] = array();
                }
                $new[$key_new][] = $en;
            }
            //var_dump($new);
            foreach ($new as $k=>$collection) {
                $obj = new CMultiple($collection);
                $obj->set_first(clone $obj->elements[0],'collected_header');
                $obj->set_layout('collected_entry');
                $new[$k] = $obj;
            }
            //var_dump($new);
            $this->entries = $new;
                    
        }
        //var_dump($this->entries);
    }
}
