<?php
/**
 * Block::
 *
 * $Horde: horde/lib/Block.php,v 1.16 2003/06/06 22:28:26 chuck Exp $
 *
 * @package horde.block
 */
class Horde_Block {

    /**
     * Block specific parameters.
     *
     * @var array $_params
     */
    var $_params = array();

    /**
     * Application that this block originated from.
     *
     * @var string $_app
     */
    var $_app;

    /**
     * The type of this block.
     * Possible values depend on the subclass inherited
     * from Horde_Block.
     *
     * @var string $_type
     */
    var $_type;

    /**
     * The number of rows this block spans.
     *
     * @var integer $_height
     */
    var $_height;

    /**
     * The number of cols this block spans.
     *
     * @var integer $_width
     */
    var $_width;

    /**
     * Constructor
     */
    function Horde_Block()
    {
    }

    /**
     * Sets the height of this block.
     *
     * @param integer $val  The height to set.
     */
    function setHeight($val)
    {
        $this->_height = intval($val);
    }

    /**
     * Returns the height of this block.
     *
     * @return integer  The height of this block.
     */
    function getHeight()
    {
        return empty($this->_height) ? 1 : $this->_height;
    }

    /**
     * Sets the width of this block.
     *
     * @param integer $val  The width to set.
     */
    function setWidth($val)
    {
        $this->_width = intval($val);
    }

    /**
     * Returns the width of this block.
     *
     * @return integer  The width of this block.
     */
    function getWidth()
    {
        return empty($this->_width) ? 1 : $this->_width;
    }

    /**
     * Returns the application that this block is from.
     *
     * @return string  The application name.
     */
    function getApp()
    {
        return $this->_app;
    }

    /**
     * Return the type of this block. This type is unique to
     * the application only.
     *
     * @return string  The block type
     */
    function getType()
    {
        return $this->_type;
    }

    /**
     * Does this block have any user editable parameters?
     *
     * @return boolean  True is there are editable paramters
     *                  False if there are not
     */
    function isEditable()
    {
        return false;
    }

