/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "../cmCacheManager.h"
#include "../cmSystemTools.h"
#include "../cmVersion.h"
#include "../cmake.h"
#include "cmCursesMainForm.h"
#include "cmCursesStringWidget.h"
#include "cmCursesLabelWidget.h"
#include "cmCursesBoolWidget.h"
#include "cmCursesPathWidget.h"
#include "cmCursesFilePathWidget.h"
#include "cmCursesDummyWidget.h"
#include "cmCursesCacheEntryComposite.h"
#include "cmCursesLongMessageForm.h"


inline int ctrl(int z)
{
    return (z&037);
}

cmCursesMainForm::cmCursesMainForm(std::vector<std::string> const& args,
                                   int initWidth) :
  Args(args), InitialWidth(initWidth)
{
  this->NumberOfPages = 0;
  this->Fields = 0;
  this->Entries = 0;
  this->AdvancedMode = false;
  this->NumberOfVisibleEntries = 0;
  this->OkToGenerate = false;
  this->HelpMessage.push_back("Welcome to ccmake, curses based user interface for CMake.");
  this->HelpMessage.push_back("");
  this->HelpMessage.push_back(s_ConstHelpMessage);
  this->CMakeInstance = new cmake;
  this->CMakeInstance->SetCMakeEditCommand(
    cmSystemTools::GetCMakeCursesCommand());

  // create the arguments for the cmake object
  std::string whereCMake = cmSystemTools::GetProgramPath(this->Args[0].c_str());
  whereCMake += "/cmake";
  this->Args[0] = whereCMake;
  this->CMakeInstance->SetArgs(this->Args);
  this->SearchString = "";
  this->OldSearchString = "";
  this->SearchMode = false;
}

cmCursesMainForm::~cmCursesMainForm()
{
  if (this->Form)
    {
    unpost_form(this->Form);
    free_form(this->Form);
    this->Form = 0;
    }
  delete[] this->Fields;

  // Clean-up composites
  if (this->Entries)
    {
    std::vector<cmCursesCacheEntryComposite*>::iterator it;
    for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
      {
      delete *it;
      }
    }
  delete this->Entries;
  if (this->CMakeInstance)
    {
    delete this->CMakeInstance;
    this->CMakeInstance = 0;
    }
}

// See if a cache entry is in the list of entries in the ui.
bool cmCursesMainForm::LookForCacheEntry(const std::string& key)
{
  if (!this->Entries)
    {
    return false;
    }

  std::vector<cmCursesCacheEntryComposite*>::iterator it;
  for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
    {
    if (key == (*it)->Key)
      {
      return true;
      }
    }

  return false;
}

// Create new cmCursesCacheEntryComposite entries from the cache
void cmCursesMainForm::InitializeUI()
{
  // Create a vector of cmCursesCacheEntryComposite's
  // which contain labels, entries and new entry markers
  std::vector<cmCursesCacheEntryComposite*>* newEntries =
    new std::vector<cmCursesCacheEntryComposite*>;
  newEntries->reserve(this->CMakeInstance->GetCacheManager()->GetSize());

  // Count non-internal and non-static entries
  int count=0;
  for(cmCacheManager::CacheIterator i =
        this->CMakeInstance->GetCacheManager()->NewIterator();
      !i.IsAtEnd(); i.Next())
    {
    if ( i.GetType() != cmCacheManager::INTERNAL &&
         i.GetType() != cmCacheManager::STATIC  &&
         i.GetType() != cmCacheManager::UNINITIALIZED)
      {
      ++count;
      }
    }

  int entrywidth = this->InitialWidth - 35;

  cmCursesCacheEntryComposite* comp;
  if ( count == 0 )
    {
    // If cache is empty, display a label saying so and a
    // dummy entry widget (does not respond to input)
    comp = new cmCursesCacheEntryComposite("EMPTY CACHE", 30, 30);
    comp->Entry = new cmCursesDummyWidget(1, 1, 1, 1);
    newEntries->push_back(comp);
    }
  else
    {
    // Create the composites.

    // First add entries which are new
    for(cmCacheManager::CacheIterator i =
          this->CMakeInstance->GetCacheManager()->NewIterator();
        !i.IsAtEnd(); i.Next())
      {
      std::string key = i.GetName();
      if ( i.GetType() == cmCacheManager::INTERNAL ||
           i.GetType() == cmCacheManager::STATIC ||
           i.GetType() == cmCacheManager::UNINITIALIZED )
        {
        continue;
        }

      if (!this->LookForCacheEntry(key))
        {
        newEntries->push_back(new cmCursesCacheEntryComposite(key, i,
                                                              true, 30,
                                                              entrywidth));
        this->OkToGenerate = false;
        }
      }

    // then add entries which are old
    for(cmCacheManager::CacheIterator i =
          this->CMakeInstance->GetCacheManager()->NewIterator();
        !i.IsAtEnd(); i.Next())
      {
      std::string key = i.GetName();
      if ( i.GetType() == cmCacheManager::INTERNAL ||
           i.GetType() == cmCacheManager::STATIC ||
           i.GetType() == cmCacheManager::UNINITIALIZED )
        {
        continue;
        }

      if (this->LookForCacheEntry(key))
        {
        newEntries->push_back(new cmCursesCacheEntryComposite(key, i,
                                                              false, 30,
                                                              entrywidth));
        }
      }
    }

  // Clean old entries
  if (this->Entries)
    {
    // Have to call delete on each pointer
    std::vector<cmCursesCacheEntryComposite*>::iterator it;
    for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
      {
      delete *it;
      }
    }
  delete this->Entries;
  this->Entries = newEntries;

  // Compute fields from composites
  this->RePost();
}


