<?php
/**
 * patTemplate-function inject configuration value
 *
 * @package ValueAce
 * @subpackage patTemplate
 * @author gERD Schaufelberger <gerd@php-tools.net>
 */

WBClass::load(
    'patTemplate_Module'
    , 'patTemplate_Function'
    , 'WBConfig');

/**
 * patTemplate-function inject configuration value
 *
 * Override Wombat's config modifier in order to select data from customer
 *
 * @version 0.5.2
 * @package ValueAce
 * @subpackage patTemplate
 */
class patTemplate_Function_Config extends patTemplate_Function
{
    /**
     * Name of the function
     * @access protected
     * @var string
     */
    public $_name  =   'config';

    /**
     * tell that this function must not be executed during runtime
     * @var string
     */
    public $_type = PATTEMPLATE_FUNCTION_RUNTIME;

    /**
     * Configuration Object
     * @var WBConfig
     */
    private static $CONFIG;

    /**
     * Customer Access
     * @var ValueAce_Customer
     */
    private static $CUSTOMER;

    /**
     * Configuration Object
     * @var WBConfig
     */
    private $config;

    /**
     * Customer Access
     * @var ValueAce_Customer
     */
    private $customer;

    /**
     * Dictionary URL
     * @var WBDictionary_URL
     */
    private $dict;

    /**
     * Constructor
     *
     */
    public function __construct()
    {
        if (empty(self::$CONFIG)) {
            self::$CONFIG   =   WBClass::create('WBConfig');
            if (WBClass::load('ValueAce_Customer')) {
                self::$CUSTOMER =   WBClass::create('ValueAce_Customer');
            }
        }

        $this->config   =   self::$CONFIG;
        $this->customer =   self::$CUSTOMER;
    }

    /**
     * Call the function
     *
     * @param array $params parameters of the function (= attributes of the tag)
     * @param string $content inside tag
     * @return string content to insert into the template
     */
    public function call($params, $content)
    {
        if (empty($params['mode'])) {
            // html or tex
            $params['mode']   =   'html';
        }
        if (empty($params['config'])) {
            $params['config']   =   'info';
        }
        if (empty($params['default'])) {
            $params['default']  =   '';
        }
        if (empty($params['addvar'])) {
            $params['addvar']  =   '';
        }
        if (!isset($params['output'])) {
            $params['output']  =   1;
        }

        $this->config->load($params['config']);
        if ('info' != $params['config'] || empty($this->customer)) {
            $value  =   $this->call4Config($params, $content);
        }
        else {
            $value  =   $this->call4Customer($params, $content);
        }

        // add template var
        if (!empty($params['addvar'])) {
            $this->tmplRef->addGlobalVar($params['addvar'], $value);
        }

        // avoid output
        if (1 > $params['output']) {
            return '';
        }

        return $value;
    }

    /**
     * Call 4 Customer
     *
     * @param array $params parameters of the function (= attributes of the tag)
     * @param string $content inside tag
     * @return string content to insert into the template
     */
    private function call4Customer($params, $content)
    {
        $iCustomer  =   $this->config->get('general/customer', '');
        if (empty($iCustomer)) {
            return $this->call4Config($params, $content);
        }

        $data   =   $this->customer->get($iCustomer);
        if (empty($data)) {
            return $this->call4Config($params, $content);
        }

        /*
        <address>
            <label>
                <item>Tim Fisch</item>
                <item>Kingfisher</item>
                <item>Am Hafen 14</item>
                <item>27298 Helgoland</item>
                <item nls:translate="1" nls:domain="wombat">Germany</item>
            </label>
        </address>
        <contact>
            <phone>+49 123 123456</phone>
            <email>timfisch@Kingfisher.de</email>
        </contact>
        <legal>
            <ustid></ustid>
        </legal>
        <bank>
            <name></name>
            <bix></bic>
            <iban></iban>
        </bank>
        */

        $value  =   '';
        switch ($content) {
            case 'general/name':
                $value  =   $data['customer'];
                break;

            case 'general/shortname':
                $value  =   $data['shortname'];
                break;

            case 'general/tagline':
                $value  =   $data['tagline'];
                break;

            case 'general/ceo':
                $value  =   $data['ceo'];
                break;

            case 'general/address/label':
                $value  =   $data['billaddresslabel'];
                /** @var WBDictionary_Country */
                $dict   =   WBClass::create('WBDictionary_Country');
                $dict->load($data['country']);
                $value  .=   "\n" . $dict->getWord();
                break;

            case 'general/address/street':
                $value  =   $data['billaddresslabel'];
                $value  =   explode("\n", $value);
                array_pop($value);
                $value  =   array_pop($value);
                break;

            case 'general/address/city':
                $value  =   $data['billaddresslabel'];
                $value  =   explode("\n", $value);
                $value  =   array_pop($value);
                if(preg_match('/.*\d.*\\s+(.*)$/', $value, $match)) {
                    $value  =   $match[1];
                }
                break;

            case 'general/address/zip':
                $value  =   $data['billaddresslabel'];
                $value  =   explode("\n", $value);
                $value  =   array_pop($value);
                if(preg_match('/(.*\d.*)\\s+/', $value, $match)) {
                    $value  =   $match[1];
                }
                break;

            case 'general/address/country':
                /** @var WBDictionary_Country */
                $dict   =   WBClass::create('WBDictionary_Country');
                $dict->load($data['country']);
                $value  =   $dict->getWord();
                break;

            case 'general/contact/forename':
                $value  =   $data['contactforename'];
                break;

            case 'general/contact/surname':
                $value  =   $data['contactsurname'];
                break;

            case 'general/contact/phone':
                $value  =   $data['contactphone'];
                break;

            case 'general/contact/email':
                $value  =   $this->getFromUrlId($data['contactemailurlid']);
                break;

            case 'general/legal/register/no';
                $value  =   $data['register'];
                break;
            case 'general/legal/register/place';
                $value  =   $data['registerplace'];
                break;

            case 'general/legal/ustid';
            case 'general/legal/taxvatno';
                $value  =   $data['taxvatno'];
                break;

            case 'general/legal/stnr';
            case 'general/legal/taxno';
                $value  =   $data['taxno'];
                break;

            case 'general/bank/name':
                $value  =   $data['bankname'];
                break;

            case 'general/bank/bic':
                $value  =   $data['bankbic'];
                break;

            case 'general/bank/iban':
                $value  =   $data['bankiban'];
                break;

            case 'general/www':
                $value  =   $data['urlid'];
                $value  =   $this->getFromUrlId($data['urlid'], '[[SERVER]][[SELF]]');
                $value  =   explode('://', $value);
                array_shift($value);
                $value  =   implode('://', $value);
                $value  =   trim($value, '/');
                break;

            case 'general/logo':
                $value  =   $data['vfsfid'];
                break;

            case 'general/colour/em':
                $value  =   ltrim($data['colourem'], '#');
                break;
            case 'general/colour/mute':
                $value  =   ltrim($data['colourmute'], '#');
                break;

            default:
                break;
        }

        $value  =   trim($value);

        if (empty($value)) {
            return $this->call4Config($params, $content);
        }
        $this->quote($value, $params);
        return $this->finishValue($value, $params);
    }

