<?php
/**
 * Songlist Plugin: Extract and generate a list of songs from a given page, the songs are indexed by IDs.
 *
 * Syntax:     <songlist {src=]page>
 *   src    the page that contains the lines of the form
 *          text to be inserted on a line|ID
 * 
 * @license    GPL v2+ (http://www.gnu.org/licenses/gpl.html)
 * @author     Reinhold Kainhofer <reinhold@kainhofer.com>
 */

if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
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_songlist extends DokuWiki_Syntax_Plugin {
    /**
     * return some info
     */
    function getInfo(){
      return array(
        'author' => 'Reinhold Kainhofer',
        'email'  => 'reinhold@kainhofer.com',
        'date'   => '2008-09-03',
        'name'   => 'Songlist Plugin',
        'desc'   => 'Automatically generate a list with lines taken from a master page. Each song is identified by an ID. 
                     Syntax: <songlist src=pagename>',
        'url'    => 'http://wiki.splitbrain.org/plugin:songlist',
      );
    }

    function getType(){ return 'substition';}
    function getAllowedTypes() { return array('container','substition','protected','disabled','formatting','paragraphs'); }
    function getPType(){ return 'block';}

    function getSort(){ return 999; }

    /** Connect pattern to lexer */
    function connectTo($mode) {
        $this->Lexer->addSpecialPattern('<songlist\s*.*?>.*?</songlist.*?>',$mode,'plugin_songlist');
    }

    function normalize_id($id) {
      return preg_replace("/[,'!?.\ ]/", "", strtolower ($id) );
    }

    /**
     * Handle the match
     */
    function handle($match, $state, $pos, &$handler){
        //
        global $entrymap;
        //
        switch ($state) {
            case DOKU_LEXER_SPECIAL:
                if ( preg_match( "/^<songlist\s*(?:src=|)\"?([^ ]*?)\"?\s*>/", $match, $matches ) ) {
                  $filename=$matches[1];
                  $entrymap = $this->readPatternFile( $filename, $entrymap );
                }
                $data = $match;
                $data = preg_replace( ":\</?songlist.*?\>:", "", $data );
                $line = strtok( $data, "\n" );
                while ($line !== false ) {
                  $id = $this->normalize_id ($line);
                  if ( $entrymap[$id] ) {
                    $result .= $entrymap[$id]."\n";
                  } else {
                    $result .= $line."\n";
                  }
                  $line = strtok( "\n" );
                }
                return array( $state, $result );
                break;
        }
        return false;
    }

    /**
     * Create output
     */
    function render($mode, &$renderer, $indata) {
      //
      if($mode == 'xhtml'){
          list($instr, $data) = $indata;
          switch ($instr) {
          case DOKU_LEXER_SPECIAL:
              $renderer->doc .= p_render( 'xhtml', p_get_instructions($data), $info );
              break;
        }
        return true;
      }
      return false;
    }

    function readPatternFile( $pagename, $tmp )
    {
      $replacements = $tmp;
      $pages = array( $pagename );
      $loadedPages = array();
      foreach( $pages as $page )
      {
        $page = cleanID( $page );
        //
        // don't read in pages that were already read
        if( in_array( $page, $loadedPages ) ) continue;
        $loadedPages[] = $page;
        //
        // Only use pages that the user is allowed to read
        if ( auth_quickaclcheck( $page ) < AUTH_READ ) continue;
        //
        // get the actual filename and load it into the array
        $filename = wikiFN( $page );
        if( !file_exists( $filename ) ) continue;
        //
        // Read all lines from the file and parse them
        $handle = fopen ( $filename, "r" );
        while ( !feof($handle) ) {
          $buffer = fgets( $handle, 4096 );
          if ( preg_match( "/^(.*)\|([-a-zA-Z0-9_ ,!?ßäöüÄÖÜ']+)\n?$/", $buffer, $matches ) ) {
            $id = $this->normalize_id ($matches[2]);
            $replacements[$id] = $matches[1];
          }
        }
      }
      return $replacements;
    }
}