void cmCursesMainForm::RePost()
{
  // Create the fields to be passed to the form.
  if (this->Form)
    {
    unpost_form(this->Form);
    free_form(this->Form);
    this->Form = 0;
    }
  delete[] this->Fields;
  if (this->AdvancedMode)
    {
    this->NumberOfVisibleEntries = this->Entries->size();
    }
  else
    {
    // If normal mode, count only non-advanced entries
    this->NumberOfVisibleEntries = 0;
    std::vector<cmCursesCacheEntryComposite*>::iterator it;
    for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
      {
      cmCacheManager::CacheIterator mit =
        this->CMakeInstance->GetCacheManager()->GetCacheIterator((*it)->GetValue());
      if (mit.IsAtEnd() ||
          (!this->AdvancedMode && mit.GetPropertyAsBool("ADVANCED")))
        {
        continue;
        }
      this->NumberOfVisibleEntries++;
      }
    }
  // there is always one even if it is the dummy one
  if(this->NumberOfVisibleEntries == 0)
    {
    this->NumberOfVisibleEntries = 1;
    }
  // Assign the fields: 3 for each entry: label, new entry marker
  // ('*' or ' ') and entry widget
  this->Fields = new FIELD*[3*this->NumberOfVisibleEntries+1];
  size_t cc;
  for ( cc = 0; cc < 3 * this->NumberOfVisibleEntries+1; cc ++ )
    {
    this->Fields[cc] = 0;
    }

  // Assign fields
  int j=0;
  std::vector<cmCursesCacheEntryComposite*>::iterator it;
  for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
    {
    cmCacheManager::CacheIterator mit =
      this->CMakeInstance->GetCacheManager()->GetCacheIterator((*it)->GetValue());
    if (mit.IsAtEnd() ||
        (!this->AdvancedMode && mit.GetPropertyAsBool("ADVANCED")))
      {
      continue;
      }
    this->Fields[3*j]    = (*it)->Label->Field;
    this->Fields[3*j+1]  = (*it)->IsNewLabel->Field;
    this->Fields[3*j+2]  = (*it)->Entry->Field;
    j++;
    }
  // if no cache entries there should still be one dummy field
  if(j == 0)
    {
    it = this->Entries->begin();
    this->Fields[0]    = (*it)->Label->Field;
    this->Fields[1]  = (*it)->IsNewLabel->Field;
    this->Fields[2]  = (*it)->Entry->Field;
    this->NumberOfVisibleEntries = 1;
    }
  // Has to be null terminated.
  this->Fields[3*this->NumberOfVisibleEntries] = 0;
}