    /**
     * Call 4 Config
     *
     * @param array $params parameters of the function (= attributes of the tag)
     * @param string $content inside tag
     * @return string content to insert into the template
     */
    private function call4Config($params, $content)
    {
        $value  =   $this->config->get($content, $params['default']);
        switch ($content) {
            case 'general/www':
                $value  =   '[[SERVER]][[SELF]]';
                break;

            case 'general/colour/em':
                $value  =   ltrim($value, '#');
                if (empty($value)) {
                    $value  =   '000000';
                }
                break;

            case 'general/colour/mute':
                $value  =   ltrim($value, '#');
                if (empty($value)) {
                    $value  =   '707070';
                }
                break;

            default:
                break;
        }

        $this->quote($value, $params);
        return $this->finishValue($value, $params);
    }

    private function finishValue($value, $params)
    {
        if (empty($value)) {
            return '';
        }
        if (is_scalar($value)) {
            $value  =   array_map('trim', explode("\n", $value));
        }
        if (empty($params['format'])) {
            $params['format']   =   '%s';
        }
        if (empty($params['glue'])) {
            $params['glue']   =   "<br />\n";
        }
        else {
            // make newline available
            $sear   =   array();
            $sear[] =   '\\\\newline';
            $sear[] =   '\\\\n';
            $sear[] =   '\\\\';
            $repl   =   array();
            $repl[] =   '\\newline';
            $repl[] =   "\n";
            $repl[] =   '\\';
            $params['glue'] =   str_replace($sear, $repl, $params['glue']);
        }

        $out    =   array();
        foreach ($value as $k => $v) {
            $out[]  =   sprintf($params['format'], $v);
        }

        return implode($params['glue'], $out);
    }

    private function quote(&$value, $params = array())
    {
        // don't do a thing if not in TeX mode
        if ('tex' != strtolower($params['mode'])) {
            return;
        }

        // don't force string replace on numbers
        if (is_numeric($value)) {
            return;
        }

        // string replace
        $replace    =   array(
                        '"'         =>  "''",
                        "\r\n"      => "\n",
                        '%'         => '\\%',
                        '&nbsp;'    => '~',
                        '&'         => '\\&',
                        '_'         => '\\_',
                        '€'         => '\\EUR',
                        '°'         => '{\\textdegree}',
                        '&reg;'     => '®',
                        '&lt;'      => '<',
                        '&gt;'      => '>',
                        '&ge;'      => '$\ge$',
                        '&le;'      => '$\le$',
                        '&shy;'     => '\\-'
                    );
        $sear   =   array_keys($replace);
        $repl   =   array_values($replace);
        $value  =   str_replace($sear, $repl, $value);
    }

    private function getFromUrlId($id, $default = '')
    {
        $id =   trim($id);
        if (empty($id)) {
            return $default;
        }

        if (empty($this->dict)) {
            $this->dict =   WBClass::create('WBDictionary_URL');
        }

        $this->dict->load($id);
        return $this->dict->getWord();
    }
}