// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "gui/config_dialog/keybinding_editor.h"

#ifdef OS_WIN
#include <windows.h>
#include <imm.h>
#include <ime.h>
#elif OS_LINUX
#define XK_MISCELLANY
#include <X11/keysymdef.h>
#endif

#include <QtCore/QString>
#include <QtGui/QMessageBox>

#include "base/logging.h"
#include "base/util.h"

namespace mozc {
namespace gui {

namespace {
struct QtKeyEntry {
  Qt::Key qt_key;
  const char *mozc_key_name;
};

// TODO(taku): check it these mappings are correct.
const QtKeyEntry kQtKeyModifierNonRequiredTable[] = {
  { Qt::Key_Escape, "Escape" },
  { Qt::Key_Tab, "Tab" },
  { Qt::Key_Backtab, "Tab" },   // Qt handles Tab + Shift as a special key
  { Qt::Key_Backspace, "Backspace" },
  { Qt::Key_Return, "Enter" },
  { Qt::Key_Enter, "Enter" },
  { Qt::Key_Insert, "Insert" },
  { Qt::Key_Delete, "Delete" },
  { Qt::Key_Home, "Home" },
  { Qt::Key_End, "End" },
  { Qt::Key_Left, "Left" },
  { Qt::Key_Up, "Up" },
  { Qt::Key_Right, "Right" },
  { Qt::Key_Down, "Down" },
  { Qt::Key_PageUp, "PageUp" },
  { Qt::Key_PageDown, "PageDown" },
  { Qt::Key_Space, "Space" },
  { Qt::Key_F1, "F1" },
  { Qt::Key_F2, "F2" },
  { Qt::Key_F3, "F3" },
  { Qt::Key_F4, "F4" },
  { Qt::Key_F5, "F5" },
  { Qt::Key_F6, "F6" },
  { Qt::Key_F7, "F7" },
  { Qt::Key_F8, "F8" },
  { Qt::Key_F9, "F9" },
  { Qt::Key_F10, "F10" },
  { Qt::Key_F11, "F11" },
  { Qt::Key_F12, "F12" },
  { Qt::Key_F13, "F13" },
  { Qt::Key_F14, "F14" },
  { Qt::Key_F15, "F15" },
  { Qt::Key_F16, "F16" },
  { Qt::Key_F17, "F17" },
  { Qt::Key_F18, "F18" },
  { Qt::Key_F19, "F19" },
  { Qt::Key_F20, "F20" },
  { Qt::Key_F21, "F21" },
  { Qt::Key_F22, "F22" },
  { Qt::Key_F23, "F23" },
  { Qt::Key_F24, "F24" }
};

#ifdef OS_WIN
struct WinVirtualKeyEntry {
  DWORD virtual_key;
  const char *mozc_key_name;
};

const WinVirtualKeyEntry kWinVirtualKeyModifierNonRequiredTable[] = {
  //  { VK_DBE_HIRAGANA, "Kana" },       // Kana
  // "Hiragana" and "Kana" are the same key on Mozc
  { VK_DBE_HIRAGANA, "Hiragana" },       // Hiragana
  { VK_DBE_KATAKANA, "Katakana" },        // Ktakana
  { VK_DBE_ALPHANUMERIC, "Eisu" },   // Eisu
  // TODO(taku): better to support Romaji key
  // { VK_DBE_ROMAN, "Romaji" },           // Romaji
  // { VK_DBE_NOROMAN, "Romaji" },         // Romaji
  { VK_NONCONVERT, "Muhenkan" },     // Muhenkan
  { VK_CONVERT, "Henkan" },           // Henkan
  // JP109's Hankaku/Zenkaku key has two V_KEY for toggling IME-On and Off.
  // Althogh these are visible keys on 109JP, Mozc doesn't support them.
  { VK_DBE_SBCSCHAR, "Hankaku/Zenkaku" },        // Zenkaku/hankaku
  { VK_DBE_DBCSCHAR, "Hankaku/Zenkaku" },        // Zenkaku/hankaku
  // { VK_KANJI, "Kanji" },  // Do not support Kanji
};
#elif OS_LINUX
struct LinuxVirtualKeyEntry {
  uint16 virtual_key;
  const char *mozc_key_name;
};

const LinuxVirtualKeyEntry kLinuxVirtualKeyModifierNonRequiredTable[] = {
  { XK_Muhenkan, "Muhenkan" },
  { XK_Henkan, "Henkan" },
  { XK_Hiragana, "Hiragana" },
  { XK_Katakana, "Katakana" },
  // We need special hack for Hiragana_Katakana key. For the detail, please see
  // KeyBindingFilter::AddKey implementation.
  { XK_Hiragana_Katakana, "Hiragana" },
  { XK_Eisu_toggle, "Eisu" },
  { XK_Zenkaku_Hankaku, "Hankaku/Zenkaku" },
};
#endif

// On Windows Hiragana/Eisu keys only emits KEY_DOWN event.
// for these keys we don't hanlde auto-key repeat.
bool IsDownOnlyKey(const QKeyEvent &key_event) {
#ifdef OS_WIN
  const DWORD virtual_key = key_event.nativeVirtualKey();
  return (virtual_key == VK_DBE_ALPHANUMERIC ||
          virtual_key == VK_DBE_HIRAGANA ||
          virtual_key == VK_DBE_KATAKANA);
#else
  return false;
#endif  // OS_WIN
}

bool IsAlphabet(const char key) {
  return (key >= 'a' && key <= 'z');
}
}  // namespace

class KeyBindingFilter : public QObject {
 public:
  KeyBindingFilter(QLineEdit *line_edit, QPushButton *ok_button);
  virtual ~KeyBindingFilter();

