<?php
/**
 * @license    http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
 * @author     Francois Merciol <dokuplugin@merciol.fr>
 *
 * Plugin Schedule: manage events per wiki @groups
 */

if (!defined ('DOKU_INC'))
    define ('DOKU_INC', realpath (__DIR__.'/../../../').'/');
if (!defined ('DOKU_PLUGIN'))
    define ('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');

require_once (realpath (__DIR__.'/..').'/schedule.class.php');
require_once (realpath (__DIR__.'/..').'/scheduleRoot.class.php');
require_once (realpath (__DIR__.'/..').'/schedules.class.php');

// ============================================================
class syntax_plugin_schedule_block extends DokuWiki_Syntax_Plugin {
 
    // ============================================================
    function getType () { return 'substition'; }
    function getPType () { return 'block'; }
    function getSort () { return 299; }
    function connectTo ($mode) {
        $this->Lexer->addSpecialPattern ('\{\{schedule[^}]*\}\}', $mode, 'plugin_schedule_block');
    }

    // ============================================================
    function handle ($match, $state, $pos, Doku_Handler $handler) {
        switch ($state) {
        case DOKU_LEXER_SPECIAL :
            return array ($state, trim (substr ($match, 10, -2))); // "{{schedule" => 10 "}}" => 2
        }
        return false;
    }

    var $scheduleRoot;
    var $schedules;

