// * this is for making emacs happy: -*-Mode: C++;-*-
/****************************************************************************
 * Copyright (c) 1998-2003,2005 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 "cursesf.h"
#include "cursesapp.h"

MODULE_ID("$Id: cursesf.cc,v 1.21 2005/08/13 18:09:06 tom Exp $")

NCursesFormField::~NCursesFormField ()
{
  if (field)
    OnError(::free_field (field));
}

/* Construct a FIELD* array from an array of NCursesFormField
 * objects.
 */
FIELD**
NCursesForm::mapFields(NCursesFormField* nfields[])
{
  int fieldCount = 0,lcv;
  FIELD** old_fields;

  assert(nfields != 0);

  for (lcv=0; nfields[lcv]->field; ++lcv)
    ++fieldCount;

  FIELD** fields = new FIELD*[fieldCount + 1];

  for (lcv=0;nfields[lcv]->field;++lcv) {
    fields[lcv] = nfields[lcv]->field;
  }
  fields[lcv] = NULL;

  my_fields = nfields;

  if (form && (old_fields = ::form_fields(form))) {
    ::set_form_fields(form, static_cast<FIELD**>(0));
    delete[] old_fields;
  }
  return fields;
}

void NCursesForm::setDefaultAttributes()
{
  NCursesApplication* S = NCursesApplication::getApplication();

  int n = count();
  if (n > 0) {
    for(int i=0; i<n; i++) {
      NCursesFormField* f = (*this)[i];
      if ((f->options() & (O_EDIT|O_ACTIVE))==(O_EDIT|O_ACTIVE)) {
	if (S) {
	  f->set_foreground(S->foregrounds());
	  f->set_background(S->backgrounds());
	}
	f->set_pad_character('_');
      }
      else {
	if (S)
	  f->set_background(S->labels());
      }
    }
  }

  if (S) {
    bkgd(' '|S->dialog_backgrounds());
    if (sub)
      sub->bkgd(' '|S->dialog_backgrounds());
  }
}

void
NCursesForm::InitForm(NCursesFormField* nfields[],
		      bool with_frame,
		      bool autoDelete_Fields)
{
  int mrows, mcols;

  keypad(TRUE);
  meta(TRUE);

  b_framed = with_frame;
  b_autoDelete = autoDelete_Fields;

  form = static_cast<FORM*>(0);
  form = ::new_form(mapFields(nfields));
  if (!form)
    OnError (E_SYSTEM_ERROR);

  UserHook* hook = new UserHook;
  hook->m_user   = NULL;
  hook->m_back   = this;
  hook->m_owner  = form;
  ::set_form_userptr(form, reinterpret_cast<void*>(hook));

  ::set_form_init  (form, _nc_xx_frm_init);
  ::set_form_term  (form, _nc_xx_frm_term);
  ::set_field_init (form, _nc_xx_fld_init);
  ::set_field_term (form, _nc_xx_fld_term);

  scale(mrows, mcols);
  ::set_form_win(form, 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_form_sub(form, sub->w);
    b_sub_owner = TRUE;
  }
  else {
    sub = static_cast<NCursesWindow*>(0);
    b_sub_owner = FALSE;
  }
  options_on(O_NL_OVERLOAD);
  setDefaultAttributes();
}

NCursesForm::~NCursesForm()
{
  UserHook* hook = reinterpret_cast<UserHook*>(::form_userptr(form));
  delete hook;
  if (b_sub_owner) {
    delete sub;
    ::set_form_sub(form, static_cast<WINDOW *>(0));
  }
  if (form) {
    FIELD** fields = ::form_fields(form);
    int cnt = count();

    OnError(::set_form_fields(form, static_cast<FIELD**>(0)));

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

    ::free_form(form);
    // It's essential to do this after free_form()
    delete[] fields;
  }
}

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

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

void
_nc_xx_frm_term(FORM *f)
{
  NCursesForm::getHook(f)->On_Form_Termination();
}

void
_nc_xx_fld_init(FORM *f)
{
  NCursesForm* F = NCursesForm::getHook(f);
  F->On_Field_Init (*(F->current_field ()));
}

void
_nc_xx_fld_term(FORM *f)
{
  NCursesForm* F = NCursesForm::getHook(f);
  F->On_Field_Termination (*(F->current_field ()));
}

void
NCursesForm::On_Form_Init()
{
}

void
NCursesForm::On_Form_Termination()
{
}

void
NCursesForm::On_Field_Init(NCursesFormField& field)
{
}

void
NCursesForm::On_Field_Termination(NCursesFormField& field)
{
}

// call the form driver and do basic error checking.
int
NCursesForm::driver (int c)
{
  int res = ::form_driver (form, c);
  switch (res) {
  case E_OK:
  case E_REQUEST_DENIED:
  case E_INVALID_FIELD:
  case E_UNKNOWN_COMMAND:
    break;
  default:
    OnError (res);
  }
  return (res);
}

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

void NCursesForm::On_Invalid_Field(int c) const
{
  ::beep();
}

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

static const int CMD_QUIT = MAX_COMMAND + 1;

NCursesFormField*
NCursesForm::operator()(void)
{
  int drvCmnd;
  int err;
  int c;

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

  while (((drvCmnd = virtualize((c=getKey()))) != CMD_QUIT)) {
    switch((err=driver(drvCmnd))) {
    case E_REQUEST_DENIED:
      On_Request_Denied(c);
      break;
    case E_INVALID_FIELD:
      On_Invalid_Field(c);
      break;
    case E_UNKNOWN_COMMAND:
      On_Unknown_Command(c);
      break;
    case E_OK:
      break;
    default:
      OnError(err);
    }
  }

  unpost();
  hide();
  refresh();
  return my_fields[::field_index (::current_field (form))];
}

