// * This makes emacs happy -*-Mode: C++;-*-
/****************************************************************************
 * Copyright (c) 1998-2012,2014 Free Software Foundation, Inc.              *
 *                                                                          *
 * Permission is hereby granted, free of charge, to any person obtaining a  *
 * copy of this software and associated documentation files (the            *
 * "Software"), to deal in the Software without restriction, including      *
 * without limitation the rights to use, copy, modify, merge, publish,      *
 * distribute, distribute with modifications, sublicense, and/or sell       *
 * copies of the Software, and to permit persons to whom the Software is    *
 * furnished to do so, subject to the following conditions:                 *
 *                                                                          *
 * The above copyright notice and this permission notice shall be included  *
 * in all copies or substantial portions of the Software.                   *
 *                                                                          *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
 *                                                                          *
 * Except as contained in this notice, the name(s) of the above copyright   *
 * holders shall not be used in advertising or otherwise to promote the     *
 * sale, use or other dealings in this Software without prior written       *
 * authorization.                                                           *
 ****************************************************************************/

/****************************************************************************
 *   Author: Juergen Pfeifer, 1997                                          *
 ****************************************************************************/

// $Id: cursesm.h,v 1.30 2014/08/09 22:06:18 Adam.Jiang Exp $

#ifndef NCURSES_CURSESM_H_incl
#define NCURSES_CURSESM_H_incl 1

#include <cursesp.h>

extern "C" {
#  include <menu.h>
}
//
// -------------------------------------------------------------------------
// This wraps the ITEM type of <menu.h>
// -------------------------------------------------------------------------
//
class NCURSES_IMPEXP NCursesMenuItem
{
  friend class NCursesMenu;

protected:
  ITEM *item;

  inline void OnError (int err) const THROW2(NCursesException const, NCursesMenuException) {
    if (err != E_OK)
      THROW(new NCursesMenuException (err));
  }

public:
  NCursesMenuItem (const char* p_name     = NULL,
		   const char* p_descript = NULL)
    : item(0)
  {
    item = p_name ? ::new_item (p_name, p_descript) : STATIC_CAST(ITEM*)(0);
    if (p_name && !item)
      OnError (E_SYSTEM_ERROR);
  }
  // Create an item. If you pass both parameters as NULL, a delimiting
  // item is constructed which can be used to terminate a list of
  // NCursesMenu objects.

  NCursesMenuItem& operator=(const NCursesMenuItem& rhs)
  {
    if (this != &rhs) {
      *this = rhs;
    }
    return *this;
  }

  NCursesMenuItem(const NCursesMenuItem& rhs)
    : item(0)
  {
    (void) rhs;
  }

  virtual ~NCursesMenuItem ();
  // Release the items memory

  inline const char* name () const {
    return ::item_name (item);
  }
  // Name of the item

  inline const char* description () const {
    return ::item_description (item);
  }
  // Description of the item

  inline int (index) (void) const {
    return ::item_index (item);
  }
  // Index of the item in an item array (or -1)

  inline void options_on (Item_Options opts) {
    OnError (::item_opts_on (item, opts));
  }
  // Switch on the items options

  inline void options_off (Item_Options opts) {
    OnError (::item_opts_off (item, opts));
  }
  // Switch off the item's option

  inline Item_Options options () const {
    return ::item_opts (item);
  }
  // Retrieve the items options

  inline void set_options (Item_Options opts) {
    OnError (::set_item_opts (item, opts));
  }
  // Set the items options

  inline void set_value (bool f) {
    OnError (::set_item_value (item,f));
  }
  // Set/Reset the items selection state

  inline bool value () const {
    return ::item_value (item);
  }
  // Retrieve the items selection state

  inline bool visible () const {
    return ::item_visible (item);
  }
  // Retrieve visibility of the item

