<?php

require_once('HTML/QuickForm/textarea.php');

class HTML_QuickForm_htmlarea extends HTML_QuickForm_textarea
{
    /**
     * URL where to find htmlarea
     *
     * @var string
     * @access private
     */
    var $_url = './htmlarea/';
    
    /**
     * Language of HTMLArea
     *
     * @var string
     * @access private
     */
    var $_lang = 'en';
    
    /**
     * Configuration array for HTMLArea
     *
     * @var array
     * @access private
     */
    var $_config = array();
    
    /**
     * Additional buttons for HTMLArea
     *
     * @var array
     * @access private
     */
    var $_buttons = array();
    
    /**
     * Additional buttons of standard toolbar
     *
     * @var array
     * @access private
     */
    var $_toolbar = array();
    
    /**
     * Registered Plugins
     *
     * @var array
     * @access private
     */
    var $_plugins = array();
    
    /**
     * Class constructor
     *
     * @param   string  Htmlarea name/id
     * @param   string  Htmlarea label
     * @param   string  Attributes for the textarea
     * @param   array   Options for htmlarea
     * @access  public
     * @return  void
     */
    function HTML_QuickForm_htmlarea($elementName=null, $elementLabel=null, $options = array(), $attributes=null)
    {
        HTML_QuickForm_element::HTML_QuickForm_element($elementName, $elementLabel, $attributes);
        $this->_persistantFreeze = true;
        $this->_type = 'htmlarea';
        
        if (is_array($options)) {
            foreach ($options as $k => $v) {                
                if (isset($this->{"_$k"}) && method_exists($this, "set$k")) {
                    $this->{"set$k"}($v);
                }
            }
        }
    }
    
    /**
     * Set the url where the htmlarea scripts are located
     *
     * @param string
     * @return void
     */
    function setURL($url)
    {
        if (is_string($url) && strlen($url)) {
            $this->_url = $url;
            if (substr($url, -1) != '/') {
                $this->_url .= '/';
            }
        }
    }
    
    /**
     * Set the htmlarea language
     *
     * @param string
     * @return void
     */
    function setLang($lang)
    {
        if (is_string($lang) && strlen($lang)) {
            $this->_lang = $lang;
        }
    }
    
    /**
     * Set config array for HTMLArea
     *
     * @param mixed Name of config var or array
     * @param mixed Value of config var
     * @access public
     * @return void     
     */
    function setConfig($name, $value = null)
    {
        if (is_array($name)) {
            foreach ($name as $k => $v) {
                $this->_config[$k] = $v;
            }
        } else {
            $this->_config[$name] = $value;
        }
    }

    /**
     * Set Toolbar in config array
     *
     * @param array Array of buttons
     * @access public
     * @return void     
     */
    function setToolbar($buttons)
    {
        if (empty($this->_config['toolbar']) || !is_array($this->_config['toolbar'])) {
            $this->_config['toolbar'] = array();
        }
        if (is_array($buttons) && count($buttons)) {
            $this->_config['toolbar'][] = $buttons;
        }
    }

    /**
     * Register button to HTMLArea
     *
     * @param array Array of buttons
     * @access public
     * @return void     
     */
    function registerButton($id, $tooltip, $image, $textmode, $action)
    {
        $this->_buttons[] = array('id' => $id,
                                  'tooltip' => $tooltip,
                                  'image' => $image,
                                  'textmode' => $textmode,
                                  'action' => $action);
    }
    
    /**
     * Push button to HTMLArea standard toolbar
     *
     * @param string button name
     * @access public
     * @return void     
     */
    function pushButton($name)
    {
        $this->_toolbar[] = $name;
    }
    
    /**
     * Register Plugin to HTMLArea
     *
     * @param string plugin name
     * @param array plugin config
     * @access public
     * @return void     
     */
    function registerPlugin($name, $config = array())
    {
        $this->_plugins[$name] = $config;
    }
    
