<?php
/**
 * plot-Plugin: Parses gnuplot-blocks
 *
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Wizardry and Steamworks <wizardry.steamworks@outlook.com>,
 *             Alexander 'E-Razor' Krause <alexander.krause@erazor-zone.de>
 *
 * [WaS] The following plugin is a revision of the GNUplot Plugin by
 * Alexander 'E-Razor' Krause from 2005 that uses the original gnuplot binary
 * in order to render graphs that has been patched up to work on modern
 * DokuWiki versions.
 *
 */

if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');

/**
 * All DokuWiki plugins to extend the parser/rendering mechanism
 * need to inherit from this class
 */
class syntax_plugin_plotwas extends DokuWiki_Syntax_Plugin {
    
    function getType() { return 'protected'; }
    function getPType() { return 'normal'; }
    function getSort() { return 200; }

    /**
     * Connect pattern to lexer
     */
    function connectTo($mode) {
        $this->Lexer->addEntryPattern('<plot(?=.*\x3C/plot\x3E)', $mode, 'plugin_plotwas');
    }

    function postConnect() {
        $this->Lexer->addExitPattern('</plot>', 'plugin_plotwas');
    }

    /**
     * Handle the match
     */
    function handle($match, $state, $pos, Doku_Handler $handler) {
        if ( $state == DOKU_LEXER_UNMATCHED ) {
            $matches = preg_split('/>/u', $match, 2);
            $matches[0] = trim($matches[0]);
            if ( trim($matches[0]) == '' ) {
                $matches[0] = NULL;
            }
            return array($matches[1],$matches[0]);
        }
        return array($state, '', '');
    }

    /**
     * Create output
     */
    function render($mode, Doku_Renderer $renderer, $data) {
        global $conf;
        if($mode == 'xhtml' && strlen($data[0]) > 1) {
            $plotdir = $conf['mediadir'] . '/plot';
            if ( !is_dir($plotdir) ) {
                mkdir($plotdir, 0777 - $conf['dmask'], true);
            }

            $hash = md5(serialize($data[0]));
            $filename = $plotdir.'/'.$hash.'.png';
            $size_str = $data[1];

            // If image already exists, render it immediately
            if ( is_readable($filename) ) {
                $renderer->doc .=  $this->plugin_render('{{'.'plot:'.$hash.'.png'."$size_str}}");
                return true;
            }

            // Attempt to create image and check for true success
            if ($this->createImage($filename, $data[0])) {
                $renderer->doc .=  $this->plugin_render('{{'.'plot:'.$hash.'.png'."$size_str}}");
            } else {
                $renderer->doc .= '**ERROR RENDERING GNUPLOT**';
            }
            return true;
        }

        return false;
    }

    function createImage($filename, &$data) {
        $tmpfname = tempnam(sys_get_temp_dir(), "dokuwiki.plot");

        $gnuplot_data = 'set terminal png transparent nocrop enhanced font arial 8 size 420,320'."\n".
                        "set output '".$filename."'\n" . $data;

        file_put_contents($tmpfname, $gnuplot_data);

        // Execute and capture status
        exec('/usr/bin/gnuplot '.$tmpfname, $output, $return_var);

        unlink($tmpfname);
        
        // gnuplot returns 0 on success
        return ($return_var === 0);
    }

    // output text string through the parser, allows dokuwiki markup to be used
    function plugin_render($text, $format='xhtml') {
        $info = array();
        return p_render($format, p_get_instructions($text), $info);
    }
}
