// * This makes emacs happy -*-Mode: C++;-*-
/****************************************************************************
 * Copyright (c) 1998-2011,2012 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.                                                           *
 ****************************************************************************/

/*
 *   Silly demo program for the NCursesPanel class.
 *
 *   written by Anatoly Ivasyuk (anatoly@nick.csh.rit.edu)
 *
 *   Demo code for NCursesMenu and NCursesForm written by
 *   Juergen Pfeifer
 *
 * $Id: demo.cc,v 1.41 2012/02/23 10:41:56 tom Exp $
 */

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

#ifdef __MINGW32__
#undef KEY_EVENT
#endif

#ifndef __MINGW32__
extern "C" unsigned int sleep(unsigned int);
#endif

#undef index // needed for NeXT

//
// -------------------------------------------------------------------------
//
class SillyDemo
{
  public:
  void run(int sleeptime) {

    NCursesPanel *mystd = new NCursesPanel();

    //  Make a few small demo panels

    NCursesPanel *u = new NCursesPanel(8, 20, 12, 4);
    NCursesPanel *v = new NCursesPanel(8, 20, 10, 6);
    NCursesPanel *w = new NCursesPanel(8, 20, 8, 8);
    NCursesPanel *x = new NCursesPanel(8, 20, 6, 10);
    NCursesPanel *y = new NCursesPanel(8, 20, 4, 12);
    NCursesPanel *z = new NCursesPanel(8, 30, 2, 14);

    //  Draw something on the main screen, so we can see what happens
    //  when panels get moved or deleted.

    mystd->box();
    mystd->move(mystd->height()/2, 1);
    mystd->hline(mystd->width()-2);
    mystd->move(1, mystd->width()/2);
    mystd->vline(mystd->height()-2);
    mystd->addch(0, mystd->width()/2, ACS_TTEE);
    mystd->addch(mystd->height()-1, mystd->width()/2, ACS_BTEE);
    mystd->addch(mystd->height()/2, 0, ACS_LTEE);
    mystd->addch(mystd->height()/2, mystd->width()-1, ACS_RTEE);
    mystd->addch(mystd->height()/2, mystd->width()/2, ACS_PLUS);

    //  Draw frames with titles around panels so that we can see where
    //  the panels are located.
    u->boldframe("Win U");
    v->frame("Win V");
    w->boldframe("Win W");
    x->frame("Win X");
    y->boldframe("Win Y");
    z->frame("Win Z");
    if (NCursesApplication::getApplication()->useColors()) {
      u->bkgd(' '|COLOR_PAIR(1));
      w->bkgd(' '|COLOR_PAIR(1));
      y->bkgd(' '|COLOR_PAIR(1));
      v->bkgd(' '|COLOR_PAIR(2));
      x->bkgd(' '|COLOR_PAIR(2));
      z->bkgd(' '|COLOR_PAIR(2));
    }

    //  A refresh to any valid panel updates all panels and refreshes
    //  the screen.  Using mystd is just convenient - We know it's always
    //  valid until the end of the program.

    mystd->refresh();
    sleep(sleeptime);

    //  Show what happens when panels are deleted and moved.

    sleep(sleeptime);
    delete u;
    mystd->refresh();

    sleep(sleeptime);
    delete z;
    mystd->refresh();

    sleep(sleeptime);
    delete v;
    mystd->refresh();

    // show how it looks when a panel moves
    sleep(sleeptime);
    y->mvwin(5, 30);
    mystd->refresh();

    sleep(sleeptime);
    delete y;
    mystd->refresh();

    // show how it looks when you raise a panel
    sleep(sleeptime);
    w->top();
    mystd->refresh();

    sleep(sleeptime);
    delete w;
    mystd->refresh();

    sleep(sleeptime);
    delete x;

    mystd->clear();
    mystd->refresh();

    //  Don't forget to clean up the main screen.  Since this is the
    //  last thing using NCursesWindow, this has the effect of
    //  shutting down ncurses and restoring the terminal state.

    sleep(sleeptime);
    delete mystd;
  }
};

class UserData
{
private:
  int u;
public:
  UserData(int x) : u(x) {}
  int sleeptime() const { return u; }
};
//
// -------------------------------------------------------------------------
//
template<class T> class MyAction : public NCursesUserItem<T>
{
public:
  MyAction (const char* p_name,
            const T* p_UserData)
    : NCursesUserItem<T>(p_name, static_cast<const char*>(0), p_UserData)
  {}

  virtual ~MyAction() {}

  bool action() {
    SillyDemo a;
    a.run(NCursesUserItem<T>::UserData()->sleeptime());
    return FALSE;
  }
};

template class MyAction<UserData>;
template class NCURSES_IMPEXP NCursesUserItem<UserData>;

class QuitItem : public NCursesMenuItem
{
public:
  QuitItem() : NCursesMenuItem("Quit") {
  }