  enum KeyState {
    DENY_KEY,
    ACCEPT_KEY,
    SUBMIT_KEY
  };

 protected:
  bool eventFilter(QObject *obj, QEvent *event);

 private:
  void Reset();

  // add new "qt_key" to the filter.
  // return true if the current key_bindings the KeyBindingFilter holds
  // is valid. Composed key_bindings are stored to "result"
  KeyState AddKey(const QKeyEvent &key_event, QString *result);

  // encode the current key binding
  KeyState Encode(QString *result) const;

  bool committed_;
  bool ctrl_pressed_;
  bool alt_pressed_;
  bool shift_pressed_;
  QString modifier_required_key_;
  QString modifier_non_required_key_;
  QString unknown_key_;
  QLineEdit *line_edit_;
  QPushButton *ok_button_;
};

KeyBindingFilter::KeyBindingFilter(QLineEdit *line_edit,
                                   QPushButton *ok_button)
    : committed_(false),
      ctrl_pressed_(false),
      alt_pressed_(false),
      shift_pressed_(false),
      line_edit_(line_edit),
      ok_button_(ok_button) {
  Reset();
}

KeyBindingFilter::~KeyBindingFilter() {}

void KeyBindingFilter::Reset() {
  ctrl_pressed_ = false;
  alt_pressed_ = false;
  shift_pressed_ = false;
  modifier_required_key_.clear();
  modifier_non_required_key_.clear();
  unknown_key_.clear();
  committed_ = true;
  ok_button_->setEnabled(false);
}

KeyBindingFilter::KeyState KeyBindingFilter::Encode(QString *result) const {
  CHECK(result);

  // We don't accept any modifier keys for Hiragana, Eisu, Hankaku/Zenkaku keys.
  // On Windows, KEY_UP event is not raised for Hiragana/Eisu keys
  // until alternative keys (e.g., Eisu for Hiragana and Hiragana for Eisu)
  // are pressed. If Hiragana/Eisu key is pressed, we assume that
  // the key is already released at the same time.
  // Hankaku/Zenkaku key is preserved key and modifier keys are ignored.
  if (modifier_non_required_key_ == "Hiragana" ||
      modifier_non_required_key_ == "Katakana" ||
      modifier_non_required_key_ == "Eisu" ||
      modifier_non_required_key_ == "Hankaku/Zenkaku") {
    *result = modifier_non_required_key_;
    return KeyBindingFilter::SUBMIT_KEY;
  }

  QStringList results;

  if (ctrl_pressed_) {
    results << "Ctrl";
  }

  if (shift_pressed_) {
    results << "Shift";
  }

  if (alt_pressed_) {
#ifdef OS_MACOSX
    results << "Option";
#else
    // Do not support and show keybindings with alt for Windows
    // results << "Alt";
#endif
  }

  const bool has_modifier = !results.isEmpty();

  if (!modifier_non_required_key_.isEmpty()) {
    results << modifier_non_required_key_;
  }

  if (!modifier_required_key_.isEmpty()) {
    results << modifier_required_key_;
  }

  // in release binary, unknown_key_ is hidden
#ifndef NO_LOGGING
  if (!unknown_key_.isEmpty()) {
    results << unknown_key_;
  }
#endif

  KeyBindingFilter::KeyState result_state = KeyBindingFilter::ACCEPT_KEY;

  if (!unknown_key_.isEmpty()) {
    result_state = KeyBindingFilter::DENY_KEY;
  }

  const char key = modifier_required_key_.isEmpty() ?
      0 : modifier_required_key_[0].toAscii();

  // Alt or Ctrl or these combinations
  if ((alt_pressed_ || ctrl_pressed_) &&
      modifier_non_required_key_.isEmpty() &&
      modifier_required_key_.isEmpty()) {
    result_state = KeyBindingFilter::DENY_KEY;
  }

  // TODO(taku) Shift + 3 ("#" on US-keyboard) is also valid
  // keys, but we disable it for now, since we have no way
  // to get the original key "3" from "#" only with Qt layer.
  // need to see platform dependent scan code here.

  // Don't support Shift only
  // Shift in composition is set to EDIT_INSERT by default.
  // Now we do not make the keybindings for EDIT_INSERT configurable.
  // For avoiding complexity, we do not support Shift here.
  if (shift_pressed_ && !ctrl_pressed_ && !alt_pressed_ &&
      modifier_required_key_.isEmpty() &&
      modifier_non_required_key_.isEmpty()) {
    result_state = KeyBindingFilter::DENY_KEY;
  }

  // Don't support Shift + 'a' only
  if (shift_pressed_ && !ctrl_pressed_ && !alt_pressed_ &&
      !modifier_required_key_.isEmpty() && IsAlphabet(key)) {
    result_state = KeyBindingFilter::DENY_KEY;
  }

  // Don't support Shift + Ctrl + '@'
  if (shift_pressed_ && !modifier_required_key_.isEmpty() &&
      !IsAlphabet(key)) {
    result_state = KeyBindingFilter::DENY_KEY;
  }

  // no modifer for modifier_required_key
  if (!has_modifier && !modifier_required_key_.isEmpty()) {
    result_state = KeyBindingFilter::DENY_KEY;
  }

  // modifier_required_key and modifier_non_required_key
  // cannot co-exist
  if (!modifier_required_key_.isEmpty() &&
      !modifier_non_required_key_.isEmpty()) {
    result_state = KeyBindingFilter::DENY_KEY;
  }

  // no valid key
  if (results.empty()) {
    result_state = KeyBindingFilter::DENY_KEY;
  }

  *result = results.join(" ");

  return result_state;
}

KeyBindingFilter::KeyState KeyBindingFilter::AddKey(
    const QKeyEvent &key_event, QString *result) {
  CHECK(result);
  result->clear();

  const int qt_key = key_event.key();

  // modifier keys
  switch (qt_key) {
#ifdef OS_MACOSX
    case Qt::Key_Meta:
      ctrl_pressed_ = true;
      return Encode(result);
    case Qt::Key_Alt:   // Option key
     //    case Qt::Key_Control:  Command key
      alt_pressed_ = true;
      return Encode(result);
#else
    case Qt::Key_Control:
      ctrl_pressed_ = true;
      return Encode(result);
      //    case Qt::Key_Meta:  // Windows key
    case Qt::Key_Alt:
      alt_pressed_ = true;
      return Encode(result);
#endif
    case Qt::Key_Shift:
      shift_pressed_ = true;
      return Encode(result);
    default:
      break;
  }

  // non-printable command, which doesn't require modifier keys
  for (size_t i = 0; i < arraysize(kQtKeyModifierNonRequiredTable); ++i) {
    if (kQtKeyModifierNonRequiredTable[i].qt_key == qt_key) {
      modifier_non_required_key_ =
          kQtKeyModifierNonRequiredTable[i].mozc_key_name;
      return Encode(result);
    }
  }

#ifdef OS_WIN
  // Handle JP109's Muhenkan/Henkan/katakana-hiragana and Zenkaku/Hankaku
  const DWORD virtual_key = key_event.nativeVirtualKey();
  for (size_t i = 0; i < arraysize(kWinVirtualKeyModifierNonRequiredTable);
       ++i) {
    if (kWinVirtualKeyModifierNonRequiredTable[i].virtual_key ==
        virtual_key) {
      modifier_non_required_key_ =
          kWinVirtualKeyModifierNonRequiredTable[i].mozc_key_name;
      return Encode(result);
    }
  }
#elif OS_LINUX
  const uint16 virtual_key = key_event.nativeVirtualKey();

  // The XKB defines three types of logical key code: "xkb::Hiragana",
  // "xkb::Katakana" and "xkb::Hiragana_Katakana".
  // On most of Linux distributions, any key event against physical
  // "ひらがな/カタカナ" key is likely to be mapped into
  // "xkb::Hiragana_Katakana" regardless of the state of shift modifier. This
  // means that you are likely to receive "Shift + xkb::Hiragana_Katakana"
  // rather than "xkb::Katakana" when you physically press Shift +
  // "ひらがな/カタカナ".
  // On the other hand, Mozc protocol expects that Shift + "ひらがな/カタカナ"
  // key event is always interpret as "{special_key: KeyEvent::KATAKANA}"
  // without shift modifier. This is why we have the following special treatment
  // against "shift + XK_Hiragana_Katakana". See b/6087341 for the background
  // information.
  // We use |key_event.modifiers()| instead of |shift_pressed_| because
  // |shift_pressed_| is no longer valid in the following scenario.
  //   1. Press "Shift"
  //   2. Press "Hiragana/Katakana"  (shift_pressed_ == true)
  //   3. Press "Hiragana/Katakana"  (shift_pressed_ == false)
  const bool with_shift = (key_event.modifiers() & Qt::ShiftModifier) != 0;
  if (with_shift && (virtual_key == XK_Hiragana_Katakana)) {
    modifier_non_required_key_ = "Katakana";
    return Encode(result);
  }

  // Handle JP109's Muhenkan/Henkan/katakana-hiragana and Zenkaku/Hankaku
  for (size_t i = 0; i < arraysize(kLinuxVirtualKeyModifierNonRequiredTable);
       ++i) {
    if (kLinuxVirtualKeyModifierNonRequiredTable[i].virtual_key ==
        virtual_key) {
      modifier_non_required_key_ =
          kLinuxVirtualKeyModifierNonRequiredTable[i].mozc_key_name;
      return Encode(result);
    }
  }
#endif

  if (qt_key == Qt::Key_yen) {
    // Japanese Yen mark, treat it as backslash for compatibility
    modifier_non_required_key_ = "\\";
    return Encode(result);
  }

  // printable command, which requires modifier keys
  if ((qt_key >= 0x21 && qt_key <= 0x60) ||
      (qt_key >= 0x7B && qt_key <= 0x7E)) {
    if (qt_key >= 0x41 && qt_key <= 0x5A) {
      modifier_required_key_ = static_cast<char>(qt_key - 'A' + 'a');
    } else {
      modifier_required_key_ = static_cast<char>(qt_key);
    }
    return Encode(result);
  }

  unknown_key_.sprintf("<UNK:0x%x 0x%x 0x%x>",
                       key_event.key(),
                       key_event.nativeScanCode(),
                       key_event.nativeVirtualKey());

  return Encode(result);
}

bool KeyBindingFilter::eventFilter(QObject *obj, QEvent *event) {
  if ((event->type() == QEvent::KeyPress ||
       event->type() == QEvent::KeyRelease) &&
      !IsDownOnlyKey(*static_cast<QKeyEvent *>(event)) &&
      static_cast<QKeyEvent *>(event)->isAutoRepeat()) {
    // ignores auto key repeat. just eat the event
    return true;
  }

  // TODO(taku): the following sequence doesn't work as once
  // user relase any of keys, the statues goes to "submitted"
  // 1. Press Ctrl + a
  // 2. Release a, but keep pressing Ctrl
  // 3. Press b  (the result should be "Ctrl + b").

  if (event->type() == QEvent::KeyPress) {
    // when the state is committed, reset the internal key binding
    if (committed_) {
      Reset();
      line_edit_->clear();
    }
    committed_ = false;
    const QKeyEvent *key_event = static_cast<QKeyEvent *>(event);
    QString result;
    const KeyBindingFilter::KeyState state = AddKey(*key_event, &result);
    ok_button_->setEnabled(state != KeyBindingFilter::DENY_KEY);
    line_edit_->setText(result);
    line_edit_->setCursorPosition(0);
    line_edit_->setAttribute(Qt::WA_InputMethodEnabled, false);
    if (state == KeyBindingFilter::SUBMIT_KEY) {
      committed_ = true;
    }
    return true;
  } else if (event->type() == QEvent::KeyRelease) {
    // when any of key is released, change the state "committed";
    line_edit_->setCursorPosition(0);
    committed_ = true;
    return true;
  }

  return QObject::eventFilter(obj, event);
}

KeyBindingEditor::KeyBindingEditor(QWidget *parent, QWidget *trigger_parent)
    : QDialog(parent), trigger_parent_(trigger_parent) {
  setupUi(this);
#ifdef OS_LINUX
  // Workaround for the issue http://code.google.com/p/mozc/issues/detail?id=9
  // Seems that even after clicking the button for the keybinding dialog,
  // the edit is not raised. This might be a bug of setFocusProxy.
  setWindowFlags(Qt::WindowSystemMenuHint | Qt::Tool |
                 Qt::WindowStaysOnTopHint);
#else
  setWindowFlags(Qt::WindowSystemMenuHint | Qt::Tool);
#endif

  QPushButton *ok_button =
      KeyBindingEditorbuttonBox->button(QDialogButtonBox::Ok);
  CHECK(ok_button != NULL);

  filter_.reset(new KeyBindingFilter(KeyBindingLineEdit, ok_button));
  KeyBindingLineEdit->installEventFilter(filter_.get());

  // no right click
  KeyBindingLineEdit->setContextMenuPolicy(Qt::NoContextMenu);
  KeyBindingLineEdit->setMaxLength(32);
  KeyBindingLineEdit->setAttribute(Qt::WA_InputMethodEnabled, false);

#ifdef OS_WIN
  ::ImmAssociateContext(KeyBindingLineEdit->winId(), 0);
#endif

  QObject::connect(KeyBindingEditorbuttonBox,
                   SIGNAL(clicked(QAbstractButton *)),
                   this,
                   SLOT(Clicked(QAbstractButton *)));

  setFocusProxy(KeyBindingLineEdit);
}

KeyBindingEditor::~KeyBindingEditor() {}

void KeyBindingEditor::Clicked(QAbstractButton *button) {
  switch (KeyBindingEditorbuttonBox->buttonRole(button)) {
    case QDialogButtonBox::AcceptRole:
      QDialog::accept();
      break;
    default:
      QDialog::reject();
      break;
  }
}

const QString KeyBindingEditor::GetBinding() const {
  return KeyBindingLineEdit->text();
}

void KeyBindingEditor::SetBinding(const QString &binding) {
  KeyBindingLineEdit->setText(binding);
  KeyBindingLineEdit->setCursorPosition(0);
}
}  // namespace gui
}  // namespace mozc
