// * this is for making emacs happy: -*-Mode: C++;-*-
/****************************************************************************
 * Copyright (c) 1998-2005,2011 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                                          *
 ****************************************************************************/

#include "internal.h"
#include "cursesm.h"
#include "cursesapp.h"

MODULE_ID("$Id: cursesm.cc,v 1.23 2011/09/17 22:11:32 tom Exp $")

NCursesMenuItem::~NCursesMenuItem()
{
  if (item)
    OnError(::free_item(item));
}

bool
NCursesMenuItem::action()
{
  return FALSE;
}

NCursesMenuCallbackItem::~NCursesMenuCallbackItem()
{
}

bool
NCursesMenuCallbackItem::action()
{
  if (p_fct)
    return p_fct (*this);
  else
    return FALSE;
}

/* Internal hook functions. They will route the hook
 * calls to virtual methods of the NCursesMenu class,
 * so in C++ providing a hook is done simply by
 * implementing a virtual method in a derived class
 */
void
_nc_xx_mnu_init(MENU *m)
{
  NCursesMenu::getHook(m)->On_Menu_Init();
}

void
_nc_xx_mnu_term(MENU *m)
{
  NCursesMenu::getHook(m)->On_Menu_Termination();
}

void
_nc_xx_itm_init(MENU *m)
{
  NCursesMenu* M = NCursesMenu::getHook(m);
  M->On_Item_Init (*(M->current_item ()));
}

void
_nc_xx_itm_term(MENU *m)
{
  NCursesMenu* M = NCursesMenu::getHook(m);
  M->On_Item_Termination (*(M->current_item ()));
}

/* Construct an ITEM* array from an array of NCursesMenuItem
 * objects.
 */
ITEM**
NCursesMenu::mapItems(NCursesMenuItem* nitems[])
{
  int itemCount = 0,lcv;

  for (lcv=0; nitems[lcv]->item; ++lcv)
    ++itemCount;

  ITEM** itemArray = new ITEM*[itemCount + 1];

  for (lcv=0;nitems[lcv]->item;++lcv) {
    itemArray[lcv] = nitems[lcv]->item;
  }
  itemArray[lcv] = NULL;

  my_items = nitems;

  if (menu)
    delete[] ::menu_items(menu);
  return itemArray;
}

void
NCursesMenu::InitMenu(NCursesMenuItem* nitems[],
		      bool with_frame,
		      bool autoDelete_Items)
{
  int mrows, mcols;

  keypad(TRUE);
  meta(TRUE);

  b_framed = with_frame;
  b_autoDelete = autoDelete_Items;

  menu = static_cast<MENU*>(0);
  menu = ::new_menu(mapItems(nitems));
  if (!menu)
    OnError (E_SYSTEM_ERROR);

  UserHook* hook = new UserHook;
  hook->m_user   = NULL;
  hook->m_back   = this;
  hook->m_owner  = menu;
  ::set_menu_userptr(menu, static_cast<void*>(hook));

  ::set_menu_init (menu, _nc_xx_mnu_init);
  ::set_menu_term (menu, _nc_xx_mnu_term);
  ::set_item_init (menu, _nc_xx_itm_init);
  ::set_item_term (menu, _nc_xx_itm_term);

  scale(mrows, mcols);
  ::set_menu_win(menu, w);

  if (with_frame) {
    if ((mrows > height()-2) || (mcols > width()-2))
      OnError(E_NO_ROOM);
    sub = new NCursesWindow(*this,mrows,mcols,1,1,'r');
    ::set_menu_sub(menu, sub->w);
    b_sub_owner = TRUE;
  }
  else {
    sub = static_cast<NCursesWindow*>(0);
    b_sub_owner = FALSE;
  }
  setDefaultAttributes();
}

void
NCursesMenu::setDefaultAttributes()
{
  NCursesApplication* S = NCursesApplication::getApplication();
  if (S) {
    ::set_menu_fore(menu, S->foregrounds());
    ::set_menu_back(menu, S->backgrounds());
    ::set_menu_grey(menu, S->inactives());
  }
}

NCursesMenu::~NCursesMenu()
{
  UserHook* hook = reinterpret_cast<UserHook*>(::menu_userptr(menu));
  delete hook;
  if (b_sub_owner) {
    delete sub;
    ::set_menu_sub(menu, static_cast<WINDOW *>(0));
  }
  if (menu) {
    ITEM** itms = ::menu_items(menu);
    int cnt = count();

    OnError(::set_menu_items(menu, static_cast<ITEM**>(0)));

    if (b_autoDelete) {
      if (cnt>0) {
	for (int i=0; i <= cnt; i++)
	  delete my_items[i];
      }
      delete[] my_items;
    }

    ::free_menu(menu);
    // It's essential to do this after free_menu()
    delete[] itms;
  }
}

void
NCursesMenu::setSubWindow(NCursesWindow& nsub)
{
  if (!isDescendant(nsub))
    OnError(E_SYSTEM_ERROR);
  else {
    if (b_sub_owner)
      delete sub;
    sub = &nsub;
    ::set_menu_sub(menu,sub->w);
  }
}

