/*=========================================================================

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile: cmCursesMainForm.cxx,v $
  Language:  C++
  Date:      $Date: 2012/03/29 17:21:09 $
  Version:   $Revision: 1.1.1.1 $

  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.

     This software is distributed WITHOUT ANY WARRANTY; without even 
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     PURPOSE.  See the above copyright notices 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("ccmake");

  // 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->CMakeInstance->SetCMakeCommand(whereCMake.c_str());
  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 char* key)
{
  if (!key || !this->Entries)
    {
    return false;
    }

  std::vector<cmCursesCacheEntryComposite*>::iterator it;
  for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
    {
    if (!strcmp(key, (*it)->Key.c_str()))
      {
      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())
      {
      const char* 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())
      {
      const char* 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];
  int 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
  bool isNewPage;
  int i=0;
  this->NumberOfPages = 1;
  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)
    {
    sprintf(firstLine, 
            "                                                               ");  
    sprintf(secondLine, 
            "                                                               ");  
    sprintf(thirdLine, 
            "                                                               ");  
    }
  else
    {
    if (this->OkToGenerate)
      {
      sprintf(firstLine,  
              "Press [c] to configure     Press [g] to generate and exit");
      }
    else
      {
      sprintf(firstLine,  "Press [c] to configure                                   ");
      }
    if (this->AdvancedMode)
      {
      sprintf(thirdLine,  "Press [t] to toggle advanced mode (Currently On)");
      }
    else
      {
      sprintf(thirdLine,  "Press [t] to toggle advanced mode (Currently 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-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];
  int i, curFieldLen = strlen(curField);
  int helpLen = strlen(help);

  int 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 %d.%d - %s", cmVersion::GetMajorVersion(),
          cmVersion::GetMinorVersion(),cmVersion::GetReleaseVersion().c_str());
  int 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;
      }
    // reset error condition
    cmSystemTools::ResetErrorOccuredFlag();
    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.");
    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->Entries->erase(it);
      break;
      }
    }
}

// copy from the list box to the cache manager
void cmCursesMainForm::FillCacheManagerFromUI()
{   
  int size = this->Entries->size();
  for(int 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,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(-1, 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 += 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);
        int 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(-1, 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);
        int 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(int idx, const char* astr)
{
  std::string str;
  if ( astr )
    {
    str = cmSystemTools::LowerCase(astr);
    }

  if ( idx > this->NumberOfVisibleEntries )
    {
    return;
    }
  if ( idx < 0 && str.size() == 0)
    {
    return;
    }
  FIELD* cur = current_field(this->Form);
  int start_index = field_index(cur);
  int findex = start_index;
  while ( (findex / 3) != idx ) 
    {
    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 ( 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";


