// 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 "unix/ibus/key_event_handler.h"

#include <map>

#include "base/logging.h"
#include "base/port.h"
#include "base/singleton.h"

namespace mozc {
namespace ibus {

namespace {
// TODO(hsumita): Removes this class, and moves |data_| into member
// variables of KeyEventhandler.
class AdditionalModifiersData {
 public:
  AdditionalModifiersData() {
    data_[commands::KeyEvent::LEFT_ALT] = commands::KeyEvent::ALT;
    data_[commands::KeyEvent::RIGHT_ALT] = commands::KeyEvent::ALT;
    data_[commands::KeyEvent::LEFT_CTRL] = commands::KeyEvent::CTRL;
    data_[commands::KeyEvent::RIGHT_CTRL] = commands::KeyEvent::CTRL;
    data_[commands::KeyEvent::LEFT_SHIFT] = commands::KeyEvent::SHIFT;
    data_[commands::KeyEvent::RIGHT_SHIFT] = commands::KeyEvent::SHIFT;
  }
  const map<uint32, commands::KeyEvent::ModifierKey> &data() {
    return data_;
  }

 private:
  map<uint32, commands::KeyEvent::ModifierKey> data_;
};

// TODO(hsumita): Moves this function into member functions of
// KeyEventHandler.
void AddAdditionalModifiers(
    set<commands::KeyEvent::ModifierKey> *modifier_keys_set) {
  DCHECK(modifier_keys_set);

  const map<uint32, commands::KeyEvent::ModifierKey> &data =
      Singleton<AdditionalModifiersData>::get()->data();

  // Adds MODIFIER if there are (LEFT|RIGHT)_MODIFIER like LEFT_SHIFT.
  for (set<commands::KeyEvent::ModifierKey>::const_iterator it =
           modifier_keys_set->begin(); it != modifier_keys_set->end(); ++it) {
    map<uint32, commands::KeyEvent::ModifierKey>::const_iterator item =
        data.find(*it);
    if (item != data.end()) {
      modifier_keys_set->insert(item->second);
    }
  }
}

bool IsModifierToBeSentOnKeyUp(const commands::KeyEvent &key_event) {
  if (key_event.modifier_keys_size() == 0) {
    return false;
  }

  if (key_event.modifier_keys_size() == 1 &&
      key_event.modifier_keys(0) == commands::KeyEvent::CAPS) {
    return false;
  }

  return true;
}
}  // namespace

KeyEventHandler::KeyEventHandler() : key_translator_(new KeyTranslator) {
  Clear();
}

bool KeyEventHandler::GetKeyEvent(
    guint keyval, guint keycode, guint modifiers,
    config::Config::PreeditMethod preedit_method,
    bool layout_is_jp, commands::KeyEvent *key) {
  DCHECK(key);
  key->Clear();

  if (!key_translator_->Translate(
          keyval, keycode, modifiers, preedit_method, layout_is_jp, key)) {
    LOG(ERROR) << "Translate failed";
    return false;
  }

  const bool is_key_up = ((modifiers & IBUS_RELEASE_MASK) != 0);
  return ProcessModifiers(is_key_up, keyval, key);
}

void KeyEventHandler::Clear() {
  is_non_modifier_key_pressed_ = false;
  currently_pressed_modifiers_.clear();
  modifiers_to_be_sent_.clear();
}

bool KeyEventHandler::ProcessModifiers(bool is_key_up, guint keyval,
                                       commands::KeyEvent *key_event) {
  // Manage modifier key event.
  // Modifier key event is sent on key up if non-modifier key has not been
  // pressed since key down of modifier keys and no modifier keys are pressed
  // anymore.
  // Following examples are expected behaviors.
  //
  // E.g.) Shift key is special. If Shift + printable key is pressed, key event
  //       does NOT have shift modifiers. It is handled by KeyTranslator class.
  //    <Event from ibus> <Event to server>
  //     Shift down      | None
  //     "a" down        | A
  //     "a" up          | None
  //     Shift up        | None
  //
  // E.g.) Usual key is sent on key down.  Modifier keys are not sent if usual
  //       key is sent.
  //    <Event from ibus> <Event to server>
  //     Ctrl down       | None
  //     "a" down        | Ctrl+a
  //     "a" up          | None
  //     Ctrl up         | None
  //
  // E.g.) Modifier key is sent on key up.
  //    <Event from ibus> <Event to server>
  //     Shift down      | None
  //     Shift up        | Shift
  //
  // E.g.) Multiple modifier keys are sent on the last key up.
  //    <Event from ibus> <Event to server>
  //     Shift down      | None
  //     Control down    | None
  //     Shift up        | None
  //     Control up      | Control+Shift
  //
  // Essentialy we cannot handle modifier key evnet perfectly because
  // - We cannot get current keyboard status with ibus. If some modifiers
  //   are pressed or released without focusing the target window, we
  //   cannot handle it.
  // E.g.)
  //    <Event from ibus> <Event to server>
  //     Ctrl down       | None
  //     (focuses out, Ctrl up, focuses in)
  //     Shift down      | None
  //     Shift up        | None (But we should send Shift key)
  // To avoid a inconsistent state as much as possible, we clear states
  // when key event without modifier keys is sent.

  const bool is_modifier_only =
      !(key_event->has_key_code() || key_event->has_special_key());

  // We may get only up/down key event when a user moves a focus.
  // This code handles such situation as much as possible.
  // This code has a bug. If we send Shift + 'a', KeyTranslator removes a shift
  // modifier and converts 'a' to 'A'. This codes does NOT consider these
  // situation since we don't have enough data to handle it.
  // TODO(hsumita): Moves the logic about a handling of Shift or Caps keys from
  // KeyTranslator to MozcEngine.
  if (key_event->modifier_keys_size() == 0) {
    Clear();
  }

  if (!currently_pressed_modifiers_.empty() && !is_modifier_only) {
    is_non_modifier_key_pressed_ = true;
  }
  if (is_non_modifier_key_pressed_) {
    modifiers_to_be_sent_.clear();
  }

  if (is_key_up) {
    currently_pressed_modifiers_.erase(keyval);
    if (!is_modifier_only) {
      return false;
    }
    if (!currently_pressed_modifiers_.empty() ||
        modifiers_to_be_sent_.empty()) {
      is_non_modifier_key_pressed_ = false;
      return false;
    }
    if (is_non_modifier_key_pressed_) {
      return false;
    }
    DCHECK(!is_non_modifier_key_pressed_);

    // Modifier key event fires
    key_event->mutable_modifier_keys()->Clear();
    for (set<commands::KeyEvent::ModifierKey>::const_iterator it =
             modifiers_to_be_sent_.begin();
         it != modifiers_to_be_sent_.end();
         ++it) {
      key_event->add_modifier_keys(*it);
    }
    modifiers_to_be_sent_.clear();
  } else if (is_modifier_only) {
    // TODO(hsumita): Supports a key sequence below.
    // - Ctrl down
    // - a down
    // - Alt down
    // We should add Alt key to |currently_pressed_modifiers|, but current
    // implementation does NOT do it.
    if (currently_pressed_modifiers_.empty() ||
        !modifiers_to_be_sent_.empty()) {
      for (size_t i = 0; i < key_event->modifier_keys_size(); ++i) {
        modifiers_to_be_sent_.insert(key_event->modifier_keys(i));
      }
      AddAdditionalModifiers(&modifiers_to_be_sent_);
    }
    currently_pressed_modifiers_.insert(keyval);
    return false;
  }

  // Clear modifier data just in case if |key| has no modifier keys.
  if (!IsModifierToBeSentOnKeyUp(*key_event)) {
    Clear();
  }

  return true;
}

}  // namespace ibus
}  // namespace mozc
