<?php
/**
 * The Menu:: class provides standardized methods for creating menus in
 * Horde applications.
 *
 * $Horde: horde/lib/Menu.php,v 1.41 2003/08/15 16:31:34 mdjukic Exp $
 *
 * Copyright 1999-2003 Chuck Hagenbuch <chuck@horde.org>
 * Copyright 1999-2003 Jon Parise <jon@horde.org>
 *
 * See the enclosed file COPYING for license information (LGPL). If you
 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
 *
 * @author  Chuck Hagenbuch <chuck@horde.org>
 * @author  Jon Parise <jon@horde.org>
 * @version $Revision: 1.41 $
 * @since   Horde 1.3
 * @package horde
 */
class Menu {

    var $_with_help;
    var $_with_login;
    var $_menufile;

    /**
     * Constructor
     */
    function Menu($with_help = true, $with_login = null)
    {
        /* Default to false if help turned off or no javascript support. */
        if ($GLOBALS['conf']['user']['online_help'] &&
            $GLOBALS['browser']->hasFeature('javascript')) {
            $with_help = false;
        }
        $this->_with_help = $with_help;

        /* If no setting specified for login button, default to true if no
           Horde frameset and false if there is a Horde frameset. */
        if (is_null($with_login)) {
            $this->_with_login = !$GLOBALS['conf']['menu']['display'];
        } else {
            $this->_with_login = $with_login;
        }

        $this->_menufile = $GLOBALS['registry']->getParam('fileroot') . '/config/menu.php';
    }

    /**
     * Store a static variable that can be used to turn accesskeys on
     * or off, and return whether or not we should be using
     * accesskeys.
     *
     * @param optional boolean $use  Turn accesskey use on or off.
     *
     * @return  boolean  If called with no arguments, whether or not we
     *                   should use accesskeys.
     */
    function useAccessKeys($use = null)
    {
        static $accesskeys;
        if (!isset($accesskeys)) {
            $accesskeys = true;
        }

        if (is_null($use)) {
            global $prefs;
            if ($accesskeys &&
                $prefs->getValue('widget_accesskey') &&
                $prefs->getValue('menu_view') != 'icon') {
                return true;
            } else {
                return false;
            }
        }

        $accesskeys = $use;
    }

    /**
     * Generates the HTML for an item on the menu bar.
     *
     * @param string $url       String containing the value for the hyperlink.
     * @param string $text      String containing the label for this menu item.
     * @param optional string $icon   String containing the filename of the image
     *                                icon to display for this menu item.
     * @param optional string $icon_path  If the icon lives in a non-default
     *                                    directory, where is it?
     * @param optional string $target     If the link needs to open in another frame
     *                                    or window, what is its name?
     * @param optional string $onclick    Onclick javascript, if desired.
     * @param optional string $cell_class CSS class for the table cell.
     * @param optional string $link_class CSS class for the item link.
     *
     * @return  string  String containing the HTML to display this menu item.
     */
    function createItem($url, $text, $icon = '', $icon_path = null,
                        $target = '', $onclick = null, $cell_class = null,
                        $link_class = 'menuitem')
    {
        global $conf, $prefs;

        if (is_null($cell_class)) {
            $c = parse_url($_SERVER['PHP_SELF']);
            $l = parse_url($url);

            /* Try to match the item's path against the current script
             * filename as well as other possible URLs to this script.
             */
            if (array_key_exists('path', $l) &&
                ($c['path'] == $l['path'] ||
                 $l['path'] . 'index.php' == $c['path'] ||
                 $l['path'] . '/index.php' == $c['path'])) {
                $cell_class = 'menuselected';
            }
        }
        if ($cell_class === '__noselection') {
            $cell_class = null;
        }
        if (Menu::useAccessKeys()) {
            $accesskey = Horde::getAccessKey($text);
        } else {
            $accesskey = '';
        }

        $html = '<td align="center" nowrap="nowrap" valign="';
        $html .= ($prefs->getValue('menu_view') == 'icon') ? 'middle' : 'bottom';
        $html .= '"';
        $html .= (!empty($cell_class)) ? " class=\"$cell_class\">" : '>';
        $html .= Horde::link($url, $text, $link_class, $target, $onclick, '', $accesskey);

        if (!empty($icon) && ($prefs->getValue('menu_view') == 'icon' || $prefs->getValue('menu_view') == 'both')) {
            $html .= Horde::img($icon, $text, $prefs->getValue('menu_view') == 'icon' ? 'hspace="5" vspace="5"' : '', $icon_path);
            if ($prefs->getValue('menu_view') == 'both') {
                $html .= '<br />';
            }
        }

        if ($prefs->getValue('menu_view') != 'icon') {
            $html .= Horde::highlightAccessKey($text, $accesskey);
        }

        $html .= "</a>&nbsp;</td>\n";

        return $html;
    }

    /**
     * Prints the result of the createItem() function.
     *
     * @param string $url       String containing the value for the hyperlink.
     * @param string $text      String containing the label for this menu item.
     * @param optional string $icon   String containing the filename of the image
     *                                icon to display for this menu item.
     * @param optional string $icon_path  If the icon lives in a non-default
     *                                    directory, where is it?
     * @param optional string $target     If the link needs to open in another frame
     *                                    or window, what is its name?
     * @param optional string $onclick    Onclick javascript, if desired.
     * @param optional string $cell_class CSS class for the table cell.
     * @param optional string $link_class CSS class for the item link.
     */
    function printItem($url, $text, $icon = '', $icon_path = null,
                       $target = '', $onclick = null, $cell_class = null,
                       $link_class = 'menuitem')
    {
        echo Menu::createItem($url, $text, $icon, $icon_path, $target,
                              $onclick, $cell_class, $link_class);
    }

