<?php
/**
 * MoaiEditor plugin for DokuWiki
 */
# Constants
const MOAIED_FAKE_MESSAGES = false;     # Create fake messages (info, error, success, notify) to test template compatibilty
 
//include_once('/var/www/html/zdebug/inc.php');

use dokuwiki\Extension\Plugin;

if(!defined('DOKU_INC')) die();

class action_plugin_moaieditor extends DokuWiki_Action_Plugin {

    // Register hook function
    public function register(Doku_Event_Handler $controller) {
        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'moaieditor_main');
    }
    // Main function
    public function moaieditor_main (Doku_Event &$event, $param) {
        global $ACT, $INFO, $conf, $lang;
        
        // Exit if not in edit mode
        if (!in_array($ACT, ['edit'])) {
            return;
        }
        // Load the JS files in 'templates/' and 'user_templates/'
        $info = $this->getInfo();
        $version = str_replace('-', '', $info['date']);      
        $plugin_path = DOKU_PLUGIN.'moaieditor';
        $plugin_url  = DOKU_BASE.'lib/plugins/moaieditor';  
        $t = $this->scanTemplateDir ($plugin_url, $plugin_path, "templates");
        $u = $this->scanTemplateDir ($plugin_url, $plugin_path, "user_templates");
        $templates = array_merge($t, $u);
        foreach ($templates as $template)
            $event->data['script'][] = array(
                'type' => 'text/javascript',
                'charset' => 'utf-8',
                'src' => $plugin_url.'/'.$template['folder'].'/'.$template['name'].".js?v=$version",
                'defer' => 'defer',
            );
        // Pass some data to Javascript
        $jsinfo = array(
            // Configuration options
            'base_url'                  => $plugin_url,
            'templates'                 => $templates,
            'hide_editor_by_default'    => $this->getConf('hide_editor_by_default'),
            'editor_width_side_by_side' => $this->getConf('editor_width_side_by_side'),
            'editor_width_top_bottom'   => $this->getConf('editor_width_top_bottom'),
            'editor_width_single_pane'  => $this->getConf('editor_width_single_pane'),
            // Docinfo
            'docinfo'                   => $this->getDocinfo(),
            // Editor intro message
            'intromsg'                  => $this->getEditorIntroMessage(),
        );
        $event->data['script'][] = array(
            'type' => 'text/javascript',
            '_data' => 'JSINFO.plugin_moaieditor = ' . json_encode($jsinfo),
        );
        // Simulate template messages (for testing template compatibility)
        if( isset($_GET['fakemsg']) || MOAIED_FAKE_MESSAGES)
            $this->simulate_template_messages();
    } 
    // ───────────────────────────────────────────
    // Scan template dir
    public function scanTemplateDir ($plugin_url, $plugin_path, $folder) {
        $files = [];    
        foreach (scandir("$plugin_path/$folder") as $filename)
            if (str_ends_with($filename, '.js'))
                if (!str_ends_with($filename, 'default.js')) {
                    $name = pathinfo($filename, PATHINFO_FILENAME);
                    $css = Null;
                    if (file_exists("$plugin_path/$folder/$name.css"))
                        $css = "$plugin_url/$folder/$name.css";
                    $files[] = ['name'=>$name, 'folder'=>$folder, 'css'=>$css];                    
                }
        return $files;
    }
    // ───────────────────────────────────────────
    // Get the intro message shown by DokuWiki in editor mode (whether we show it or not will depend on user settings)
    public function getEditorIntroMessage () {
        # The editor intro message is rendered here: inc/Ui/Editor.php -> show()
        # In editor mode, it can be of two types: 'editrev' or 'edit'
        #      /inc/lang/en/edit.txt       "**You've loaded an old revision of the document!** If you save it, you will create a new version with this data."
        #      /inc/lang/en/editrev.txt    "Edit the page and hit ''Save''. See [[wiki:syntax]] for Wiki syntax. Please edit the page only if you can **improve** it. If you want to test some things, learn to make your first steps on the [[playground:playground|playground]]."
        global $REV;
        global $INFO;
        $wr = $INFO['writable'] && !$INFO['locked'];
        if (!$wr)
            return null;
        $type = ($REV) ? 'editrev' : 'edit';   // intro locale text (edit, rditrev, or read)
        $html = p_locale_xhtml($type);
        return ['type'=>$type, 'html'=>$html];
    }
    // ───────────────────────────────────────────
    // Get document info (mostly copied from 'tpl_pageinfo' but we want to format the data differently)
    public function getDocinfo () {
        global $conf, $lang, $INFO, $ID;
        
        // Document info will not exist when creating a new page
        if (!$INFO['exists']) 
            return null;

        // Document path on disk
        $fn = $INFO['filepath'];
        if (!$conf['fullpath']) {
            if ($INFO['rev'])
                $fn = str_replace($conf['olddir'] . '/', '', $fn);
            else 
                $fn = str_replace($conf['datadir'] . '/', '', $fn);
        }
        $fn = utf8_decodeFN($fn);
        
        // Last modification time
        $dateLocal = dformat($INFO['lastmod']);
        $dateIso = date(DATE_ISO8601, $INFO['lastmod']);
        
        // Edited by
        if ($INFO['editor']) 
            $by = $lang['by'].' <bdi><b>'.editorinfo($INFO['editor']).'</b></bdi>';
        else 
            $by = '('.$lang['external_edit'].')';
        
        // Return it
        return [
            'labelPath' => 'Document path on disk',
            'labelMod'  => $lang['lastmod'],
            'path'      => "<bdi><i>data/pages/</i><b>$fn</b></bdi>",
            'time'      => "<time datetime='$dateIso'><b>$dateLocal</b></time>",
            'by'        => $by
        ];
    }   
    // ───────────────────────────────────────────
    // Function to create fake messages intended to facilitate testing of templates
    public function simulate_template_messages () {
        global $MSG;        
        $MSG[] = ['msg'=>'Error message (-1)',  'lvl'=>'error',   'allow'=>0, 'line'=>'', 'file'=>''];
        $MSG[] = ['msg'=>'Info message (0)',    'lvl'=>'info',    'allow'=>0, 'line'=>'', 'file'=>''];
        $MSG[] = ['msg'=>'Success message (1)', 'lvl'=>'success', 'allow'=>0, 'line'=>'', 'file'=>''];
        $MSG[] = ['msg'=>'Notify message (2)',  'lvl'=>'notify',  'allow'=>0, 'line'=>'', 'file'=>''];
    }
    
} // End class