// Provide a default key virtualization. Translate the keyboard
// code c into a form request code.
// The default implementation provides a hopefully straightforward
// mapping for the most common keystrokes and form requests.
int
NCursesForm::virtualize(int c)
{
  switch(c) {

  case KEY_HOME      : return(REQ_FIRST_FIELD);
  case KEY_END       : return(REQ_LAST_FIELD);

  case KEY_DOWN      : return(REQ_DOWN_CHAR);
  case KEY_UP        : return(REQ_UP_CHAR);
  case KEY_LEFT      : return(REQ_PREV_CHAR);
  case KEY_RIGHT     : return(REQ_NEXT_CHAR);

  case KEY_NPAGE     : return(REQ_NEXT_PAGE);
  case KEY_PPAGE     : return(REQ_PREV_PAGE);

  case KEY_BACKSPACE : return(REQ_DEL_PREV);
  case KEY_ENTER     : return(REQ_NEW_LINE);
  case KEY_CLEAR     : return(REQ_CLR_FIELD);

  case CTRL('X')     : return(CMD_QUIT);        // eXit

  case CTRL('F')     : return(REQ_NEXT_FIELD);  // Forward
  case CTRL('B')     : return(REQ_PREV_FIELD);  // Backward
  case CTRL('L')     : return(REQ_LEFT_FIELD);  // Left
  case CTRL('R')     : return(REQ_RIGHT_FIELD); // Right
  case CTRL('U')     : return(REQ_UP_FIELD);    // Up
  case CTRL('D')     : return(REQ_DOWN_FIELD);  // Down

  case CTRL('W')     : return(REQ_NEXT_WORD);
  case CTRL('T')     : return(REQ_PREV_WORD);

  case CTRL('A')     : return(REQ_BEG_FIELD);
  case CTRL('E')     : return(REQ_END_FIELD);

  case CTRL('I')     : return(REQ_INS_CHAR);
  case CTRL('M')     :
  case CTRL('J')     : return(REQ_NEW_LINE);
  case CTRL('O')     : return(REQ_INS_LINE);
  case CTRL('V')     : return(REQ_DEL_CHAR);
  case CTRL('H')     : return(REQ_DEL_PREV);
  case CTRL('Y')     : return(REQ_DEL_LINE);
  case CTRL('G')     : return(REQ_DEL_WORD);
  case CTRL('K')     : return(REQ_CLR_EOF);

  case CTRL('N')     : return(REQ_NEXT_CHOICE);
  case CTRL('P')     : return(REQ_PREV_CHOICE);

  default:
    return(c);
  }
}
//
// -------------------------------------------------------------------------
// User Defined Fieldtypes
// -------------------------------------------------------------------------
//
bool _nc_xx_fld_fcheck(FIELD *f, const void *u)
{
  NCursesFormField* F = reinterpret_cast<NCursesFormField*>(const_cast<void *>(u));
  assert(F != 0);
  UserDefinedFieldType* udf = reinterpret_cast<UserDefinedFieldType*>(F->fieldtype());
  assert(udf != 0);
  return udf->field_check(*F);
}

bool _nc_xx_fld_ccheck(int c, const void *u)
{
  NCursesFormField* F = reinterpret_cast<NCursesFormField*>(const_cast<void *>(u));
  assert(F != 0);
  UserDefinedFieldType* udf =
    reinterpret_cast<UserDefinedFieldType*>(F->fieldtype());
  assert(udf != 0);
  return udf->char_check(c);
}

void* _nc_xx_fld_makearg(va_list* va)
{
  return va_arg(*va,NCursesFormField*);
}

FIELDTYPE* UserDefinedFieldType::generic_fieldtype =
  ::new_fieldtype(_nc_xx_fld_fcheck,
		  _nc_xx_fld_ccheck);

FIELDTYPE* UserDefinedFieldType_With_Choice::generic_fieldtype_with_choice =
  ::new_fieldtype(_nc_xx_fld_fcheck,
		  _nc_xx_fld_ccheck);

bool _nc_xx_next_choice(FIELD *f, const void *u)
{
  NCursesFormField* F = reinterpret_cast<NCursesFormField*>(const_cast<void *>(u));
  assert(F != 0);
  UserDefinedFieldType_With_Choice* udf =
    reinterpret_cast<UserDefinedFieldType_With_Choice*>(F->fieldtype());
  assert(udf != 0);
  return udf->next(*F);
}

bool _nc_xx_prev_choice(FIELD *f, const void *u)
{
  NCursesFormField* F = reinterpret_cast<NCursesFormField*>(const_cast<void *>(u));
  assert(F != 0);
  UserDefinedFieldType_With_Choice* udf =
    reinterpret_cast<UserDefinedFieldType_With_Choice*>(F->fieldtype());
  assert(udf != 0);
  return udf->previous(*F);
}

class UDF_Init
{
private:
  int code;
  static UDF_Init* I;

public:
  UDF_Init()
    : code(0)
  {
    code = ::set_fieldtype_arg(UserDefinedFieldType::generic_fieldtype,
			       _nc_xx_fld_makearg,
			       NULL,
			       NULL);
    if (code==E_OK)
      code = ::set_fieldtype_arg
	(UserDefinedFieldType_With_Choice::generic_fieldtype_with_choice,
	 _nc_xx_fld_makearg,
	 NULL,
	 NULL);
    if (code==E_OK)
      code = ::set_fieldtype_choice
	(UserDefinedFieldType_With_Choice::generic_fieldtype_with_choice,
	 _nc_xx_next_choice,
	 _nc_xx_prev_choice);
  }
};

UDF_Init* UDF_Init::I = new UDF_Init();