    /**
     * Creates a menu string from a custom menu item.  Custom menu items
     * can either define a new menu item or a menu separate (spacer).
     *
     * A custom menu item consists of a hash with the following properties:
     *
     *  'url'       The URL value for the menu item.
     *  'text'      The text to accompany the menu item.
     *  'icon'      The filename of an icon to use for the menu item.
     *  'icon_path' The path to the icon if it doesn't exist in the graphics/
     *              directory.
     *  'target'    The "target" of the link (e.g. '_top', '_blank').
     *  'onclick'   Any onclick javascript.
     *
     * A menu separator item is simply a string set to 'separator'.
     *
     * @param $item     Mixed parameter containing the custom menu item.
     *
     * @return string   The resulting HTML to display the menu item.
     */
    function customItem($item)
    {
        global $conf;

        $text = '';

        if (is_array($item)) {
            $text = Menu::createItem($item['url'], $item['text'],
                                     @$item['icon'], @$item['icon_path'],
                                     @$item['target'], @$item['onclick']);
        } else {
            if (strcasecmp($item, 'separator') == 0) {
                $text = '<td>&nbsp;</td>';
            }
        }

        return $text;
    }

    /**
     * Print out any site-specific links for the current application
     * that have been defined in application/config/menu.php.
     */
    function siteLinks()
    {
        $menufile = $GLOBALS['registry']->getParam('fileroot') . '/config/menu.php';
        if (@is_readable($menufile)) {
            include_once $menufile;
            if (isset($_menu) && is_array($_menu)) {
                foreach ($_menu as $item) {
                    echo Menu::customItem($item);
                }
            }
        }
    }

    /**
     * Print out any links to other Horde applications that are
     * defined in $conf['menu']['apps'].
     */
    function appLinks()
    {
        global $conf, $registry;
        if (isset($conf['menu']['apps']) && is_array($conf['menu']['apps'])) {
            foreach ($conf['menu']['apps'] as $app) {
                if ($registry->getParam('status', $app) != 'inactive') {
                    $url = $registry->getInitialPage($app);
                    if (!is_a($url, 'PEAR_Error')) {
                        Menu::printItem(Horde::url($url),
                                        $registry->getParam('name', $app), $registry->getParam('icon', $app), '');
                    }
                }
            }
        }
    }

    /**
     * Any links to other Horde applications defined in an application's config
     * file by the $conf['menu']['apps'] array are added to the menu array for
     * use in Horde_Template pages.
     */
    function addAppLinks(&$menu)
    {
        global $conf, $registry;
        if (isset($conf['menu']['apps']) && is_array($conf['menu']['apps'])) {
            foreach ($conf['menu']['apps'] as $app) {
                if ($registry->getParam('status', $app) != 'inactive') {
                    $url = $registry->getInitialPage($app);
                    if (!is_a($url, 'PEAR_Error')) {
                        $menu[] = array('url' => $url, 'text' => $registry->getParam('name', $app), 'icon' => $registry->getParam('icon', $app), 'icon_path' => '');
                    }
                }
            }
        }
    }
    function addSiteLinks(&$menu)
    {
        if (@is_readable($this->_menufile)) {
            include $this->_menufile;
            if (isset($_menu) && is_array($_menu)) {
                foreach ($_menu as $menuitem) {
                    $menu[] = $menuitem;
                }
            }
        }
    }

    function getFormattedMenu()
    {
        $menu = $this->getMenu();
        foreach ($menu as $menuitem) {
            $formattedmenu[] = $this->customItem($menuitem);
        }
        return $formattedmenu;
    }

    function getMenu()
    {
        /* Cache the menu generation. */
        static $menu = array();

        /* Return the menu array if already generated. */
        if (!empty($menu)) {
            return $menu;
        }

        global $conf, $registry;

        $app = $registry->getApp();
        $function = 'get' . $app . 'Menu';
        $menu = call_user_func(array($app, $function));

        /* Settings. */
        if (($conf['prefs']['driver'] != '') && ($conf['prefs']['driver'] != 'none')) {
            $menu[] = array('url' => Horde::applicationUrl('prefs.php'), 'text' => _("Options"), 'icon' => 'prefs.gif', 'icon_path' => $registry->getParam('graphics', 'horde'));
        }

        /* Add any app menu items. */
        $this->addAppLinks($menu);

        /* Add any custom menu items. */
        $this->addSiteLinks($menu);

        /* Help */
        if ($help_link = Help::listLink($app)) {
            Help::javascript();
            $menu[] = array('url' => $help_link, 'text' => _("Help"), 'icon' => 'manual.gif', 'icon_path' => $registry->getParam('graphics', 'horde'));
        }

        /* Login/Logout. */
        if (Auth::getAuth() && $this->_with_login) {
            $url = Horde::url($registry->getParam('webroot', 'horde') . '/login.php');
            $url = Horde::addParameter($url, 'reason', 'logout');
            $menu[] = array('url' => $url, 'text' => _("Logout"), 'icon' => 'logout.gif', 'icon_path' => $registry->getParam('graphics', 'horde'));
        } elseif ($this->_with_login) {
            $url = Auth::getLoginScreen('', Horde::selfUrl());
            $menu[] = array('url' => $url, 'text' => _("Login"), 'icon' => 'login.gif', 'icon_path' => $registry->getParam('graphics', 'horde'));
        }

        return $menu;
    }

}
