// * this is for making emacs happy: -*-Mode: C++;-*-
/****************************************************************************
 * Copyright 2019,2020 Thomas E. Dickey                                     *
 * Copyright 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 "cursesf.h"
#include "cursesapp.h"

MODULE_ID("$Id: cursesf.cc,v 1.24 2020/02/02 23:34:34 tom Exp $")

NCursesFormField::~NCursesFormField () THROWS(NCursesException)
{
  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() THROWS(NCursesException)
{
  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) field;
}

void
NCursesForm::On_Field_Termination(NCursesFormField& field)
{
  (void) 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
{
  (void) c;
  ::beep();
}

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

void NCursesForm::On_Unknown_Command(int c) const
{
  (void) c;
  ::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)
{
  (void) f;
  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)
{
  (void) f;
  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)
{
  (void) f;
  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();