    // ============================================================
    function render ($mode, Doku_Renderer $renderer, $indata) {
        $dumy = "";
        if (empty($indata))
            return false;
        if ($mode != 'xhtml')
            return false;
        list ($instr, $data) = $indata;
        switch ($instr) {
        case DOKU_LEXER_SPECIAL :
            $args = " ".$data." ";
            if (preg_match_all ("#(\"[^\"]*\")* help (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0) {
                $renderer->doc .= $this->scheduleHelp ();
                return true;
            }

            $this->scheduleRoot = new scheduleRoot ($this);

            if (preg_match_all ("#(\"[^\"]*\")* admin (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0) {
                ob_start ();
                echo '<div class="schedule">'.NL;
                $this->scheduleRoot->manageAction ($_REQUEST['schd']);
                $this->scheduleRoot->printForm ();
                echo '      </div>';
                $text = ob_get_contents ();
                ob_end_clean ();
                foreach ($this->scheduleRoot->message as $type => $msg)
                    $text = '<div class="'.$type.'">'.$msg.'</div>'.$text;
                $renderer->doc .= $text;
                return true;
            }

            // namespace
            global $ID;
            $ns = getNS ($ID);
            if (preg_match_all ("#^ >([^ ]*) (.*)#", $args, $dumy) > 0) {
                $ns = $dumy[1][0];
                $args = ' '.$dumy[2][0];
                if (($ns == '*') || ($ns == ':'))
                    $ns = '';
                elseif ($ns == '.')
                    $ns = getNS ($ID);
                else
                    $ns = cleanID ($ns);
            }
            $mapId = "";
            if (preg_match_all ('/("[^"]*")* id="(?<id>[0-9a-zA-Z_]+)" ("[^"]*")*/', strtolower ($args), $dumy) > 0)
                for ($i = 0; $i < count ($dumy['id']); $i++)
                    $mapId = $dumy ['id'][$i];
            $this->schedules = new schedules ($this->scheduleRoot, $ns);
            $renderer->info ['cache'] = FALSE;
            $request = false;
            global $_REQUEST;
            if ((isset ($_REQUEST['schd']) && isset ($_REQUEST['schd']['ns']) && $_REQUEST['schd']['ns'] == $ns) ||
                (preg_match_all ("#(\"[^\"]*\")* (prop|form|ctrl) (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0))
                $request = true;
            if ($this->getConf ('useMap') && !is_dir (__DIR__.'/../../ol3'))
                $renderer->doc .= '<p><a href="http://www.dokuwiki.org/plugin:ol3">ol3 plugin</a> not installed (see <a href="http://www.dokuwiki.org/plugin:schedule">doc</a>)</p>';
            $cache = $this->schedules->readCache ($args);
            if ($cache) {
                $renderer->doc .= $cache;
                return true;
            }
            $this->schedules->load ();
            ob_start ();
            if (preg_match_all ("#(\"[^\"]*\")* table (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0) {
                echo '<div class="schedule">'.NL;
                $this->schedules->printScheduleCalendar (($mapId ? $mapId : "scheduleMapTable"), mktime (0, 0, 0, date ("n"), date ("j"), date ("Y")));
                echo '</div>';
            } else {
                $formLevel = 0;
                // form
                if (preg_match_all ("#(\"[^\"]*\")* prop (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0)
                    $formLevel = max ($formLevel, 3);
                if (preg_match_all ("#(\"[^\"]*\")* form (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0)
                    $formLevel = max ($formLevel, 2);
                if (preg_match_all ("#(\"[^\"]*\")* ctrl (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0)
                    $formLevel = max ($formLevel, 1);
                $this->scheduleDateFilters ($args);
                $this->schedules->setFormLevel ($formLevel);
                if ($request)
                    $this->schedules->manageAction ($_REQUEST['schd']);
                $this->scheduleOtherFilters ($args);
                $this->schedules->printScheduleList (($mapId ? $mapId : "scheduleMapList"));
            }
            $text = ob_get_contents ();
            ob_end_clean ();
            if (!$request)
                $this->schedules->writeCache ($args, $text);

            $this->schedules->writeSchedules ();
            $this->schedules->writeProp ();
            foreach ($this->scheduleRoot->message as $type => $msg)
                $text = '<div class="'.$type.'">'.$msg.'</div>'.$text;
            $renderer->doc .= $text;
        }
        return true;
    }

    // ============================================================
    function scheduleHelp () {
        $url = "http://admin.parlenet.org/plugins/schedule/";
        return
            '      <h1>Help Schedule</h1>'.NL.
            '      <ul>'.NL.
            '        <li><b>{{schedule</b> help <b>}}</b></li>'.NL.
            '        <li><b>{{schedule</b> admin <b>}}</b></li>'.NL.
            '        <li><b>{{schedule&gt;</b>nameSpace table [(<|=|>)(!|+-delta|jj/mm/aa|jj/mm/aaaa)] <b>}}</b></li>'.NL.
            '        <li><b>{{schedule&gt;</b>nameSpace id="id" [(<|=|>)(!|+-delta|jj/mm/aa|jj/mm/aaaa)] [#maxLine] [prop|form|ctrl] [(member|what|audience|noMember|noWhat|noAudience)="x1,x2,..."] <b>}}</b></li>'.NL.
            '      </ul>'.NL.
            '      <p><a class="urlextern" rel="nofollow" title="'.$url.'" href="'.$url.'">'.$url.'</a></p>'.NL;
    }

    // ============================================================
    function scheduleDateFilters ($args) {
        $before = "";
        $date = "";
        $after = "";
        $periode = array ("<" => &$before, "=" => &$date, ">" => &$after);
        $dumy = "";
        // <! =! >!
        if (preg_match_all ("#(\"[^\"]*\")*(?<op>[<=>])!(\"[^\"]*\")*#", $args, $dumy) > 0)
            $periode [$dumy ['op'][0]] = "!";
        // <+j =+j >+j <-j =-j >-j 
        if (preg_match_all ("#(\"[^\"]*\")*(?<op>[<=>])(?<delta>[+\-][0-9]*)(\"[^\"]*\")*#", $args, $dumy) > 0)
            for ($i = 0; $i < count ($dumy['op']); $i++)
                $periode [$dumy ['op'][$i]] = $dumy ['delta'][$i];
        // <jj/mm/aaa =jj/mm/aaa >jj/mm/aaa
        if (preg_match_all ("# (?<op>[<=>])(?<date>[0-9]{1,2}[-/][0-9]{1,2}[-/][0-9]{1,4}) #", $args, $dumy) > 0)
            for ($i = 0; $i < count ($dumy['op']); $i++)
                $periode [$dumy ['op'][$i]] = $dumy ['date'][$i];
        $this->schedules->setDateFilters ($before, $date, $after);
    }

    // ============================================================
    function scheduleOtherFilters ($args) {
        $max = "";
        $filterNames = array ("member", "what", "audience", "noMember", "noWhat", "noAudience");
        $filters = array ();
        $grouped = "";
        $dumy = "";

        // maxline
        if (preg_match_all ("/(\"[^\"]*\")*#(?<max>[0-9]+)(\"[^\"]*\")*/", strtolower ($args), $dumy) > 0)
            for ($i = 0; $i < count ($dumy['max']); $i++)
                $max = $dumy ['max'][$i];
        // filters
        foreach ($filterNames as $filterName) {
            if (preg_match_all ("#".$filterName."=\"(?<".$filterName.">[^\"]*)\"#", $args, $dumy) > 0) {
                $sep = "";
                for ($i = 0; $i < count ($dumy[$filterName]); $i++) {
                    $filters [$filterName] .= $sep.trim (trim ($dumy[$filterName][$i]), ',');
                    $sep = ',';
                }
            }
        }
        // grouped
        if (preg_match_all ("#(\"[^\"]*\")* (?<grouped>grouped|isolated) (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0)
            $grouped = $dumy ['grouped'][0];
        $this->schedules->setOtherFilters ($max, $filters, $grouped);
    }

    // ============================================================
}
