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

#include "RSI/editor.h"
#include "RSI/definitions.h"
#include "RSI/preferences.h"
#include "RSI/track.h"
#include "RSI/main_wnd.h"

#include "third_party/cJSON/cJSON.h"

#include "WDL/wdlstring.h"
#include "WDL/filewrite.h"

#define RSI_CTRL_KEY_DOWN (GetAsyncKeyState(VK_CONTROL)&0x8000)
#define RSI_SHIFT_KEY_DOWN (GetAsyncKeyState(VK_SHIFT)&0x8000)
#define RSI_ALT_KEY_DOWN (GetAsyncKeyState(VK_MENU)&0x8000)

RSI_PreviewEditor::RSI_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
  */
}

RSI_PreviewEditor::~RSI_PreviewEditor()
{}

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

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

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

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

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

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

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

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

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

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

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

  if (c == 27)
  {
    return WDL_CursesEditor::onChar(c);
  }

  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;
}

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

RSI_PreferencesEditor::~RSI_PreferencesEditor()
{}

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

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

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

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

  if (c == 'S' - 'A' + 1)
  {
    if (RSI_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.AppendFormatted(1024, "%s\n", m_text.Get(i)->Get());
      }

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

      if (!root)
      {
        WDL_FastString err;

        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr)
        {
          err.SetFormatted(2048, "Parse error before: %s\n", error_ptr);
        }

        draw_message(err.Get());
      }
      else
      {
        updateFile();
        draw_message("Parsed and saved successfully");
      }

      cJSON_Delete(root);

      return 0;
    }
  }

  if (c == KEY_F12)
  {
    if (RSI_CTRL_KEY_DOWN)
    {
      bool active = false;

      for (int i = 0; i < g_tracks.GetSize(); i++)
      {
        RSI_Track *trk = g_tracks.Enumerate(i);
        if (trk)
        {
          if (trk->IsActive()) { active = true; break; }
        }
      }

      if (active && g_preferences->AskExit())
      {
        int res = MessageBox(g_mainwnd->Handle(), "Playback is active. Do you really want to Exit?", "Ask Exit", MB_YESNO);
        if (res == IDYES) { g_preferences->SetRelaunch(true); DestroyWindow(g_mainwnd->Handle()); }
      }
      else
      {
        g_preferences->SetRelaunch(true);
        DestroyWindow(g_mainwnd->Handle());
      }
    }
  }

  if (c == 27)
  {
    return WDL_CursesEditor::onChar(c);
  }

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

  return WDL_CursesEditor::onChar(c);
}

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

  BOLD(" F12");
  addstr(":relaunch");
#undef BOLD
}