    /**
     * HTML of this block for editing, has arrows to move block and
     * fields to allow editing of values.
     */
    function displayLayoutBlock($url, $col, $row, $blocks, $edit = true)
    {
        global $registry;
        $form_url = $url;
        $url = Horde::addParameter($url, 'col', $col);
        $url = Horde::addParameter($url, 'row', $row);
        $thisblock = $blocks[$this->_app][$this->_type];
    ?>
        <table border="0" cellspacing="0" width="100%">
          <tr class="header">
            <td><?php echo $registry->getParam('name', $this->getApp()); ?> : <?php echo $blocks[$this->getApp()][$this->getType()]['name'] ?></td>
            <td align="right">
                <?php Horde::plink(Horde::addParameter($url, 'action', 'edit'), _("Edit Block"), 'light', '', '', _("Edit Block")) ?>
                    <?php echo _("Edit") ?>
                </a>

                <?php Horde::plink(Horde::addParameter($url, 'action', 'remove'), _("Remove Block"), '', '', '', _("Remove Block")) ?>
                    <?php Horde::pimg('block/close.gif', _("Remove Block")) ?>
                </a>
            </td>
          </tr>
          <tr>
            <td colspan="2" class="summarytext" valign="middle" align="center">
                <?php if ($row > 0): ?>
                <?php Horde::plink(Horde::addParameter($url, 'action', 'expand-top'), _("Expand"), '', '', '', _("Expand")) ?>
                    <?php Horde::pimg('block/shrink.gif', _("Expand")) ?>
                </a>
                <?php endif; ?>

                <?php if ($this->getHeight() > 1) :?>
                <?php Horde::plink(Horde::addParameter($url, 'action', 'shrink-top'), _("Shrink"), '', '', '', _("Shrink")) ?>
                    <?php Horde::pimg('block/expand.gif', _("Shrink")) ?>
                </a>
                <?php endif; ?>
            </td>
          </tr>
          <tr>
            <td colspan="2" class="summarytext" valign="middle" align="center">
                <table width="100%">
                  <tr>
                    <td rowspan="3" width="50%">
                        <?php if ($col > 0): ?>
                            <?php Horde::plink(Horde::addParameter($url, 'action', 'expand-left'), _("Expand"), '', '', '', _("Expand")) ?>
                                <?php Horde::pimg('block/large_left.gif', _("Expand")) ?>
                            </a>
                        <?php endif; ?>
                        <?php if ($this->getWidth() > 1) :?>
                            <?php if ($col > 0): ?>
                                <br/>
                            <?php endif; ?>
                            <?php Horde::plink(Horde::addParameter($url, 'action', 'shrink-left'), _("Shrink"), '', '', '', _("Shrink")) ?>
                                <?php Horde::pimg('block/large_right.gif', _("Shrink")) ?>
                            </a>
                        <?php endif; ?>
                    </td>
                    <td>&nbsp;</td>
                    <td>
                    <?php if ($row > 0): ?>
                        <?php Horde::plink(Horde::addParameter($url, 'action', 'up'), _("Move Up"), '', '', '', _("Move Up")) ?>
                            <?php Horde::pimg('block/up.gif', _("Move Up")) ?>
                        </a>
                    <?php else: ?>
                        <?php Horde::pimg('block/up.gif') ?>
                    <?php endif; ?>
                    </td>
                    <td>&nbsp;</td>
                    <td rowspan="3" width="50%" align="right">
                        <?php if ($this->getWidth() > 1) :?>
                            <?php Horde::plink(Horde::addParameter($url, 'action', 'shrink-right'), _("Shrink"), '', '', '', _("Shrink")) ?>
                                <?php Horde::pimg('block/large_left.gif', _("Shrink")) ?>
                            </a><br/>
                        <?php endif; ?>
                        <?php Horde::plink(Horde::addParameter($url, 'action', 'expand-right'), _("Expand"), '', '', '', _("Expand")) ?>
                            <?php Horde::pimg('block/large_right.gif', _("Expand")) ?>
                        </a>
                    </td>
                  </tr>
                  <tr>
                    <td>
                    <?php if ($col > 0): ?>
                        <?php Horde::plink(Horde::addParameter($url, 'action', 'left'), _("Move Left"), '', '', '', _("Move Left")) ?>
                            <?php Horde::pimg('block/left.gif', _("Move Left")) ?>
                        </a>
                    <?php else: ?>
                        <?php Horde::pimg('block/left.gif') ?>
                    <?php endif; ?>
                    </td>
                    <td><?php Horde::pimg('block/add.gif') ?></td>
                    <td>
                        <?php Horde::plink(Horde::addParameter($url, 'action', 'right'), _("Move Right"), '', '', '', _("Move Right")) ?>
                            <?php Horde::pimg('block/right.gif', _("Move Right")) ?>
                        </a>
                    </td>
                  </tr>
                  <tr>
                    <td>&nbsp;</td>
                    <td>
                        <?php Horde::plink(Horde::addParameter($url, 'action', 'down'), _("Move Down"), '', '', '', _("Move Down")) ?>
                            <?php Horde::pimg('block/down.gif', _("Move Down")) ?>
                        </a>
                    </td>
                    <td>&nbsp;</td>
                  </tr>
                </table>
            </td>
          </tr>
          <tr>
            <td colspan="2" class="summarytext" valign="middle" align="center">
                <?php if ($this->getHeight() > 1) :?>
                <?php Horde::plink(Horde::addParameter($url, 'action', 'shrink-bottom'), _("Shrink"), '', '', '', _("Shrink")) ?>
                    <?php Horde::pimg('block/shrink.gif', _("Shrink")) ?>
                </a>
                <?php endif; ?>

                <?php Horde::plink(Horde::addParameter($url, 'action', 'expand-bottom'), _("Expand"), '', '', '', _("Expand")) ?>
                    <?php Horde::pimg('block/expand.gif', _("Expand")) ?>
                </a>
            </td>
          </tr>
        </table>
<?php if ($edit): ?>
        <table border="0" cellspacing="0" width="100%">
          <tr>
            <td colspan="2" class="summarytext" valign="middle" align="left">
                <form action="<?php echo $form_url ?>" method='post' name="blockform">
                    <?php Horde::pformInput() ?>
                    <input type="hidden" name="row" value="<?php echo $row ?>" />
                    <input type="hidden" name="col" value="<?php echo $col ?>" />
                    <input type="hidden" name="action" value="save" />
                    <table>
<?php
                    $options = '';
                    foreach ($blocks as $app => $appblocks):
                        if (is_a($appblocks, 'PEAR_Error')) {
                            continue;
                        }
                        $sel = (boolean)($app == $this->getApp());
                        foreach ($appblocks as $blockid => $appblock):
                        if (($sel && $this->_type == $blockid)) {
                            $selstr = 'selected="selecled"';
                        } else {
                            $selstr = '';
                        }
                        $options .= sprintf('<option value="%s:%s"%s>%s: %s</option>%s',
                                            $app,
                                            $blockid,
                                            $selstr,
                                            $registry->getParam('name', $app),
                                            $appblock['name'],
                                            "\n");
                        endforeach;
                    endforeach;

                    $widget = '<select name="app" onchange="document.blockform.action.value=\'save-resume\';document.blockform.submit()">' . $options . '</select>';
                    echo sprintf("<tr><td><b>%s:</b>&nbsp;</td><td>%s</td></tr>\n", _("Block Type") , $widget);

                    if ($this->isEditable()):
                        echo sprintf("<tr><td colspan='2'><br/><b>%s</b></tr>\n", _("Block Parameters"));
                        foreach ($thisblock['params'] as $paramid => $param):
                            echo sprintf("<tr><td valign='top'><b>%s:</b>&nbsp;</td><td valign='top'>", $param['name']);
                            switch ($param['type']):
                                case 'enum':
                                    $options = '';
                                    $val = array_key_exists($paramid, $this->_params) ? $this->_params[$paramid]: '';
                                    foreach ($param['values'] as $key => $name) {
                                        $sel = ($val == $key) ? 'selected="selected"' : '';
                                        if (strlen($name) > 30) {
                                            $name = substr($name, 0, 27) . '...';
                                        }
                                        $options .= sprintf('<option value="%s" %s>%s</option>%s', $key, $sel, $name, "\n");
                                    }

                                    echo sprintf('<select name="params[%s]">%s</select>%s', $paramid, $options, "\n");
                                    break;

                                case 'mlenum':
                                    // Multi-level enum.
                                    $val = '';
                                    if (array_key_exists($paramid, $this->_params)) {
                                        $val = $this->_params[$paramid];
                                    } else {
                                        $val = array_keys(current($param['values']));
                                        $val = current($val);
                                    }

                                    $thisvalues = array();
                                    if (array_key_exists('__' . $paramid, $this->_params)) {
                                        $thisvalues = $param['values'][$this->_params['__' . $paramid]];
                                        if (!array_key_exists($val, $thisvalues)) {
                                            $val = current(array_keys($thisvalues));
                                        }
                                    }

                                    $options = '';
                                    foreach ($param['values'] as $key => $values) {
                                        $sel = '';
                                        if (array_key_exists($val, $values)) {
                                            $thisvalues = $values;
                                            $sel = ' selected="selected"';
                                        }
                                        $name = strlen($key) > 30 ? substr($key, 0, 27) . '...' : $key;
                                        $options .= sprintf('<option value="%s"%s>%s</option>%s', $key, $sel, $name, "\n");
                                    }
                                    echo sprintf('<select name="params[__%s]" onchange="document.blockform.action.value=\'save-resume\';document.blockform.submit()">%s</select>%s', $paramid, $options, "<br/>\n");

                                    $options = '';
                                    asort($thisvalues);
                                    foreach ($thisvalues as $key => $name) {
                                        $sel = ($val == $key) ? 'selected="selected"' : '';
                                        $name = (strlen($name) > 30) ? substr($name, 0, 27) . '...' : $name;
                                        $options .= sprintf('<option value="%s" %s>%s</option>%s', $key, $sel, $name, "\n");
                                    }
                                    echo sprintf('<select name="params[%s]">%s</select>%s', $paramid, $options, "<br/>\n");
                                    break;

                                case 'color':
                                    $val = array_key_exists($paramid, $this->_params) ? $this->_params[$paramid] : '';
                                    echo sprintf('<input style="background-color:%s" type="text" name="params[%s]" value="%s" />', $val, $paramid, $val);
                                    $url  = $registry->getParam('webroot', 'horde');
                                    $url .= Horde::addParameter('/util/colorpicker.php?target=params[' . $paramid . ']', 'form', 'blockform');
                                    echo sprintf('<a href="%s" onclick="window.open(\'%s\', \'colorpicker\', \'toolbar=no,location=no,status=no,scrollbars=no,resizable=no,width=120,height=250,left=100,top=100\'); return false;" onmouseout="window.status=\'\';" onmouseover="window.status=\'%s\'; return true;" class="widget" target="colorpicker">',
                                        $url, $url, _("Color Picker"));
                                    echo Horde::img('colorpicker.gif', _("Color Picker"), 'height="16"', $registry->getParam('graphics', 'horde'));
                                    echo '</a>';
                                    break;

                                case 'string':
                                default:
                                    $val = array_key_exists($paramid, $this->_params) ? $this->_params[$paramid] : '';
                                    echo sprintf('<input type="text" name="params[%s]" value="%s" />', $paramid, $val);
                                    break;

                            endswitch;
                            echo "</td></tr>\n";
                        endforeach;
                    endif;
?>
                    </table>
                    <br/><input type="submit" class="button" value="Save" />
                </form>
            </td>
          </tr>
        </table>
<?php
        endif;
    }