void cmCursesMainForm::Render(int left, int top, int width, int height)
{

  if (this->Form)
    {
    FIELD* currentField = current_field(this->Form);
    cmCursesWidget* cw = reinterpret_cast<cmCursesWidget*>
      (field_userptr(currentField));
    // If in edit mode, get out of it
    if ( cw->GetType() == cmCacheManager::STRING ||
         cw->GetType() == cmCacheManager::PATH   ||
         cw->GetType() == cmCacheManager::FILEPATH )
      {
      cmCursesStringWidget* sw = static_cast<cmCursesStringWidget*>(cw);
      sw->SetInEdit(false);
      }
    // Delete the previous form
    unpost_form(this->Form);
    free_form(this->Form);
    this->Form = 0;
    }

  // Wrong window size
  if ( width < cmCursesMainForm::MIN_WIDTH  ||
       width < this->InitialWidth               ||
       height < cmCursesMainForm::MIN_HEIGHT )
    {
    return;
    }

  // Leave room for toolbar
  height -= 7;

  if (this->AdvancedMode)
    {
    this->NumberOfVisibleEntries = this->Entries->size();
    }
  else
    {
    // If normal, display only non-advanced entries
    this->NumberOfVisibleEntries = 0;
    std::vector<cmCursesCacheEntryComposite*>::iterator it;
    for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
      {
      cmCacheManager::CacheIterator mit =
        this->CMakeInstance->GetCacheManager()->GetCacheIterator((*it)->GetValue());
      if (mit.IsAtEnd() ||
          (!this->AdvancedMode && mit.GetPropertyAsBool("ADVANCED")))
        {
        continue;
        }
      this->NumberOfVisibleEntries++;
      }
    }

  // Re-adjust the fields according to their place
  this->NumberOfPages = 1;
  if (height > 0)
    {
    bool isNewPage;
    int i=0;
    std::vector<cmCursesCacheEntryComposite*>::iterator it;
    for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
      {
      cmCacheManager::CacheIterator mit =
        this->CMakeInstance->GetCacheManager()->GetCacheIterator((*it)->GetValue());
      if (mit.IsAtEnd() ||
          (!this->AdvancedMode && mit.GetPropertyAsBool("ADVANCED")))
        {
        continue;
        }
      int row = (i % height) + 1;
      int page = (i / height) + 1;
      isNewPage = ( page > 1 ) && ( row == 1 );

      if (isNewPage)
        {
        this->NumberOfPages++;
        }
      (*it)->Label->Move(left, top+row-1, isNewPage);
      (*it)->IsNewLabel->Move(left+32, top+row-1, false);
      (*it)->Entry->Move(left+33, top+row-1, false);
      (*it)->Entry->SetPage(this->NumberOfPages);
      i++;
      }
    }

  // Post the form
  this->Form = new_form(this->Fields);
  post_form(this->Form);
  // Update toolbar
  this->UpdateStatusBar();
  this->PrintKeys();

  touchwin(stdscr);
  refresh();
}

void cmCursesMainForm::PrintKeys(int process /* = 0 */)
{
  int x,y;
  getmaxyx(stdscr, y, x);
  if ( x < cmCursesMainForm::MIN_WIDTH  ||
       x < this->InitialWidth               ||
       y < cmCursesMainForm::MIN_HEIGHT )
    {
    return;
    }

  // Give the current widget (if it exists), a chance to print keys
  cmCursesWidget* cw = 0;
  if (this->Form)
    {
    FIELD* currentField = current_field(this->Form);
    cw = reinterpret_cast<cmCursesWidget*>(field_userptr(currentField));
    }

  if (cw)
    {
    cw->PrintKeys();
    }

//    {
//    }
//  else
//    {
  char firstLine[512]="";
  char secondLine[512]="";
  char thirdLine[512]="";
  if (process)
    {
    const char* clearLine =
      "                                                                    ";
    strcpy(firstLine, clearLine);
    strcpy(secondLine, clearLine);
    strcpy(thirdLine, clearLine);
    }
  else
    {
    if (this->OkToGenerate)
      {
      sprintf(firstLine,
              "Press [c] to configure       Press [g] to generate and exit");
      }
    else
      {
      sprintf(firstLine,  "Press [c] to configure                                   ");
      }
    {
      const char* toggleKeyInstruction =
        "Press [t] to toggle advanced mode (Currently %s)";
      sprintf(thirdLine,
              toggleKeyInstruction,
              this->AdvancedMode ? "On" : "Off");
    }
    sprintf(secondLine,
            "Press [h] for help           "
            "Press [q] to quit without generating");
    }

  curses_move(y-4,0);
  char fmt[512] = "Press [enter] to edit option";
  if ( process )
    {
    strcpy(fmt, "                           ");
    }
  printw(fmt);
  curses_move(y-3,0);
  printw(firstLine);
  curses_move(y-2,0);
  printw(secondLine);
  curses_move(y-1,0);
  printw(thirdLine);

  if (cw)
    {
    sprintf(firstLine, "Page %d of %d", cw->GetPage(), this->NumberOfPages);
    curses_move(0,65-static_cast<unsigned int>(strlen(firstLine))-1);
    printw(firstLine);
    }
//    }

  pos_form_cursor(this->Form);

}

