/*============================================================================
  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 "cmCursesOptionsWidget.h"
#include "cmCursesMainForm.h"

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

cmCursesOptionsWidget::cmCursesOptionsWidget(int width, int height,
                                       int left, int top) :
  cmCursesWidget(width, height, left, top)
{
  this->Type = cmCacheManager::BOOL; // this is a bit of a hack
  // there is no option type, and string type causes ccmake to cast
  // the widget into a string widget at some point.  BOOL is safe for
  // now.
  set_field_fore(this->Field,  A_NORMAL);
  set_field_back(this->Field,  A_STANDOUT);
  field_opts_off(this->Field,  O_STATIC);
}

bool cmCursesOptionsWidget::HandleInput(int& key, cmCursesMainForm*, WINDOW* w)
{

  // 10 == enter
  if (key == 10 || key == KEY_ENTER)
    {
    this->NextOption();
    touchwin(w);
    wrefresh(w);
    return true;
    }
  else if (key == KEY_LEFT || key == ctrl('b'))
    {
    touchwin(w);
    wrefresh(w);
    this->PreviousOption();
    return true;
    }
  else if (key == KEY_RIGHT || key == ctrl('f'))
    {
    this->NextOption();
    touchwin(w);
    wrefresh(w);
    return true;
    }
  else
    {
    return false;
    }
  return false;
}

void cmCursesOptionsWidget::AddOption(std::string const & option )
{
  this->Options.push_back(option);
}

void cmCursesOptionsWidget::NextOption()
{
  this->CurrentOption++;
  if(this->CurrentOption > this->Options.size()-1)
    {
    this->CurrentOption = 0;
    }
  this->SetValue(this->Options[this->CurrentOption].c_str());
}
void cmCursesOptionsWidget::PreviousOption()
{
  if(this->CurrentOption == 0)
    {
    this->CurrentOption = this->Options.size()-1;
    }
  else
    {
    this->CurrentOption--;
    }
  this->SetValue(this->Options[this->CurrentOption].c_str());
}

void cmCursesOptionsWidget::SetOption(const char* value)
{
  this->CurrentOption = 0; // default to 0 index
  this->SetValue(value);
  int index = 0;
  for(std::vector<std::string>::iterator i = this->Options.begin();
      i != this->Options.end(); ++i)
    {
    if(*i == value)
      {
      this->CurrentOption = index;
      }
    index++;
    }
}
