/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmCursesOptionsWidget.h"

#include "cmCursesColor.h"
#include "cmCursesWidget.h"
#include "cmStateTypes.h"

#define ctrl(z) ((z)&037)

cmCursesOptionsWidget::cmCursesOptionsWidget(int width, int height, int left,
                                             int top)
  : cmCursesWidget(width, height, left, top)
{
  this->Type = cmStateEnums::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.
  if (cmCursesColor::HasColors()) {
    set_field_fore(this->Field, COLOR_PAIR(cmCursesColor::Choice));
    set_field_back(this->Field, COLOR_PAIR(cmCursesColor::Choice));
  } else {
    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* /*fm*/,
                                        WINDOW* w)
{
  if (this->Options.empty()) {
    return false;
  }
  switch (key) {
    case 10: // 10 == enter
    case KEY_ENTER:
      this->NextOption();
      touchwin(w);
      wrefresh(w);
      return true;
    case KEY_LEFT:
    case ctrl('b'):
      touchwin(w);
      wrefresh(w);
      this->PreviousOption();
      return true;
    case KEY_RIGHT:
    case ctrl('f'):
      this->NextOption();
      touchwin(w);
      wrefresh(w);
      return true;
    default:
      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]);
}
void cmCursesOptionsWidget::PreviousOption()
{
  if (this->CurrentOption == 0) {
    this->CurrentOption = this->Options.size() - 1;
  } else {
    this->CurrentOption--;
  }
  this->SetValue(this->Options[this->CurrentOption]);
}

void cmCursesOptionsWidget::SetOption(const std::string& value)
{
  this->CurrentOption = 0; // default to 0 index
  this->SetValue(value);
  int index = 0;
  for (auto const& opt : this->Options) {
    if (opt == value) {
      this->CurrentOption = index;
    }
    index++;
  }
}
