// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/base/ime/input_method_auralinux.h"

#include "base/environment.h"
#include "ui/base/ime/linux/linux_input_method_context_factory.h"
#include "ui/base/ime/text_input_client.h"
#include "ui/events/event.h"

namespace ui {

InputMethodAuraLinux::InputMethodAuraLinux(
    internal::InputMethodDelegate* delegate)
    : allowed_to_fire_vkey_process_key_(false), vkey_processkey_flags_(0) {
  SetDelegate(delegate);
}

InputMethodAuraLinux::~InputMethodAuraLinux() {}

// Overriden from InputMethod.

void InputMethodAuraLinux::Init(bool focused) {
  CHECK(LinuxInputMethodContextFactory::instance())
      << "This failure was likely caused because "
      << "ui::InitializeInputMethod(ForTesting) was not called "
      << "before instantiating this class.";
  input_method_context_ =
      LinuxInputMethodContextFactory::instance()->CreateInputMethodContext(
          this);
  CHECK(input_method_context_.get());

  InputMethodBase::Init(focused);

  if (focused) {
    input_method_context_->OnTextInputTypeChanged(
        GetTextInputClient() ?
        GetTextInputClient()->GetTextInputType() :
        TEXT_INPUT_TYPE_TEXT);
  }
}

bool InputMethodAuraLinux::OnUntranslatedIMEMessage(
    const base::NativeEvent& event,
    NativeEventResult* result) {
  return false;
}

bool InputMethodAuraLinux::DispatchKeyEvent(const ui::KeyEvent& event) {
  DCHECK(event.type() == ET_KEY_PRESSED || event.type() == ET_KEY_RELEASED);
  DCHECK(system_toplevel_window_focused());

  // If no text input client, do nothing.
  if (!GetTextInputClient())
    return DispatchKeyEventPostIME(event);

  // Let an IME handle the key event first, and allow to fire a VKEY_PROCESSKEY
  // event for keydown events.  Note that DOM Level 3 Events Sepc requires that
  // only keydown events fire keyCode=229 events and not for keyup events.
  if (event.type() == ET_KEY_PRESSED &&
      (event.flags() & ui::EF_IME_FABRICATED_KEY) == 0)
    AllowToFireProcessKey(event);
  if (input_method_context_->DispatchKeyEvent(event))
    return true;
  StopFiringProcessKey();

  // Otherwise, insert the character.
  const bool handled = DispatchKeyEventPostIME(event);
  if (event.type() == ET_KEY_PRESSED && GetTextInputClient()) {
    const uint16 ch = event.GetCharacter();
    if (ch) {
      GetTextInputClient()->InsertChar(ch, event.flags());
      return true;
    }
  }
  return handled;
}

void InputMethodAuraLinux::OnTextInputTypeChanged(
    const TextInputClient* client) {
  if (!IsTextInputClientFocused(client))
    return;
  input_method_context_->Reset();
  // TODO(yoichio): Support inputmode HTML attribute.
  input_method_context_->OnTextInputTypeChanged(client->GetTextInputType());
}

void InputMethodAuraLinux::OnCaretBoundsChanged(const TextInputClient* client) {
  if (!IsTextInputClientFocused(client))
    return;
  input_method_context_->OnCaretBoundsChanged(
      GetTextInputClient()->GetCaretBounds());
}

void InputMethodAuraLinux::CancelComposition(const TextInputClient* client) {
  if (!IsTextInputClientFocused(client))
    return;
  input_method_context_->Reset();
  input_method_context_->OnTextInputTypeChanged(client->GetTextInputType());
}

void InputMethodAuraLinux::OnInputLocaleChanged() {
}

std::string InputMethodAuraLinux::GetInputLocale() {
  return "";
}

bool InputMethodAuraLinux::IsActive() {
  // InputMethodAuraLinux is always ready and up.
  return true;
}

bool InputMethodAuraLinux::IsCandidatePopupOpen() const {
  // There seems no way to detect candidate windows or any popups.
  return false;
}

// Overriden from ui::LinuxInputMethodContextDelegate

void InputMethodAuraLinux::OnCommit(const base::string16& text) {
  MaybeFireProcessKey();
  if (!IsTextInputTypeNone())
    GetTextInputClient()->InsertText(text);
}

void InputMethodAuraLinux::OnPreeditChanged(
    const CompositionText& composition_text) {
  MaybeFireProcessKey();
  TextInputClient* text_input_client = GetTextInputClient();
  if (text_input_client)
    text_input_client->SetCompositionText(composition_text);
}

void InputMethodAuraLinux::OnPreeditEnd() {
  MaybeFireProcessKey();
  TextInputClient* text_input_client = GetTextInputClient();
  if (text_input_client && text_input_client->HasCompositionText())
    text_input_client->ClearCompositionText();
}

void InputMethodAuraLinux::OnPreeditStart() {
  MaybeFireProcessKey();
}

// Overridden from InputMethodBase.

void InputMethodAuraLinux::OnDidChangeFocusedClient(
    TextInputClient* focused_before,
    TextInputClient* focused) {
  input_method_context_->Reset();
  input_method_context_->OnTextInputTypeChanged(
      focused ? focused->GetTextInputType() : TEXT_INPUT_TYPE_NONE);

  InputMethodBase::OnDidChangeFocusedClient(focused_before, focused);
}

// Helper functions to support VKEY_PROCESSKEY.

void InputMethodAuraLinux::AllowToFireProcessKey(const ui::KeyEvent& event) {
  allowed_to_fire_vkey_process_key_ = true;
  vkey_processkey_flags_ = event.flags();
}

void InputMethodAuraLinux::MaybeFireProcessKey() {
  if (!allowed_to_fire_vkey_process_key_)
    return;

  const ui::KeyEvent fabricated_event(ET_KEY_PRESSED,
                                      VKEY_PROCESSKEY,
                                      vkey_processkey_flags_);
  DispatchKeyEventPostIME(fabricated_event);
  StopFiringProcessKey();
}

void InputMethodAuraLinux::StopFiringProcessKey() {
  allowed_to_fire_vkey_process_key_ = false;
  vkey_processkey_flags_ = 0;
}

}  // namespace ui