    /**
     * Return the text to go in the title of this block.This function handles
     * the changing of current application as needed so code is executed in
     * the scope of the application the block originated from.
     *
     * @return string   The title text
     */
    function getTitle()
    {
        global $registry;

        // Switch application contexts, if necessary. Return an
        // error immediately if pushApp() fails.
        $pushed = $registry->pushApp($this->_app);
        if (is_a($pushed, 'PEAR_Error')) {
            return $pushed;
        }

        $title = $this->_title();

        // If we changed application context in the course of this
        // call, undo that change now.
        if ($pushed === true) {
            $registry->popApp();
        }

        return $title;
    }

    /**
     * Get the content for this block. This function handles the changing
     * of current application as needed so code is executed in the scope
     * of the application the block originated from.
     *
     * @return string   The content
     */
    function getContent()
    {
        global $registry;

        // Switch application contexts, if necessary. Return an error
        // immediately if pushApp() fails.
        $pushed = $registry->pushApp($this->_app);
        if (is_a($pushed, 'PEAR_Error')) {
            return $pushed;
        }

        $content = $this->_content();

        // If we changed application context in the course of this
        // call, undo that change now.
        if ($pushed === true) {
            $registry->popApp();
        }

        return $content;
    }

    /**
     * The title to go in this block.
     * This function should be defined in all subclasses of this class.
     *
     * @return string   The title text.
     */
    function _title()
    {
        return _("Title Goes Here!");
    }

    /**
     * The content to go in this block.
     * This function should be defined in all subclasses of this class.
     *
     * @return string   The content
     */
    function _content()
    {
        return _("Content Goes Here!");
    }

}