// Print the key of the current entry and the CMake version
// on the status bar. Designed for a width of 80 chars.
void cmCursesMainForm::UpdateStatusBar(const char* message)
{
  int x,y;
  getmaxyx(stdscr, y, x);
  // If window size is too small, display error and return
  if ( x < cmCursesMainForm::MIN_WIDTH  ||
       x < this->InitialWidth               ||
       y < cmCursesMainForm::MIN_HEIGHT )
    {
    curses_clear();
    curses_move(0,0);
    char fmt[] = "Window is too small. A size of at least %dx%d is required.";
    printw(fmt,
           (cmCursesMainForm::MIN_WIDTH < this->InitialWidth ?
            this->InitialWidth : cmCursesMainForm::MIN_WIDTH),
           cmCursesMainForm::MIN_HEIGHT);
    touchwin(stdscr);
    wrefresh(stdscr);
    return;
    }

  // Get the key of the current entry
  FIELD* cur = current_field(this->Form);
  int findex = field_index(cur);
  cmCursesWidget* lbl = 0;
  if ( findex >= 0 )
    {
    lbl = reinterpret_cast<cmCursesWidget*>(field_userptr(this->Fields[findex-2]));
    }
  char help[128] = "";
  const char* curField = "";
  if ( lbl )
    {
    curField = lbl->GetValue();

    // Get the help string of the current entry
    // and add it to the help string
    cmCacheManager::CacheIterator it =
      this->CMakeInstance->GetCacheManager()->GetCacheIterator(curField);
    if (!it.IsAtEnd())
      {
      const char* hs = it.GetProperty("HELPSTRING");
      if ( hs )
        {
        strncpy(help, hs, 127);
        help[127] = '\0';
        }
      else
        {
        help[0] = 0;
        }
      }
    else
      {
      sprintf(help," ");
      }
    }

  // Join the key, help string and pad with spaces
  // (or truncate) as necessary
  char bar[cmCursesMainForm::MAX_WIDTH];
  size_t i, curFieldLen = strlen(curField);
  size_t helpLen = strlen(help);

  size_t width;
  if (x < cmCursesMainForm::MAX_WIDTH )
    {
    width = x;
    }
  else
    {
    width = cmCursesMainForm::MAX_WIDTH;
    }

  if ( message )
    {
    curField = message;
    curFieldLen = strlen(message);
    if ( curFieldLen < width )
      {
      strcpy(bar, curField);
      for(i=curFieldLen; i < width; ++i)
        {
        bar[i] = ' ';
        }
      }
    else
      {
      strncpy(bar, curField, width);
      }
   }
  else
    {
    if (curFieldLen >= width)
      {
      strncpy(bar, curField, width);
      }
    else
      {
      strcpy(bar, curField);
      bar[curFieldLen] = ':';
      bar[curFieldLen+1] = ' ';
      if (curFieldLen + helpLen + 2 >= width)
        {
        strncpy(bar+curFieldLen+2, help, width
                - curFieldLen - 2);
        }
      else
        {
        strcpy(bar+curFieldLen+2, help);
        for(i=curFieldLen+helpLen+2; i < width; ++i)
          {
          bar[i] = ' ';
          }
        }
      }
    }


  bar[width] = '\0';


  // Display CMake version info on the next line
  // We want to display this on the right
  char version[cmCursesMainForm::MAX_WIDTH];
  char vertmp[128];
  sprintf(vertmp,"CMake Version %s", cmVersion::GetCMakeVersion());
  size_t sideSpace = (width-strlen(vertmp));
  for(i=0; i<sideSpace; i++) { version[i] = ' '; }
  sprintf(version+sideSpace, "%s", vertmp);
  version[width] = '\0';

  // Now print both lines
  curses_move(y-5,0);
  attron(A_STANDOUT);
  char format[] = "%s";
  printw(format, bar);
  attroff(A_STANDOUT);
  curses_move(y-4,0);
  printw(version);
  pos_form_cursor(this->Form);
}

void cmCursesMainForm::UpdateProgress(const char *msg, float prog, void* vp)
{
  cmCursesMainForm* cm = static_cast<cmCursesMainForm*>(vp);
  if ( !cm )
    {
    return;
    }
  char tmp[1024];
  const char *cmsg = tmp;
  if ( prog >= 0 )
    {
    sprintf(tmp, "%s %i%%",msg,(int)(100*prog));
    }
  else
    {
    cmsg = msg;
    }
  cm->UpdateStatusBar(cmsg);
  cm->PrintKeys(1);
  curses_move(1,1);
  touchwin(stdscr);
  refresh();
}