  bool action() {
    return TRUE;
  }
};
//
// -------------------------------------------------------------------------
//
class Label : public NCursesFormField
{
public:
  Label(const char* title,
        int row, int col)
    : NCursesFormField(1, static_cast<int>(::strlen(title)), row, col) {
      set_value(title);
      options_off(O_EDIT|O_ACTIVE);
  }
};
//
// -------------------------------------------------------------------------
//
class MyFieldType : public UserDefinedFieldType
{
private:
  int chk;
protected:
  bool field_check(NCursesFormField& f) {
    (void) f;
    return TRUE;
  }
  bool char_check(int c) {
    return (c==chk?TRUE:FALSE);
  }
public:
  MyFieldType(int x) : chk(x) {
  }
};
//
// -------------------------------------------------------------------------
//
class TestForm : public NCursesForm
{
private:
  NCursesFormField** F;
  MyFieldType* mft;
  Integer_Field *ift;
  Enumeration_Field *eft;

  static const char *weekdays[];

public:
  TestForm()
    : NCursesForm(13, 51, (lines() - 15)/2, (cols() - 53)/2),
      F(0),
      mft(0),
      ift(0),
      eft(0)
  {

    F     = new NCursesFormField*[10];
    mft   = new MyFieldType('X');
    ift   = new Integer_Field(0, 1, 10);
    eft   = new Enumeration_Field(weekdays);

    F[0]  = new Label("Demo Entry Form", 0, 16);
    F[1]  = new Label("Weekday Enum", 2, 1);
    F[2]  = new Label("Number(1-10)", 2, 21);
    F[3]  = new Label("Only 'X'", 2, 35);
    F[4]  = new Label("Multiline Field (Dynamic and Scrollable)", 5, 1);
    F[5]  = new NCursesFormField(1, 18, 3, 1);
    F[6]  = new NCursesFormField(1, 12, 3, 21);
    F[7]  = new NCursesFormField(1, 12, 3, 35);
    F[8]  = new NCursesFormField(4, 46, 6, 1, 2);
    F[9]  = new NCursesFormField();

    InitForm(F, TRUE, TRUE);
    boldframe();

    F[5]->set_fieldtype(*eft);
    F[6]->set_fieldtype(*ift);

    F[7]->set_fieldtype(*mft);
    F[7]->set_maximum_growth(20); // max. 20 characters
    F[7]->options_off(O_STATIC);  // make field dynamic

    F[8]->set_maximum_growth(10); // max. 10 lines
    F[8]->options_off(O_STATIC);  // make field dynamic
  }

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

  TestForm(const TestForm& rhs)
    : NCursesForm(rhs), F(0), mft(0), ift(0), eft(0)
  {
  }

  ~TestForm() {
    delete mft;
    delete ift;
    delete eft;
  }
};

const char* TestForm::weekdays[] = {
    "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
    "Friday", "Saturday", NULL };
//
// -------------------------------------------------------------------------
//
class FormAction : public NCursesMenuItem
{
public:
  FormAction(const char *s) : NCursesMenuItem(s) {
  }

  bool action() {
    TestForm F;
    Soft_Label_Key_Set* S = new Soft_Label_Key_Set;
    for(int i=1; i <= S->labels(); i++) {
      char buf[8];
      assert(i < 100);
      ::_nc_SPRINTF(buf, _nc_SLIMIT(sizeof(buf)) "Frm%02d", i);
      (*S)[i] = buf;                                      // Text
      (*S)[i] = Soft_Label_Key_Set::Soft_Label_Key::Left; // Justification
    }
    NCursesApplication::getApplication()->push(*S);
    F();
    NCursesApplication::getApplication()->pop();
    delete S;
    return FALSE;
  }
};
//
// -------------------------------------------------------------------------
//
class PadAction : public NCursesMenuItem
{
public:
  PadAction(const char* s) : NCursesMenuItem(s) {
  }

  bool action() {
    const int GRIDSIZE = 3;
    const int PADSIZE  = 200;
    unsigned gridcount = 0;

    NCursesPanel mystd;
    NCursesPanel P(mystd.lines()-2, mystd.cols()-2, 1, 1);
    NCursesFramedPad FP(P, PADSIZE, PADSIZE);

    for (int i=0; i < PADSIZE; i++) {
      for (int j=0; j < PADSIZE; j++) {
        if (i % GRIDSIZE == 0 && j % GRIDSIZE == 0) {
          if (i==0 || j==0)
            FP.addch('+');
          else
            FP.addch(static_cast<chtype>('A' + (gridcount++ % 26)));
        }
        else if (i % GRIDSIZE == 0)
          FP.addch('-');
        else if (j % GRIDSIZE == 0)
          FP.addch('|');
        else
          FP.addch(' ');
      }
    }

    P.label("Pad Demo", NULL);
    FP();
    P.clear();
    return FALSE;
  }
};

