<?php
/*  $Id: PhDHelper.class.php 281268 2009-05-28 07:35:09Z cweiske $ */

/**
* Base class for PhDTheme
*/
class PhDHelper
{
    /**
    * Array of all ids as key and their "attributes" (not xml-atts)
    * as array.
    * Created by mktoc.php
    *
    * @var array
    */
    private $IDs = array();

    /**
    * Array of &lt;refname&gt; tag contents as key,
    * and the ID of the section they appear in as value.
    * Created by mktoc.php
    *
    * @var array
    */
    private $refs = array();

    private $classes        = array();
    private $vars           = array();

    /* abstract */ protected $elementmap  = array();
    /* abstract */ protected $textmap     = array();
    private static $autogen         = array();

    /**
    * Array of highlighter objects
    * Key is the format, value the object
    *
    * @var array
    */
    private static $highlighters = array();



    /**
    * Creates the helper object.
    *
    * @param array $a Array with ID array as first value, ref array as second.
    *
    * @see $IDs
    * @see $refs
    */
    public function __construct(array $a) {
        $this->IDs = $a[0];
        $this->refs = $a[1];
        $this->classes = $a[2];
        $this->vars    = $a[3];
    }

    /**
    * When the tag associated with that $id is to be chunked,
    * the filename (without extension) is returned.
    *
    * @param string $id ID of an element
    *
    * @return mixed Filename without extension (string) or false if the element
    *               is not to be chunked
    *
    * @see $IDs
    */
    final public function getFilename($id)
    {
        return isset($this->IDs[$id]) ? $this->IDs[$id]["filename"] : false;
    }

    final public function getDescription($id, $long = false) {
        return $long ?
            ($this->IDs[$id]["ldesc"] ? $this->IDs[$id]["ldesc"] : $this->IDs[$id]["sdesc"]) :
            ($this->IDs[$id]["sdesc"] ? $this->IDs[$id]["sdesc"] : $this->IDs[$id]["ldesc"]);
    }

    /**
    * Returns an array of direct children tags with IDs.
    *
    * @param string $id ID of an element
    *
    * @return array Array of children IDs (empty array when no kids)
    *
    * @see $IDs
    */
    final public function getChildren($id)
    {
        return $this->IDs[$id]["children"];
    }

    /**
    * Returns the toc entry of the given ID.
    *
    * @param string $id ID of an element
    *
    * @return array toc entry array
    *
    * @see $IDs
    */
    final public function getSelf($id)
    {
        return $this->IDs[$id];
    }

    /**
    * Returns ID of the first parental block tag with an ID.
    *
    * @param string $id ID of an element
    *
    * @return string ID of the parent tag
    *
    * @see $IDs
    */
    final public function getParent($id)
    {
        return $this->IDs[$id]["parent"];
    }

    /**
    * Returns the id of the reference page for a given function/method/class.
    *
    * @param string $ref Name of referenced object (e.g. "$class", "$class-$method")
    *
    * @return mixed ID (string) of reference page or null if not found.
    *
    * @see $refs
    */
    public function getRefnameLink($ref)
    {
        return isset($this->refs[$ref]) ? $this->refs[$ref] : null;
    }

    public function getClassnameLink($class) {
        return isset($this->classes[$class]) ? $this->classes[$class] : null;
    }
    public function getVarnameLink($var) {
        return isset($this->vars[$var]) ? $this->vars[$var] : null;
    }

    final public function getElementMap() {
        return $this->elementmap;
    }
    final public function getTextMap() {
        return $this->textmap;
    }

    /**
    * Reads $phddir/include/langs/$lang.xml and returns the translation
    * for the given $text.
    *
    * @note
    * This function is used only internally, it has nothing to do with the
    * manual content. Used e.g. for autogenerated table of contents titles.
    *
    * @param string $text Text to translate ("warning", "toc", "by")
    * @param string $lang Two-letter ISO code of language (de, en, ..)
    *
    * @return string Translated text
    */
    final public function autogen($text, $lang)
    {
        if (isset(PhDHelper::$autogen[$lang])) {
            return PhDHelper::$autogen[$lang][$text];
        }

        $filename = dirname(__FILE__) ."/langs/$lang.xml";
        $r = new XMLReader;
        if (!file_exists($filename) || !$r->open($filename)) {
            if ($lang == "en") {
                throw new Exception("Cannot open $filename");
            }
            return $this->autogen($text, "en");
        }
        $autogen = array();
        while ($r->read()) {
            if ($r->nodeType != XMLReader::ELEMENT) {
                continue;
            }
            if ($r->name == "term") {
                $r->read();
                $k = $r->value;
                $autogen[$k] = "";
            } else if ($r->name == "simpara") {
                $r->read();
                $autogen[$k] = $r->value;
            }
        }
        PhDHelper::$autogen[$lang] = $autogen;
        return PhDHelper::$autogen[$lang][$text];
    }

    /**
    * Highlight (color) the given piece of source code
    *
    * @param string $text   Text to highlight
    * @param string $role   Source code role to use (php, xml, html, ...)
    * @param string $format Format to highlight (pdf, xhtml, troff, ...)
    *
    * @return string Highlighted code
    */
    public function highlight($text, $role = 'php', $format = 'xhtml')
    {
        if (!isset(self::$highlighters[$format])) {
            $class = $GLOBALS['OPTIONS']['highlighter'];

            if (!class_exists($class, true)) {
                if ($class == 'PhDHighlighter') {
                    //hard coded path for phdhighlighter, since phd doesn't follow
                    // pear file conventions
                    require_once dirname(__FILE__) . '/PhDHighlighter.class.php';
                } else {
                    //simple autoload replacement for pear-style classes
                    require_once str_replace('_', '/', $class) . '.php';
                }

                if (!class_exists($class, false)) {
                    trigger_error(
                        'Highlighter class ' . $class . ' is not available',
                        E_USER_ERROR
                    );
                }
            }
            self::$highlighters[$format] = call_user_func(
                array($class, 'factory'), $format
            );

        }

        return self::$highlighters[$format]->highlight(
            $text, $role, $format
        );
    }//public function highlight(..)
}

/*
 * vim600: sw=4 ts=4 fdm=syntax syntax=php et
 * vim<600: sw=4 ts=4
 */