int cmCursesMainForm::Configure(int noconfigure)
{
  int xi,yi;
  getmaxyx(stdscr, yi, xi);

  curses_move(1,1);
  this->UpdateStatusBar("Configuring, please wait...");
  this->PrintKeys(1);
  touchwin(stdscr);
  refresh();
  this->CMakeInstance->SetProgressCallback(cmCursesMainForm::UpdateProgress, this);

  // always save the current gui values to disk
  this->FillCacheManagerFromUI();
  this->CMakeInstance->GetCacheManager()->SaveCache(
    this->CMakeInstance->GetHomeOutputDirectory());
  this->LoadCache(0);

  // Get rid of previous errors
  this->Errors = std::vector<std::string>();

  // run the generate process
  this->OkToGenerate = true;
  int retVal;
  if ( noconfigure )
    {
    retVal = this->CMakeInstance->DoPreConfigureChecks();
    this->OkToGenerate = false;
    if ( retVal > 0 )
      {
      retVal = 0;
      }
    }
  else
    {
    retVal = this->CMakeInstance->Configure();
    }
  this->CMakeInstance->SetProgressCallback(0, 0);

  keypad(stdscr,TRUE); /* Use key symbols as
                          KEY_DOWN*/

  if( retVal != 0 || !this->Errors.empty())
    {
    // see if there was an error
    if(cmSystemTools::GetErrorOccuredFlag())
      {
      this->OkToGenerate = false;
      }
    int xx,yy;
    getmaxyx(stdscr, yy, xx);
    cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(
      this->Errors,
      cmSystemTools::GetErrorOccuredFlag()
      ? "Errors occurred during the last pass." :
      "CMake produced the following output.");
    // reset error condition
    cmSystemTools::ResetErrorOccuredFlag();
    CurrentForm = msgs;
    msgs->Render(1,1,xx,yy);
    msgs->HandleInput();
    // If they typed the wrong source directory, we report
    // an error and exit
    if ( retVal == -2 )
      {
      return retVal;
      }
    CurrentForm = this;
    this->Render(1,1,xx,yy);
    }

  this->InitializeUI();
  this->Render(1, 1, xi, yi);

  return 0;
}

int cmCursesMainForm::Generate()
{
  int xi,yi;
  getmaxyx(stdscr, yi, xi);

  curses_move(1,1);
  this->UpdateStatusBar("Generating, please wait...");
  this->PrintKeys(1);
  touchwin(stdscr);
  refresh();
  this->CMakeInstance->SetProgressCallback(cmCursesMainForm::UpdateProgress, this);

  // Get rid of previous errors
  this->Errors = std::vector<std::string>();

  // run the generate process
  int retVal = this->CMakeInstance->Generate();

  this->CMakeInstance->SetProgressCallback(0, 0);
  keypad(stdscr,TRUE); /* Use key symbols as
                          KEY_DOWN*/

  if( retVal != 0 || !this->Errors.empty())
    {
    // see if there was an error
    if(cmSystemTools::GetErrorOccuredFlag())
      {
      this->OkToGenerate = false;
      }
    // reset error condition
    cmSystemTools::ResetErrorOccuredFlag();
    int xx,yy;
    getmaxyx(stdscr, yy, xx);
    const char* title = "Messages during last pass.";
    if(cmSystemTools::GetErrorOccuredFlag())
      {
      title = "Errors occurred during the last pass.";
      }
    cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(this->Errors,
                                                                title);
    CurrentForm = msgs;
    msgs->Render(1,1,xx,yy);
    msgs->HandleInput();
    // If they typed the wrong source directory, we report
    // an error and exit
    if ( retVal == -2 )
      {
      return retVal;
      }
    CurrentForm = this;
    this->Render(1,1,xx,yy);
    }

  this->InitializeUI();
  this->Render(1, 1, xi, yi);

  return 0;
}

void cmCursesMainForm::AddError(const char* message, const char*)
{
  this->Errors.push_back(message);
}

void cmCursesMainForm::RemoveEntry(const char* value)
{
  if (!value)
    {
    return;
    }

  std::vector<cmCursesCacheEntryComposite*>::iterator it;
  for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
    {
    const char* val = (*it)->GetValue();
    if (  val && !strcmp(value, val) )
      {
      this->CMakeInstance->UnwatchUnusedCli(value);
      this->Entries->erase(it);
      break;
      }
    }
}

// copy from the list box to the cache manager
void cmCursesMainForm::FillCacheManagerFromUI()
{
  size_t size = this->Entries->size();
  for(size_t i=0; i < size; i++)
    {
    cmCacheManager::CacheIterator it =
      this->CMakeInstance->GetCacheManager()->GetCacheIterator(
        (*this->Entries)[i]->Key.c_str());
    if (!it.IsAtEnd())
      {
      std::string oldValue = it.GetValue();
      std::string newValue = (*this->Entries)[i]->Entry->GetValue();
      std::string fixedOldValue;
      std::string fixedNewValue;
      this->FixValue(it.GetType(), oldValue, fixedOldValue);
      this->FixValue(it.GetType(), newValue, fixedNewValue);

      if(!(fixedOldValue == fixedNewValue))
        {
        // The user has changed the value.  Mark it as modified.
        it.SetProperty("MODIFIED", true);
        it.SetValue(fixedNewValue.c_str());
        }
      }
    }
}

