// Copyright (c) 2019 Giorgos Vougioukas
//
// The license can be found in the LICENSE file.

#include "euterpe/editor.h"
#include "euterpe/definitions.h"

#include "WDL/wdlstring.h"

#define RSE_CTRL_KEY_DOWN (GetAsyncKeyState(VK_CONTROL)&0x8000)
#define RSE_SHIFT_KEY_DOWN (GetAsyncKeyState(VK_SHIFT)&0x8000)
#define RSE_ALT_KEY_DOWN (GetAsyncKeyState(VK_MENU)&0x8000)

RSE_PreviewEditor::RSE_PreviewEditor(void *curses_ctx)
  : WDL_CursesEditor(curses_ctx)
{
  m_indent_size = 2;

  /*
  init_pair(1, COLOR_WHITE, COLOR_BLUE);     // COLOR_BOTTOMLINE
  init_pair(2, COLOR_BLACK, COLOR_CYAN);     // COLOR_SELECTION
  init_pair(3, RGB(0,255,255),COLOR_BLACK);  // SYNTAX_HIGHLIGHT1
  init_pair(4, RGB(0,255,0),COLOR_BLACK);    // SYNTAX_HIGHLIGHT2
  init_pair(5, RGB(96,128,192),COLOR_BLACK); // SYNTAX_COMMENT
  init_pair(6, COLOR_WHITE, COLOR_RED);      // SYNTAX_ERROR
  init_pair(7, RGB(255,255,0), COLOR_BLACK); // SYNTAX_FUNC
  init_pair(8, RGB(255,128,128), COLOR_BLACK);  // SYNTAX_REGVAR
  init_pair(9, RGB(0,192,255), COLOR_BLACK);    // SYNTAX_KEYWORD
  init_pair(10, RGB(255,192,192), COLOR_BLACK); // SYNTAX_STRING
  init_pair(11, RGB(192,255,128), COLOR_BLACK); // SYNTAX_STRINGVAR
  init_pair(12, COLOR_BLACK, COLOR_CYAN);       // COLOR_MESSAGE (maps to COLOR_SELECTION)
  init_pair(13, COLOR_WHITE, COLOR_RED);        // COLOR_TOPLINE (maps to SYNTAX_ERROR)
  init_pair(14, RGB(192,192,0), COLOR_BLACK);   // SYNTAX_FUNC2
  */
}

RSE_PreviewEditor::~RSE_PreviewEditor()
{}

void RSE_PreviewEditor::SetParent(HWND parent)
{
  m_parent = parent;
}

void RSE_PreviewEditor::ClearText()
{
  m_curs_x = 0;
  m_curs_y = 0;
  m_text.Empty(true);
  m_undoStack.Empty(true);
}

int RSE_PreviewEditor::onChar(int c)
{
  if (m_ui_state == UI_STATE_SEARCH)
  {
    return WDL_CursesEditor::onChar(c);
  }

  if (c == '\t')
  {
    if (RSE_CTRL_KEY_DOWN)
    {
      SendMessage(m_parent, WM_TOGGLE_FOCUS, 2, 0);
      return 0;
    }
  }

  if (c == 'G' - 'A' + 1)
  {
    if (RSE_CTRL_KEY_DOWN) return WDL_CursesEditor::onChar(c);
  }

  if (c == 'P' - 'A' + 1)
  {
    if (RSE_CTRL_KEY_DOWN) return WDL_CursesEditor::onChar(c);
  }

  if (c == 'O' - 'A' + 1)
  {
    if (RSE_CTRL_KEY_DOWN) return WDL_CursesEditor::onChar(c);
  }

  if (c == 'W' - 'A' + 1)
  {
    if (RSE_CTRL_KEY_DOWN) { DestroyWindow(m_parent); return 0; }
  }

  if (c == 'F' - 'A' + 1)
  {
    if (RSE_CTRL_KEY_DOWN) return WDL_CursesEditor::onChar(c);
  }

  if (c == 'C' - 'A' + 1)
  {
    if (RSE_CTRL_KEY_DOWN) return WDL_CursesEditor::onChar(c);
  }

  if (c == 27)
  {
    DestroyWindow(m_parent);
    return 0;
  }

  if (c == KEY_DOWN || c == KEY_UP || c == KEY_PPAGE || c == KEY_NPAGE ||
    c == KEY_RIGHT || c == KEY_LEFT || c == KEY_HOME || c == KEY_END ||
    c == KEY_F1 || c == KEY_F2 || c == KEY_F3 || c == KEY_F4 || c == KEY_F5 ||
    c == KEY_F6 || c == KEY_F7 || c == KEY_F8 || c == KEY_F9 || c == KEY_F10 ||
    c == KEY_F11 || c == KEY_F12)
  {
    return WDL_CursesEditor::onChar(c);
  }

  return 0;
}

#if 0
RSE_SimpleEditor::RSE_SimpleEditor(void *curses_ctx)
  : WDL_CursesEditor(curses_ctx)
{
  m_indent_size = 2;
}

RSE_SimpleEditor::~RSE_SimpleEditor()
{}

void RSE_SimpleEditor::SetParent(HWND parent)
{
  m_parent = parent;
}

void RSE_SimpleEditor::ClearText()
{
  m_curs_x = 0;
  m_curs_y = 0;
  m_text.Empty(true);
  m_undoStack.Empty(true);
}

int RSE_SimpleEditor::onChar(int c)
{
  if (c == '\t')
  {
    if (RSE_CTRL_KEY_DOWN)
    {
      SendMessage(m_parent, WM_TOGGLE_FOCUS, 1, 0);
      return 0;
    }
  }

  if (c == 'W' - 'A' + 1)
  {
    if (RSE_CTRL_KEY_DOWN)
    {
      DestroyWindow(m_parent);
      return 0;
    }
  }

  if (c == 'S' - 'A' + 1)
  {
    if (RSE_CTRL_KEY_DOWN)
    {
      int len = 0;

      for (int i = 0; i < m_text.GetSize(); i++)
      {
        len += m_text.Get(i)->GetLength();
      }

      WDL_String prefs("", len);

      for (int i = 0; i < m_text.GetSize(); i++)
      {
        prefs.Append(m_text.Get(i)->Get());
      }

      cJSON_Minify(prefs.Get());

      cJSON *root = cJSON_Parse(prefs.Get());

      if (root == NULL)
      {
        draw_message("Parse error");
      }
      else
      {
        WDL_FileWrite out(GetFileName());

        if (out.IsOpen())
        {
          for (int i = 0; i < m_text.GetSize(); i++)
          {
            out.Write(m_text.Get(i)->Get(),
                      m_text.Get(i)->GetLength());

            if (i < m_text.GetSize() - 1)
            {
              out.Write("\n", 1);
            }
          }

          g_conf.LoadDefaultSettings();
          g_conf.LoadUserSettings();

          draw_message("Parsed successfully and saved");
        }
        else
        {
          draw_message("Cannot open file for writing");
        }
      }

      cJSON_Delete(root);

      return 0;
    }
  }

  return WDL_CursesEditor::onChar(c);
}

void RSE_SimpleEditor::draw_bottom_line()
{
#define BOLD(x) { attrset(COLOR_BOTTOMLINE|A_BOLD); addstr(x); attrset(COLOR_BOTTOMLINE&~A_BOLD); }
  BOLD("S");
  addstr("ave");
#undef BOLD
}
#endif