  virtual bool action();
  // Perform an action associated with this item; you may use this in an
  // user supplied driver for a menu; you may derive from this class and
  // overload action() to supply items with different actions.
  // If an action returns true, the menu will be exited. The default action
  // is to do nothing.
};

// Prototype for an items callback function.
typedef bool ITEMCALLBACK(NCursesMenuItem&);

// If you don't like to create a child class for individual items to
// overload action(), you may use this class and provide a callback
// function pointer for items.
class NCURSES_IMPEXP NCursesMenuCallbackItem : public NCursesMenuItem
{
private:
  ITEMCALLBACK* p_fct;

public:
  NCursesMenuCallbackItem(ITEMCALLBACK* fct       = NULL,
			  const char* p_name      = NULL,
			  const char* p_descript  = NULL )
    : NCursesMenuItem (p_name, p_descript),
      p_fct (fct) {
  }

  NCursesMenuCallbackItem& operator=(const NCursesMenuCallbackItem& rhs)
  {
    if (this != &rhs) {
      *this = rhs;
    }
    return *this;
  }

  NCursesMenuCallbackItem(const NCursesMenuCallbackItem& rhs)
    : NCursesMenuItem(rhs),
      p_fct(0)
  {
  }

  virtual ~NCursesMenuCallbackItem();

  bool action();
};

  // This are the built-in hook functions in this C++ binding. In C++ we use
  // virtual member functions (see below On_..._Init and On_..._Termination)
  // to provide this functionality in an object oriented manner.
extern "C" {
  void _nc_xx_mnu_init(MENU *);
  void _nc_xx_mnu_term(MENU *);
  void _nc_xx_itm_init(MENU *);
  void _nc_xx_itm_term(MENU *);
}

//
// -------------------------------------------------------------------------
// This wraps the MENU type of <menu.h>
// -------------------------------------------------------------------------
//
class NCURSES_IMPEXP NCursesMenu : public NCursesPanel
{
protected:
  MENU *menu;

private:
  NCursesWindow* sub;   // the subwindow object
  bool b_sub_owner;     // is this our own subwindow?
  bool b_framed;        // has the menu a border?
  bool b_autoDelete;    // Delete items when deleting menu?

  NCursesMenuItem** my_items; // The array of items for this menu

  // This structure is used for the menu's user data field to link the
  // MENU* to the C++ object and to provide extra space for a user pointer.
  typedef struct {
    void*              m_user;      // the pointer for the user's data
    const NCursesMenu* m_back;      // backward pointer to C++ object
    const MENU*        m_owner;
  } UserHook;

  // Get the backward pointer to the C++ object from a MENU
  static inline NCursesMenu* getHook(const MENU *m) {
    UserHook* hook = STATIC_CAST(UserHook*)(::menu_userptr(m));
    assert(hook != 0 && hook->m_owner==m);
    return const_cast<NCursesMenu*>(hook->m_back);
  }

  friend void _nc_xx_mnu_init(MENU *);
  friend void _nc_xx_mnu_term(MENU *);
  friend void _nc_xx_itm_init(MENU *);
  friend void _nc_xx_itm_term(MENU *);

  // Calculate ITEM* array for the menu
  ITEM** mapItems(NCursesMenuItem* nitems[]);

protected:
  // internal routines
  inline void set_user(void *user) {
    UserHook* uptr = STATIC_CAST(UserHook*)(::menu_userptr (menu));
    assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu);
    uptr->m_user = user;
  }

  inline void *get_user() {
    UserHook* uptr = STATIC_CAST(UserHook*)(::menu_userptr (menu));
    assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu);
    return uptr->m_user;
  }

  void InitMenu (NCursesMenuItem* menu[],
		 bool with_frame,
		 bool autoDeleteItems);

  inline void OnError (int err) const THROW2(NCursesException const, NCursesMenuException) {
    if (err != E_OK)
      THROW(new NCursesMenuException (this, err));
  }

  // this wraps the menu_driver call.
  virtual int driver (int c) ;

  // 'Internal' constructor to create a menu without association to
  // an array of items.
  NCursesMenu( int  nlines,
	       int  ncols,
	       int  begin_y = 0,
	       int  begin_x = 0)
    : NCursesPanel(nlines,ncols,begin_y,begin_x),
      menu (STATIC_CAST(MENU*)(0)),
      sub(0),
      b_sub_owner(0),
      b_framed(0),
      b_autoDelete(0),
      my_items(0)
  {
  }