bool
NCursesMenu::set_pattern (const char *pat)
{
  int res = ::set_menu_pattern (menu, pat);
  switch(res) {
  case E_OK:
    break;
  case E_NO_MATCH:
    return FALSE;
  default:
    OnError (res);
  }
  return TRUE;
}

// call the menu driver and do basic error checking.
int
NCursesMenu::driver (int c)
{
  int res = ::menu_driver (menu, c);
  switch (res) {
  case E_OK:
  case E_REQUEST_DENIED:
  case E_NOT_SELECTABLE:
  case E_UNKNOWN_COMMAND:
  case E_NO_MATCH:
    break;
  default:
    OnError (res);
  }
  return (res);
}

static const int CMD_QUIT   = MAX_COMMAND + 1;
static const int CMD_ACTION = MAX_COMMAND + 2;
//
// -------------------------------------------------------------------------
// 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.
// -------------------------------------------------------------------------
int
NCursesMenu::virtualize(int c)
{
  switch(c) {
  case CTRL('X')     : return(CMD_QUIT);              // eXit

  case KEY_DOWN      : return(REQ_DOWN_ITEM);
  case CTRL('N')     : return(REQ_NEXT_ITEM);         // Next
  case KEY_UP        : return(REQ_UP_ITEM);
  case CTRL('P')     : return(REQ_PREV_ITEM);         // Previous

  case CTRL('U')     : return(REQ_SCR_ULINE);         // Up
  case CTRL('D')     : return(REQ_SCR_DLINE);         // Down
  case CTRL('F')     : return(REQ_SCR_DPAGE);         // Forward
  case CTRL('B')     : return(REQ_SCR_UPAGE);         // Backward

  case CTRL('Y')     : return(REQ_CLEAR_PATTERN);
  case CTRL('H')     : return(REQ_BACK_PATTERN);
  case CTRL('A')     : return(REQ_NEXT_MATCH);
  case CTRL('E')     : return(REQ_PREV_MATCH);
  case CTRL('T')     : return(REQ_TOGGLE_ITEM);

  case CTRL('J')     :
  case CTRL('M')     : return(CMD_ACTION);

  case KEY_HOME      : return(REQ_FIRST_ITEM);
  case KEY_LEFT      : return(REQ_LEFT_ITEM);
  case KEY_RIGHT     : return(REQ_RIGHT_ITEM);
  case KEY_END       : return(REQ_LAST_ITEM);
  case KEY_BACKSPACE : return(REQ_BACK_PATTERN);
  case KEY_NPAGE     : return(REQ_SCR_DPAGE);
  case KEY_PPAGE     : return(REQ_SCR_UPAGE);

  default:
    return(c);
  }
}

NCursesMenuItem*
NCursesMenu::operator()(void)
{
  int drvCmnd;
  int err;
  int c;
  bool b_action = FALSE;

  post();
  show();
  refresh();

  while (!b_action && ((drvCmnd = virtualize((c=getKey()))) != CMD_QUIT)) {

    switch((err=driver(drvCmnd))) {
    case E_REQUEST_DENIED:
      On_Request_Denied(c);
      break;
    case E_NOT_SELECTABLE:
      On_Not_Selectable(c);
      break;
    case E_UNKNOWN_COMMAND:
      if (drvCmnd == CMD_ACTION) {
	if (options() & O_ONEVALUE) {
	  NCursesMenuItem* itm = current_item();
	  assert(itm != 0);
	  if (itm->options() & O_SELECTABLE)
	    {
	      b_action = itm->action();
	      refresh();
	    }
	  else
	    On_Not_Selectable(c);
	}
	else {
	  int n = count();
	  for(int i=0; i<n; i++) {
	    NCursesMenuItem* itm = my_items[i];
	    if (itm->value()) {
	      b_action |= itm->action();
	      refresh();
	    }
	  }
	}
      } else
	On_Unknown_Command(c);
      break;
    case E_NO_MATCH:
      On_No_Match(c);
      break;
    case E_OK:
      break;
    default:
      OnError(err);
    }
  }

  unpost();
  hide();
  refresh();
  if (options() & O_ONEVALUE)
    return my_items[::item_index (::current_item (menu))];
  else
    return NULL;
}

void
NCursesMenu::On_Menu_Init()
{
}

void
NCursesMenu::On_Menu_Termination()
{
}

void
NCursesMenu::On_Item_Init(NCursesMenuItem& item)
{
  (void) item;
}

void
NCursesMenu::On_Item_Termination(NCursesMenuItem& item)
{
  (void) item;
}

void
NCursesMenu::On_Request_Denied(int c) const
{
  (void) c;
  ::beep();
}

void
NCursesMenu::On_Not_Selectable(int c) const
{
  (void) c;
  ::beep();
}

void
NCursesMenu::On_No_Match(int c) const
{
  (void) c;
  ::beep();
}

void
NCursesMenu::On_Unknown_Command(int c) const
{
  (void) c;
  ::beep();
}