void cmCursesMainForm::FixValue(cmCacheManager::CacheEntryType type,
                                const std::string& in, std::string& out) const
{
  out = in.substr(0,in.find_last_not_of(" ")+1);
  if(type == cmCacheManager::PATH || type == cmCacheManager::FILEPATH)
    {
    cmSystemTools::ConvertToUnixSlashes(out);
    }
  if(type == cmCacheManager::BOOL)
    {
    if(cmSystemTools::IsOff(out.c_str()))
      {
      out = "OFF";
      }
    else
      {
      out = "ON";
      }
    }
}

#include <unistd.h>

void cmCursesMainForm::HandleInput()
{
  int x=0,y=0;

  if (!this->Form)
    {
    return;
    }

  FIELD* currentField;
  cmCursesWidget* currentWidget;

  char debugMessage[128];

  for(;;)
    {
    this->UpdateStatusBar();
    this->PrintKeys();
    if ( this->SearchMode )
      {
      std::string searchstr = "Search: " + this->SearchString;
      this->UpdateStatusBar( searchstr.c_str() );
      this->PrintKeys(1);
      curses_move(y-5,static_cast<unsigned int>(searchstr.size()));
      //curses_move(1,1);
      touchwin(stdscr);
      refresh();
      }
    int key = getch();

    getmaxyx(stdscr, y, x);
    // If window too small, handle 'q' only
    if ( x < cmCursesMainForm::MIN_WIDTH  ||
         y < cmCursesMainForm::MIN_HEIGHT )
      {
      // quit
      if ( key == 'q' )
        {
        break;
        }
      else
        {
        continue;
        }
      }

    currentField = current_field(this->Form);
    currentWidget = reinterpret_cast<cmCursesWidget*>(field_userptr(
      currentField));

    bool widgetHandled=false;

    if ( this->SearchMode )
      {
      if ( key == 10 || key == KEY_ENTER )
        {
        this->SearchMode = false;
        if ( this->SearchString.size() > 0 )
          {
          this->JumpToCacheEntry(this->SearchString.c_str());
          this->OldSearchString = this->SearchString;
          }
        this->SearchString = "";
        }
      /*
      else if ( key == KEY_ESCAPE )
        {
        this->SearchMode = false;
        }
      */
      else if ((key >= 'a' && key <= 'z') ||
               (key >= 'A' && key <= 'Z') ||
               (key >= '0' && key <= '9') ||
               (key == '_' ))
        {
        if ( this->SearchString.size() < static_cast<std::string::size_type>(x-10) )
          {
          this->SearchString += static_cast<char>(key);
          }
        }
      else if ( key == ctrl('h') || key == KEY_BACKSPACE || key == KEY_DC )
        {
        if ( this->SearchString.size() > 0 )
          {
          this->SearchString.resize(this->SearchString.size()-1);
          }
        }
      }
    else if (currentWidget && !this->SearchMode)
      {
      // Ask the current widget if it wants to handle input
      widgetHandled = currentWidget->HandleInput(key, this, stdscr);
      if (widgetHandled)
        {
        this->OkToGenerate = false;
        this->UpdateStatusBar();
        this->PrintKeys();
        }
      }
    if ((!currentWidget || !widgetHandled) && !this->SearchMode)
      {
      // If the current widget does not want to handle input,
      // we handle it.
      sprintf(debugMessage, "Main form handling input, key: %d", key);
      cmCursesForm::LogMessage(debugMessage);
      // quit
      if ( key == 'q' )
        {
        break;
        }
      // if not end of page, next field otherwise next page
      // each entry consists of fields: label, isnew, value
      // therefore, the label field for the prev. entry is index-5
      // and the label field for the next entry is index+1
      // (index always corresponds to the value field)
      else if ( key == KEY_DOWN || key == ctrl('n') )
        {
        FIELD* cur = current_field(this->Form);
        size_t findex = field_index(cur);
        if ( findex == 3*this->NumberOfVisibleEntries-1 )
          {
          continue;
          }
        if (new_page(this->Fields[findex+1]))
          {
          form_driver(this->Form, REQ_NEXT_PAGE);
          }
        else
          {
          form_driver(this->Form, REQ_NEXT_FIELD);
          }
        }
      // if not beginning of page, previous field, otherwise previous page
      // each entry consists of fields: label, isnew, value
      // therefore, the label field for the prev. entry is index-5
      // and the label field for the next entry is index+1
      // (index always corresponds to the value field)
      else if ( key == KEY_UP || key == ctrl('p') )
        {
        FIELD* cur = current_field(this->Form);
        int findex = field_index(cur);
        if ( findex == 2 )
          {
          continue;
          }
        if ( new_page(this->Fields[findex-2]) )
          {
          form_driver(this->Form, REQ_PREV_PAGE);
          set_current_field(this->Form, this->Fields[findex-3]);
          }
        else
          {
          form_driver(this->Form, REQ_PREV_FIELD);
          }
        }
      // pg down
      else if ( key == KEY_NPAGE || key == ctrl('d') )
        {
        form_driver(this->Form, REQ_NEXT_PAGE);
        }
      // pg up
      else if ( key == KEY_PPAGE || key == ctrl('u') )
        {
        form_driver(this->Form, REQ_PREV_PAGE);
        }
      // configure
      else if ( key == 'c' )
        {
        this->Configure();
        }
      // display help
      else if ( key == 'h' )
        {
        getmaxyx(stdscr, y, x);

        FIELD* cur = current_field(this->Form);
        int findex = field_index(cur);
        cmCursesWidget* lbl = reinterpret_cast<cmCursesWidget*>(field_userptr(
          this->Fields[findex-2]));
        const char* curField = lbl->GetValue();
        const char* helpString=0;
        cmCacheManager::CacheIterator it =
          this->CMakeInstance->GetCacheManager()->GetCacheIterator(curField);
        if (!it.IsAtEnd())
          {
          helpString = it.GetProperty("HELPSTRING");
          }
        if (helpString)
          {
          char* message = new char[strlen(curField)+strlen(helpString)
                                  +strlen("Current option is: \n Help string for this option is: \n")+10];
          sprintf(message,"Current option is: %s\nHelp string for this option is: %s\n", curField, helpString);
          this->HelpMessage[1] = message;
          delete[] message;
          }
        else
          {
          this->HelpMessage[1] = "";
          }

        cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(this->HelpMessage,
                                                                    "Help.");
        CurrentForm = msgs;
        msgs->Render(1,1,x,y);
        msgs->HandleInput();
        CurrentForm = this;
        this->Render(1,1,x,y);
        set_current_field(this->Form, cur);
        }
      // display last errors
      else if ( key == 'l' )
        {
        getmaxyx(stdscr, y, x);
        cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(this->Errors,
                                                                    "Errors occurred during the last pass.");
        CurrentForm = msgs;
        msgs->Render(1,1,x,y);
        msgs->HandleInput();
        CurrentForm = this;
        this->Render(1,1,x,y);
        }
      else if ( key == '/' )
        {
        this->SearchMode = true;
        this->UpdateStatusBar("Search");
        this->PrintKeys(1);
        touchwin(stdscr);
        refresh();
        }
      else if ( key == 'n' )
        {
        if ( this->OldSearchString.size() > 0 )
          {
          this->JumpToCacheEntry(this->OldSearchString.c_str());
          }
        }
      // switch advanced on/off
      else if ( key == 't' )
        {
        if (this->AdvancedMode)
          {
          this->AdvancedMode = false;
          }
        else
          {
          this->AdvancedMode = true;
          }
        getmaxyx(stdscr, y, x);
        this->RePost();
        this->Render(1, 1, x, y);
        }
      // generate and exit
      else if ( key == 'g' )
        {
        if ( this->OkToGenerate )
          {
          this->Generate();
          break;
          }
        }
      // delete cache entry
      else if ( key == 'd' && this->NumberOfVisibleEntries )
        {
        this->OkToGenerate = false;
        FIELD* cur = current_field(this->Form);
        size_t findex = field_index(cur);

        // make the next or prev. current field after deletion
        // each entry consists of fields: label, isnew, value
        // therefore, the label field for the prev. entry is findex-5
        // and the label field for the next entry is findex+1
        // (findex always corresponds to the value field)
        FIELD* nextCur;
        if ( findex == 2 )
          {
          nextCur=0;
          }
        else if ( findex == 3*this->NumberOfVisibleEntries-1 )
          {
          nextCur = this->Fields[findex-5];
          }
        else
          {
          nextCur = this->Fields[findex+1];
          }

        // Get the label widget
        // each entry consists of fields: label, isnew, value
        // therefore, the label field for the is findex-2
        // (findex always corresponds to the value field)
        cmCursesWidget* lbl
          = reinterpret_cast<cmCursesWidget*>(
            field_userptr(this->Fields[findex-2]));
        if ( lbl )
          {
          this->CMakeInstance->GetCacheManager()->RemoveCacheEntry(lbl->GetValue());

          std::string nextVal;
          if (nextCur)
            {
            nextVal = (reinterpret_cast<cmCursesWidget*>(field_userptr(nextCur))->GetValue());
            }

          getmaxyx(stdscr, y, x);
          this->RemoveEntry(lbl->GetValue());
          this->RePost();
          this->Render(1, 1, x, y);

          if (nextCur)
            {
            // make the next or prev. current field after deletion
            nextCur = 0;
            std::vector<cmCursesCacheEntryComposite*>::iterator it;
            for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
              {
              if (nextVal == (*it)->Key)
                {
                nextCur = (*it)->Entry->Field;
                }
              }

            if (nextCur)
              {
              set_current_field(this->Form, nextCur);
              }
            }
          }
        }
      }

    touchwin(stdscr);
    wrefresh(stdscr);
    }
}