public:
  // Make a full window size menu
  NCursesMenu (NCursesMenuItem* Items[],
	       bool with_frame=FALSE,        // Reserve space for a frame?
	       bool autoDelete_Items=FALSE)  // Autocleanup of Items?
    : NCursesPanel(),
      menu(0),
      sub(0),
      b_sub_owner(0),
      b_framed(0),
      b_autoDelete(0),
      my_items(0)
  {
      InitMenu(Items, with_frame, autoDelete_Items);
  }

  // Make a menu with a window of this size.
  NCursesMenu (NCursesMenuItem* Items[],
	       int  nlines,
	       int  ncols,
	       int  begin_y = 0,
	       int  begin_x = 0,
	       bool with_frame=FALSE,        // Reserve space for a frame?
	       bool autoDelete_Items=FALSE)  // Autocleanup of Items?
    : NCursesPanel(nlines, ncols, begin_y, begin_x),
      menu(0),
      sub(0),
      b_sub_owner(0),
      b_framed(0),
      b_autoDelete(0),
      my_items(0)
  {
      InitMenu(Items, with_frame, autoDelete_Items);
  }

  NCursesMenu& operator=(const NCursesMenu& rhs)
  {
    if (this != &rhs) {
      *this = rhs;
      NCursesPanel::operator=(rhs);
    }
    return *this;
  }

  NCursesMenu(const NCursesMenu& rhs)
    : NCursesPanel(rhs),
      menu(rhs.menu),
      sub(rhs.sub),
      b_sub_owner(rhs.b_sub_owner),
      b_framed(rhs.b_framed),
      b_autoDelete(rhs.b_autoDelete),
      my_items(rhs.my_items)
  {
  }

  virtual ~NCursesMenu ();

  // Retrieve the menus subwindow
  inline NCursesWindow& subWindow() const {
    assert(sub!=NULL);
    return *sub;
  }

  // Set the menus subwindow
  void setSubWindow(NCursesWindow& sub);

  // Set these items for the menu
  inline void setItems(NCursesMenuItem* Items[]) {
    OnError(::set_menu_items(menu,mapItems(Items)));
  }

  // Remove the menu from the screen
  inline void unpost (void) {
    OnError (::unpost_menu (menu));
  }

  // Post the menu to the screen if flag is true, unpost it otherwise
  inline void post(bool flag = TRUE) {
    flag ? OnError (::post_menu(menu)) : OnError (::unpost_menu (menu));
  }

  // Get the numer of rows and columns for this menu
  inline void scale (int& mrows, int& mcols) const  {
    OnError (::scale_menu (menu, &mrows, &mcols));
  }

  // Set the format of this menu
  inline void set_format(int mrows, int mcols) {
    OnError (::set_menu_format(menu, mrows, mcols));
  }

  // Get the format of this menu
  inline void menu_format(int& rows,int& ncols) {
    ::menu_format(menu,&rows,&ncols);
  }

  // Items of the menu
  inline NCursesMenuItem* items() const {
    return *my_items;
  }

  // Get the number of items in this menu
  inline int count() const {
    return ::item_count(menu);
  }

  // Get the current item (i.e. the one the cursor is located)
  inline NCursesMenuItem* current_item() const {
    return my_items[::item_index(::current_item(menu))];
  }

  // Get the marker string
  inline const char* mark() const {
    return ::menu_mark(menu);
  }

  // Set the marker string
  inline void set_mark(const char *marker) {
    OnError (::set_menu_mark (menu, marker));
  }

  // Get the name of the request code c
  inline static const char* request_name(int c) {
    return ::menu_request_name(c);
  }

  // Get the current pattern
  inline char* pattern() const {
    return ::menu_pattern(menu);
  }

  // true if there is a pattern match, false otherwise.
  bool set_pattern (const char *pat);

  // set the default attributes for the menu
  // i.e. set fore, back and grey attribute
  virtual void setDefaultAttributes();

  // Get the menus background attributes
  inline chtype back() const {
    return ::menu_back(menu);
  }

  // Get the menus foreground attributes
  inline chtype fore() const {
    return ::menu_fore(menu);
  }

  // Get the menus grey attributes (used for unselectable items)
  inline chtype grey() const {
    return ::menu_grey(menu);
  }

  // Set the menus background attributes
  inline chtype set_background(chtype a) {
    return ::set_menu_back(menu,a);
  }

  // Set the menus foreground attributes
  inline chtype set_foreground(chtype a) {
    return ::set_menu_fore(menu,a);
  }

  // Set the menus grey attributes (used for unselectable items)
  inline chtype set_grey(chtype a) {
    return ::set_menu_grey(menu,a);
  }

  inline void options_on (Menu_Options opts) {
    OnError (::menu_opts_on (menu,opts));
  }

  inline void options_off(Menu_Options opts) {
    OnError (::menu_opts_off(menu,opts));
  }

  inline Menu_Options options() const {
    return ::menu_opts(menu);
  }

  inline void set_options (Menu_Options opts) {
    OnError (::set_menu_opts (menu,opts));
  }

  inline int pad() const {
    return ::menu_pad(menu);
  }

  inline void set_pad (int padch) {
    OnError (::set_menu_pad (menu, padch));
  }

  // Position the cursor to the current item
  inline void position_cursor () const {
    OnError (::pos_menu_cursor (menu));
  }

  // Set the current item
  inline void set_current(NCursesMenuItem& I) {
    OnError (::set_current_item(menu, I.item));
  }

  // Get the current top row of the menu
  inline int top_row (void) const {
    return ::top_row (menu);
  }

  // Set the current top row of the menu
  inline void set_top_row (int row) {
    OnError (::set_top_row (menu, row));
  }

  // spacing control
  // Set the spacing for the menu
  inline void setSpacing(int spc_description,
			 int spc_rows,
			 int spc_columns) {
    OnError(::set_menu_spacing(menu,
			       spc_description,
			       spc_rows,
			       spc_columns));
  }

  // Get the spacing info for the menu
  inline void Spacing(int& spc_description,
		      int& spc_rows,
		      int& spc_columns) const {
    OnError(::menu_spacing(menu,
			   &spc_description,
			   &spc_rows,
			   &spc_columns));
  }

  // Decorations
  inline void frame(const char *title=NULL, const char* btitle=NULL) {
    if (b_framed)
      NCursesPanel::frame(title,btitle);
    else
      OnError(E_SYSTEM_ERROR);
  }

  inline void boldframe(const char *title=NULL, const char* btitle=NULL) {
    if (b_framed)
      NCursesPanel::boldframe(title,btitle);
    else
      OnError(E_SYSTEM_ERROR);
  }

  inline void label(const char *topLabel, const char *bottomLabel) {
    if (b_framed)
      NCursesPanel::label(topLabel,bottomLabel);
    else
      OnError(E_SYSTEM_ERROR);
  }

  // -----
  // Hooks
  // -----

  // Called after the menu gets repositioned in its window.
  // This is especially true if the menu is posted.
  virtual void On_Menu_Init();

  // Called before the menu gets repositioned in its window.
  // This is especially true if the menu is unposted.
  virtual void On_Menu_Termination();

  // Called after the item became the current item
  virtual void On_Item_Init(NCursesMenuItem& item);

  // Called before this item is left as current item.
  virtual void On_Item_Termination(NCursesMenuItem& item);

  // Provide a default key virtualization. Translate the keyboard
  // code c into a menu request code.
  // The default implementation provides a hopefully straightforward
  // mapping for the most common keystrokes and menu requests.
  virtual int virtualize(int c);


  // Operators
  inline NCursesMenuItem* operator[](int i) const {
    if ( (i < 0) || (i >= ::item_count (menu)) )
      OnError (E_BAD_ARGUMENT);
    return (my_items[i]);
  }

  // Perform the menu's operation
  // Return the item where you left the selection mark for a single
  // selection menu, or NULL for a multivalued menu.
  virtual NCursesMenuItem* operator()(void);

  // --------------------
  // Exception handlers
  // Called by operator()
  // --------------------

  // Called if the request is denied
  virtual void On_Request_Denied(int c) const;

  // Called if the item is not selectable
  virtual void On_Not_Selectable(int c) const;

  // Called if pattern doesn't match
  virtual void On_No_Match(int c) const;

  // Called if the command is unknown
  virtual void On_Unknown_Command(int c) const;

};
//
// -------------------------------------------------------------------------
// This is the typical C++ typesafe way to allow to attach
// user data to an item of a menu. Its assumed that the user
// data belongs to some class T. Use T as template argument
// to create a UserItem.
// -------------------------------------------------------------------------
//
template<class T> class NCURSES_IMPEXP NCursesUserItem : public NCursesMenuItem
{
public:
  NCursesUserItem (const char* p_name,
		   const char* p_descript = NULL,
		   const T* p_UserData    = STATIC_CAST(T*)(0))
    : NCursesMenuItem (p_name, p_descript) {
      if (item)
	OnError (::set_item_userptr (item, const_cast<void *>(reinterpret_cast<const void*>(p_UserData))));
  }

  virtual ~NCursesUserItem() {}

  inline const T* UserData (void) const {
    return reinterpret_cast<const T*>(::item_userptr (item));
  };

  inline virtual void setUserData(const T* p_UserData) {
    if (item)
      OnError (::set_item_userptr (item, const_cast<void *>(reinterpret_cast<const void *>(p_UserData))));
  }
};
//
// -------------------------------------------------------------------------
// The same mechanism is used to attach user data to a menu
// -------------------------------------------------------------------------
//
template<class T> class NCURSES_IMPEXP NCursesUserMenu : public NCursesMenu
{
protected:
  NCursesUserMenu( int  nlines,
		   int  ncols,
		   int  begin_y = 0,
		   int  begin_x = 0,
		   const T* p_UserData = STATIC_CAST(T*)(0))
    : NCursesMenu(nlines,ncols,begin_y,begin_x) {
      if (menu)
	set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
  }

public:
  NCursesUserMenu (NCursesMenuItem* Items[],
		   const T* p_UserData = STATIC_CAST(T*)(0),
		   bool with_frame=FALSE,
		   bool autoDelete_Items=FALSE)
    : NCursesMenu (Items, with_frame, autoDelete_Items) {
      if (menu)
	set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
  };

  NCursesUserMenu (NCursesMenuItem* Items[],
		   int nlines,
		   int ncols,
		   int begin_y = 0,
		   int begin_x = 0,
		   const T* p_UserData = STATIC_CAST(T*)(0),
		   bool with_frame=FALSE)
    : NCursesMenu (Items, nlines, ncols, begin_y, begin_x, with_frame) {
      if (menu)
	set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
  };

  virtual ~NCursesUserMenu() {
  };

  inline T* UserData (void) {
    return reinterpret_cast<T*>(get_user ());
  };

  inline virtual void setUserData (const T* p_UserData) {
    if (menu)
      set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData)));
  }
};

#endif /* NCURSES_CURSESM_H_incl */
