<?php
/**
 * Plugin Weiqi: Displays Weiqi (also named Go game or Baduk) diagrams.
 * http://wiki.splitbrain.org/plugin:weiqi
 * http://en.wikipedia.org/wiki/Go_(board_game)
 *
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Christophe Gragnic <christophegragnic@yahoo.fr>
 */
 
// must be run within Dokuwiki
if(!defined('DOKU_INC')) die();
 
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');
 
/**
 * All DokuWiki plugins to extend the parser/rendering mechanism
 * need to inherit from this class
 */
class syntax_plugin_weiqi extends DokuWiki_Syntax_Plugin {

    // these class vars are like conf vars (will be in the admin page one day)
    // they are initialized in the plugin constructor syntax_plugin_weiqi()
    
    // syntax starts at <xxx>, ends at </xxx> where xxx is $syntax_tag
    var $syntax_tag;
    
    /**
     * Plugin Constructor.
     */
    function syntax_plugin_weiqi() {
      require_once(DOKU_INC.'lib/plugins/weiqi/weiqi_parser.php');
      // enable direct access to language strings
      $this->setupLocale();
      // enable direct access to configuration
      $this->loadConfig();
      
      $this->syntax_tag = 'weiqi';
      
      // have a look at weiqi_parser.php
      // for some explanations about those config items
      $this->conf = array(
                'attributes_key' => 'attributes:',
                'caption_key' => 'caption:',
                'img_path_web' => DOKU_BASE.'lib/plugins/weiqi/img/',
                'img_path_fs' => 'lib/plugins/weiqi/img/',
                'letter_sequence' => 'abcdefghjklmnopqrstuvwxyz',
                'plain_text_coeff' => 0.7,
                'allowed_attribute_keys' => array(
                    'demo', 'goban', 'coords', 'grid_size',
                    'reverse_numbers', 'reverse_letters',
                    'start_number', 'start_letter',
                    'advanced'),
                'default_attributes' => array(
                    'demo' => false,
                    'goban' => 1,
                    'grid_size' => 25,
                    'edges_width' => 10,
                    'coords' => false,
                    'reverse_numbers' => false,
                    'reverse_letters' => false,
                    'start_number' => 1,
                    'start_letter' => 1,
                    'advanced' => false,
                    )
                );
    }

    function getInfo() {
      return array(
        'author' => 'Grahack',
        'email'  => 'christophegragnic@yahoo.fr',
        'date'   => '2008-06-19',
        'name'   => 'Weiqi Plugin',
        'desc'   => 'Displays Weiqi (also named Go game or Baduk) diagrams',
        'url'    => 'http://wiki.splitbrain.org/plugin:weiqi',
      );
    }
    
    function getType() { return 'protected'; }
    function getAllowedTypes() { return array('formatting', 'disabled'); }
    function getPType(){ return 'block';}
    function getSort() { return 999; }
    function connectTo($mode) {
        $pattern = '<'.$this->syntax_tag.'.*?>(?=.*?</'.$this->syntax_tag.'>)';
        $this->Lexer->addEntryPattern($pattern,$mode,'plugin_weiqi');
    }
    function postConnect() {
        $this->Lexer->addExitPattern('</'.$this->syntax_tag.'>','plugin_weiqi');
    }
    function handle($match, $state, $pos, &$handler) {
        if ($state == DOKU_LEXER_UNMATCHED) {
            $parser = new weiqi_parser();
            $parser->set_conf($this->conf);
            $parsed = $parser->parse($match);
            if (!$parser->error) return array($state, $parsed);
            else {
                switch ($parser->error_code) {
                    case WEIQI_ERROR_BAD_ATTRIBUTES :
                        $message = $this->lang['weiqi bad attributes']
                            .' ('.trim($parser->error_data['attributes_str']).')<br />';
                        $bad_attributes = '';
                        foreach( $parser->error_data['errors'] as $key => $value) {
                            if ($value == '') {
                                $bad_attributes.= ', '.$key
                                .' '.$this->lang['weiqi not allowed'];
                            } else {
                                $bad_attributes.= ', '.$value
                                .' '.$this->lang['weiqi not allowed for'].' '.$key;
                            }
                        }
                        $message.= trim(trim($bad_attributes, ','));
                        break;
                    case WEIQI_ERROR_ONE_CAPTION :
                        $message = $this->lang['weiqi one caption'];
                        break;
                    case WEIQI_ERROR_RECTANGULAR :
                        $message = $this->lang['weiqi rectangular'];
                        break;
                    default : $message = $this->lang['weiqi unknown error'];
                }
                return array($state, array(), $message);
            }
        } else return array($state);
    }
    function render($mode, &$renderer, $data) {
        if ($mode == 'xhtml') {
            list($state, $goban_data, $message) = $data;
            switch ($state) {
                case DOKU_LEXER_ENTER :
                    $renderer->doc .= '<div class="weiqi">';
                    return true;
                case DOKU_LEXER_UNMATCHED :
                    if ($message!='') {
                        $renderer->doc.= '<div class="error">';
                        $renderer->doc.= $this->lang['weiqi error'].': '.$message;
                        $renderer->doc.= '</div>';
                        // no need to display the goban if something is wrong
                        // so we stop here
                        return true;
                    }
                    $parser = new weiqi_parser();
                    $parser->set_conf($this->conf);
                    $renderer->doc .= $parser->render($goban_data);
                    return true;
                case DOKU_LEXER_EXIT :
                    $renderer->doc .= "</div>";
                    return true;
            }
        }
        return false;
    }
}