int cmCursesMainForm::LoadCache(const char *)

{
  int r = this->CMakeInstance->LoadCache();
  if(r < 0)
    {
    return r;
    }
  this->CMakeInstance->SetCacheArgs(this->Args);
  this->CMakeInstance->PreLoadCMakeFiles();
  return r;
}

void cmCursesMainForm::JumpToCacheEntry(const char* astr)
{
  std::string str;
  if ( astr )
    {
    str = cmSystemTools::LowerCase(astr);
    }

  if(str.empty())
    {
    return;
    }
  FIELD* cur = current_field(this->Form);
  int start_index = field_index(cur);
  int findex = start_index;
  for(;;)
    {
    if ( str.size() > 0 )
      {
      cmCursesWidget* lbl = 0;
      if ( findex >= 0 )
        {
        lbl = reinterpret_cast<cmCursesWidget*>(field_userptr(this->Fields[findex-2]));
        }
      if ( lbl )
        {
        const char* curField = lbl->GetValue();
        if ( curField )
          {
          std::string cfld = cmSystemTools::LowerCase(curField);
          if ( cfld.find(str) != cfld.npos && findex != start_index )
            {
            break;
            }
          }
        }
      }
    if ( size_t(findex) >= 3* this->NumberOfVisibleEntries-1 )
      {
      set_current_field(this->Form, this->Fields[2]);
      }
    else if (new_page(this->Fields[findex+1]))
      {
      form_driver(this->Form, REQ_NEXT_PAGE);
      }
    else
      {
      form_driver(this->Form, REQ_NEXT_FIELD);
      }
    /*
    char buffer[1024];
    sprintf(buffer, "Line: %d != %d / %d\n", findex, idx, this->NumberOfVisibleEntries);
    touchwin(stdscr);
    refresh();
    this->UpdateStatusBar( buffer );
    usleep(100000);
    */
    cur = current_field(this->Form);
    findex = field_index(cur);
    if ( findex == start_index )
      {
      break;
      }
    }
}