//
// -------------------------------------------------------------------------
//
class PassiveItem : public NCursesMenuItem
{
public:
  PassiveItem(const char* text) : NCursesMenuItem(text) {
    options_off(O_SELECTABLE);
  }
};

//
// -------------------------------------------------------------------------
//
class ScanAction : public NCursesMenuItem
{
public:
  ScanAction(const char* s) : NCursesMenuItem(s) {
  }

  bool action() {
    NCursesPanel *mystd = new NCursesPanel();

    NCursesPanel *w = new NCursesPanel(mystd->lines() - 2, mystd->cols() - 2, 1, 1);
    w->box();
    w->refresh();

    NCursesPanel *s = new NCursesPanel(w->lines() - 6, w->cols() - 6, 3, 3);
    s->scrollok(TRUE);
    ::echo();

    s->printw("Enter decimal integers.  The running total will be shown\n");
    int nvalue = -1;
    int result = 0;
    while (nvalue != 0) {
      nvalue = 0;
      s->scanw("%d", &nvalue);
      if (nvalue != 0) {
        s->printw("%d: ", result += nvalue);
      }
      s->refresh();
    }
    s->printw("\nPress any key to continue...");
    s->getch();

    delete s;
    delete w;
    delete mystd;
    ::noecho();
    return FALSE;
  }
};

//
// -------------------------------------------------------------------------
//
class MyMenu : public NCursesMenu
{
private:
  NCursesPanel* P;
  NCursesMenuItem** I;
  UserData *u;
  #define n_items 7

public:
  MyMenu ()
    : NCursesMenu (n_items+2, 8, (lines()-10)/2, (cols()-10)/2),
      P(0), I(0), u(0)
  {
    u = new UserData(1);
    I = new NCursesMenuItem*[1+n_items];
    I[0] = new PassiveItem("One");
    I[1] = new PassiveItem("Two");
    I[2] = new MyAction<UserData> ("Silly", u);
    I[3] = new FormAction("Form");
    I[4] = new PadAction("Pad");
    I[5] = new ScanAction("Scan");
    I[6] = new QuitItem();
    I[7] = new NCursesMenuItem(); // Terminating empty item

    InitMenu(I, TRUE, TRUE);

    P = new NCursesPanel(1, n_items, LINES-1, 1);
    boldframe("Demo", "Silly");
    P->show();
  }

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

  MyMenu(const MyMenu& rhs)
    : NCursesMenu(rhs), P(0), I(0), u(0)
  {
  }

  ~MyMenu()
  {
    P->hide();
    delete P;
    delete u;
  }

  virtual void On_Menu_Init()
  {
    NCursesWindow W(::stdscr);
    P->move(0, 0);
    P->clrtoeol();
    for(int i=1; i<=count(); i++)
      P->addch('0' + i);
    P->bkgd(W.getbkgd());
    refresh();
  }

  virtual void On_Menu_Termination()
  {
    P->move(0, 0);
    P->clrtoeol();
    refresh();
  }

  virtual void On_Item_Init(NCursesMenuItem& item)
  {
    P->move(0, item.index());
    P->attron(A_REVERSE);
    P->printw("%1d", 1+item.index());
    P->attroff(A_REVERSE);
    refresh();
  }

  virtual void On_Item_Termination(NCursesMenuItem& item)
  {
    P->move(0, item.index());
    P->attroff(A_REVERSE);
    P->printw("%1d", 1+item.index());
    refresh();
  }
};
//
// -------------------------------------------------------------------------
//
class TestApplication : public NCursesApplication
{
protected:
  int titlesize() const { return 1; }
  void title();
  Soft_Label_Key_Set::Label_Layout useSLKs() const {
    return Soft_Label_Key_Set::PC_Style_With_Index;
  }
  void init_labels(Soft_Label_Key_Set& S) const;

public:
  TestApplication() : NCursesApplication(TRUE) {
  }

  int run();
};

void TestApplication::init_labels(Soft_Label_Key_Set& S) const
{
  for(int i=1; i <= S.labels(); i++) {
    char buf[8];
    assert(i < 100);
    ::_nc_SPRINTF(buf, _nc_SLIMIT(sizeof(buf)) "Key%02d", i);
    S[i] = buf;                                      // Text
    S[i] = Soft_Label_Key_Set::Soft_Label_Key::Left; // Justification
  }
}

void TestApplication::title()
{
  const char * const titleText = "Simple C++ Binding Demo";
  const int len = ::strlen(titleText);

  titleWindow->bkgd(screen_titles());
  titleWindow->addstr(0, (titleWindow->cols() - len)/2, titleText);
  titleWindow->noutrefresh();
}


int TestApplication::run()
{
  MyMenu M;
  M();
  return 0;
}

//
// -------------------------------------------------------------------------
//
static TestApplication *Demo = new TestApplication();
