#include "stdafx.h"

#include "xtr/ui/KeyboardHandler.h"

#include "resource.h"

#include "xtr/Exteor.h"

namespace xtr::ui {

Keyboard::Keyboard() {
  russianHKL =    /*(HKL)0x0419;*/  LoadKeyboardLayoutW(L"00000419", 0);
  englishHKL =    /*(HKL)0x0409;*/  LoadKeyboardLayoutW(L"00000409", 0);
}

Keyboard& Keyboard::Instance() {
  static Keyboard instance{};
  return instance;
}

void Keyboard::SetLayout(const Layout newLang) {
  if (XTROptions::App().disableAutoKeyboard &&
      (currentLayout == Layout::RUS || newLang == Layout::RUS)) {
    return;
  }

  if (currentLayout != newLang) {
    SetInternalLayout(newLang);
  }
  if (newLang == Layout::RUS) {
    SetSystemLayout(russianHKL);
  } else {
    SetSystemLayout(englishHKL);
  }
}

void Keyboard::ResetSystemLayout() {
  systemLayout = GetKeybLang();
  SetSystemLayout(currentLayout != Layout::RUS ? englishHKL : russianHKL);
  UpdateIndicators();
}

Keyboard::Layout Keyboard::GetLayout() const noexcept {
  return currentLayout;
}

void Keyboard::RotateLayout() {
  if (!XTROptions::App().disableAutoKeyboard) {
    switch (currentLayout) {
    case Layout::RUS: SetLayout(Layout::MATH); break;
    case Layout::ENG: SetLayout(Layout::RUS); break;
    case Layout::MATH: SetLayout(Layout::ENG); break;
    }
  } else {
    ImportSystemLayout();
    switch (currentLayout) {
    case Layout::RUS: break;
    case Layout::ENG: SetLayout(Layout::MATH); break;
    case Layout::MATH: SetLayout(Layout::ENG); break;
    }
  }
}

void Keyboard::RegisterIndicator(CWnd* wnd) {
  indicators.insert(wnd);
  UpdateIndicators();
}

void Keyboard::UnregisterIndicator(CWnd* wnd) {
  indicators.erase(wnd);
}

void Keyboard::ImportSystemLayout() {
  const auto currentSystemLayout = GetKeybLang();
  auto exteorLayout = currentLayout;
  if (exteorLayout == Layout::MATH) {
    exteorLayout = Layout::ENG;
  }
  if (currentSystemLayout != exteorLayout) {
    SetInternalLayout(currentSystemLayout);
  }
}

void Keyboard::UpdateIndicators() {
  CString indicatorText;
  switch(currentLayout) {
  case Layout::MATH: indicatorText = mfc::LoadSID(IXTRC_INDICATOR_GOTHIC);  break;
  case Layout::RUS:  indicatorText = mfc::LoadSID(IXTRC_INDICATOR_RUSSIAN); break;
  case Layout::ENG:  indicatorText = mfc::LoadSID(IXTRC_INDICATOR_ENGLISH); break;
  }

  ExteorApplication::MainFrame().SetLangStatusText(indicatorText);
  for (const auto& wnd : indicators) {
    if (wnd->m_hWnd != nullptr) {
      wnd->SetWindowTextW(indicatorText);
    }
  }
}

Keyboard::Layout Keyboard::GetKeybLang() {
  CString sLayout{};
  GetKeyboardLayoutNameW(sLayout.GetBuffer(KL_NAMELENGTH + 1));
  sLayout.ReleaseBuffer();
  if (sLayout == L"00000419") {
    return Keyboard::Layout::RUS;
  } else {
    return Keyboard::Layout::ENG;
  }
}

void Keyboard::SetSystemLayout(HKL newLayout) noexcept {
  if (!XTROptions::App().disableAutoKeyboard) {
    ActivateKeyboardLayout(newLayout, KLF_REORDER);
  }
}

void Keyboard::SetInternalLayout(const Layout newLang) {
  currentLayout = newLang;
  UpdateIndicators();
}

} // namespace xtr::ui