const char* cmCursesMainForm::s_ConstHelpMessage =
"CMake is used to configure and generate build files for software projects. "
"The basic steps for configuring a project with ccmake are as follows:\n\n"
"1. Run ccmake in the directory where you want the object and executable files to be placed (build directory). If the source directory is not the same as this build directory, you have to specify it as an argument on the command line.\n\n"
"2. When ccmake is run, it will read the configuration files and display the current build options. "
"If you have run CMake before and have updated the configuration files since then, any new entries will be displayed on top and will be marked with a *. "
"On the other hand, the first time you run ccmake, all build options will be new and will be marked as such. "
"At this point, you can modify any options (see keys below) you want to change. "
"When you are satisfied with your changes, press 'c' to have CMake process the configuration files. "
"Please note that changing some options may cause new ones to appear. These will be shown on top and will be marked with *. "
"Repeat this procedure until you are satisfied with all the options and there are no new entries. "
"At this point, a new command will appear: G)enerate and Exit. You can now hit 'g' to have CMake generate all the build files (i.e. makefiles or project files) and exit. "
"At any point during the process, you can exit ccmake with 'q'. However, this will not generate/change any build files.\n\n"
"ccmake KEYS:\n\n"
"Navigation: "
"You can use the arrow keys and page up, down to navigate the options. Alternatively, you can use the following keys: \n"
" C-n : next option\n"
" C-p : previous options\n"
" C-d : down one page\n"
" C-u : up one page\n\n"
"Editing options: "
"To change an option  press enter or return. If the current options is a boolean, this will toggle it's value. "
"Otherwise, ccmake will enter edit mode. In this mode you can edit an option using arrow keys and backspace. Alternatively, you can use the following keys:\n"
" C-b : back one character\n"
" C-f : forward one character\n"
" C-a : go to the beginning of the field\n"
" C-e : go to the end of the field\n"
" C-d : delete previous character\n"
" C-k : kill the rest of the field\n"
" Esc : Restore field (discard last changes)\n"
" Enter : Leave edit mode\n"
"You can also delete an option by pressing 'd'\n\n"
"Commands:\n"
" q : quit ccmake without generating build files\n"
" h : help, shows this screen\n"
" c : process the configuration files with the current options\n"
" g : generate build files and exit, only available when there are no "
"new options and no errors have been detected during last configuration.\n"
" l : shows last errors\n"
" t : toggles advanced mode. In normal mode, only the most important options are shown. In advanced mode, all options are shown. We recommend using normal mode unless you are an expert.\n"
" / : search for a variable name.\n";