    /**
     * Return JS representation of config array
     *
     * @access private
     * @return string  
     */
    function _config2JS()
    {
        $name = $this->getAttribute('name');
        $js = '';
        
        // register buttons
        if (count($this->_buttons)) {
            foreach ($this->_buttons as $button) {
                $js .= sprintf("%sConfig.registerButton('%s','%s','%s',%s,%s);\n",
                               $name,
                               $button['id'],
                               $button['tooltip'],
                               $button['image'],
                               ($button['textmode']) ? 'true' : 'false',
                               $button['action']);
            }
        }
        
        // push buttons to standard toolbar
        if (count($this->_toolbar)) {
            $js .= "{$name}Config.toolbar.push([ ";
            $i = 1;
            foreach ($this->_toolbar as $button) {
                $js .= "'$button'";
                if ($i++ < count($this->_toolbar)) {
                    $js .= ', ';
                }
                $js .= " ]);\n";
            }
        }
        
        // output config
        foreach ($this->_config as $k => $v) {
            $js .= "{$name}Config.$k = ";
            $js .= $this->_var2JS($v);
            $js .= ";\n";
        }
        return $js;
    }
    
    function _var2JS($value)
    {
        if (is_array($value)) {
            $value = $this->_array2JS($value);
        } elseif (is_bool($value)) {
            $value = ($value) ? 'true' : 'false';
        } elseif (is_numeric($value)) {
            $value = ($value);
        } else {
            $value = "'$value'";
        }
        return $value;
    }

    /**
     * Return JS representation of an array
     *
     * @access private
     * @return string  
     */
    function _array2JS($value)
    {
        $hash = true;
        if (is_array($value)) {
            $key = key($value);
            if (is_numeric($key) && $key === 0) {
                $hash = false;
            }
            reset($value);
        }
        
        $js  = ($hash) ? '{ ' : '[ ';
        
        $i = 1;
        foreach ($value as $k => $v) {
           if ($hash) { $js .= "'$k' : "; }
           $js .= $this->_var2JS($v);
           if ($i++ < count($value)) {
               $js .= ', ';
           }
        }
        $js .= ($hash) ? ' }' : ' ]';

        return $js;
    }
         
    /**
     * Return the htmlarea in HTML
     *
     * @access public
     * @return string
     */
    function toHtml()
    {
        if ($this->_flagFrozen) {
            return $this->getFrozenHtml();
        } else {
            $name = $this->getAttribute('name');
            $this->updateAttributes(array('id' => $name));
            
            // set config vars
            $pre_js  = "\n<script type=\"text/javascript\">\n";
            $pre_js .= "_editor_url = '$this->_url';\n";
            $pre_js .= "_editor_lang = '$this->_lang';\n";
            $pre_js .= "</script>\n";
            
            // load htmlarea
            $pre_js .= "<script type=\"text/javascript\" src=\"{$this->_url}htmlarea.js\"></script>\n";
            
            // load plugins            
            $pre_js .= "\n<script type=\"text/javascript\">\n";
            foreach ($this->_plugins as $plugin => $config) {                
                $pre_js .= "HTMLArea.loadPlugin('$plugin');\n";
            }
            $pre_js .= "</script>\n";
            
            // setup editor
            $post_js = "\n<script type=\"text/javascript\">\n";                        
            $post_js .= "var {$name}Editor = new HTMLArea('$name');\n";
            
            // register plugins
            foreach ($this->_plugins as $plugin => $config) {                
                $post_js .= "{$name}Editor.registerPlugin($plugin";
                if (count($config)) {
                    $post_js .= "," . $this->_array2JS($config);
                }
                $post_js .= ");\n";
            }
            // set config
            $post_js .= "var {$name}Config = {$name}Editor.config;\n";
            $post_js .= $this->_config2JS();
            $post_js .= "{$name}Editor.generate();\n";
            $post_js .= "</script>\n";        
            
            return $pre_js.parent::toHtml().$post_js;
        }
    }
    
    /**
     * Returns the htmlarea content in HTML
     * 
     * @access public
     * @return string
     */
    function getFrozenHtml()
    {
        return $this->getValue();
    }
}

?>