// 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 "win32/ime/ime_composition_string.h"

#include <ime.h>
#include <strsafe.h>

#include "google/protobuf/stubs/common.h"
#include "base/logging.h"
#include "base/util.h"
#include "session/commands.pb.h"
#include "win32/base/immdev.h"
#include "win32/base/string_util.h"
#include "win32/ime/ime_message_queue.h"
#include "win32/ime/ime_scoped_context.h"

namespace mozc {
namespace win32 {
namespace {
const DWORD kPreeditUpdateFlags =
    (GCS_COMPREADSTR | GCS_COMPREADATTR | GCS_COMPREADCLAUSE | GCS_COMPSTR |
     GCS_COMPATTR | GCS_COMPCLAUSE | GCS_CURSORPOS | GCS_DELTASTART);
const DWORD kResultUpdateFlags =
    (GCS_RESULTREADSTR | GCS_RESULTREADCLAUSE | GCS_RESULTSTR |
     GCS_RESULTCLAUSE);
const DWORD kPreeditAndResultUpdateFlags =
    (kPreeditUpdateFlags | kResultUpdateFlags);
}  // anonymous namespace

bool CompositionString::Initialize() {
  ::ZeroMemory(this, sizeof(*this));
  info.dwSize = sizeof(CompositionString);

  // Composition string.
  info.dwCompStrOffset = offsetof(CompositionString, composition_);
  info.dwCompAttrOffset = offsetof(CompositionString, composition_attribute_);
  info.dwCompClauseOffset = offsetof(CompositionString, composition_clause_);

  // Composition reading string.
  info.dwCompReadStrOffset = offsetof(CompositionString, composition_reading_);
  info.dwCompReadAttrOffset =
      offsetof(CompositionString, composition_reading_attribute_);
  info.dwCompReadClauseOffset =
      offsetof(CompositionString, composition_reading_clause_);

  // Result.
  info.dwResultStrOffset = offsetof(CompositionString, result_);
  info.dwResultClauseOffset = offsetof(CompositionString, result_clause_);

  // Result reading.
  info.dwResultReadStrOffset = offsetof(CompositionString, result_reading_);
  info.dwResultReadClauseOffset =
      offsetof(CompositionString, result_reading_clause_);
  return true;
}

bool CompositionString::Update(
    const mozc::commands::Output &output, vector<UIMessage> *messages) {
  CompositionString prev_composition;
  ::CopyMemory(&prev_composition, this, sizeof(CompositionString));

  Initialize();

  DWORD update_flags = 0;
  if (!UpdateInternal(output, &update_flags)) {
    return false;
  }

  const bool is_oneshot_composition =
      (prev_composition.info.dwCompStrLen == 0) &&
      (info.dwCompStrLen == 0) &&
      (info.dwResultReadStrLen > 0);

  const bool prev_has_composition = (prev_composition.info.dwCompStrLen > 0);
  const bool has_composition = (info.dwCompStrLen > 0);

  // Check start composition.
  if (!prev_has_composition && (is_oneshot_composition || has_composition)) {
    messages->push_back(UIMessage(WM_IME_STARTCOMPOSITION, 0, 0));
  }

  {
    if (update_flags != 0) {
      // TODO(yukawa): support wparam of WM_IME_COMPOSITION.
      messages->push_back(UIMessage(WM_IME_COMPOSITION, 0, update_flags));
    }
  }

  // Check end composition.
  if ((prev_has_composition && !has_composition) || is_oneshot_composition) {
    // In OOo, we need this message to restore caret status.
    // We should not send this null-WM_IME_COMPOSITION when
    // |info.dwResultStrLen != 0|.  Otherwise, the result string will be
    // commited twice in wordpad.exe.
    if (info.dwResultStrLen == 0) {
      messages->push_back(UIMessage(WM_IME_COMPOSITION, 0, 0));
    }

    messages->push_back(UIMessage(WM_IME_ENDCOMPOSITION, 0, 0));
  }

  return true;
}

bool CompositionString::HandleResult(const mozc::commands::Output &output) {
  if (!output.has_result()) {
    return true;
  }

  HRESULT result = S_OK;

  wstring result_string;
  mozc::Util::UTF8ToWide(output.result().value(), &result_string);
  result = ::StringCchCopyN(result_,
                            arraysize(result_),
                            result_string.c_str(),
                            arraysize(result_));
  if (FAILED(result)) {
    return false;
  }
  info.dwResultStrLen = result_string.size();

  // Since the Mozc server does not support clause information for the
  // result string, we always declare the result string to be one segment.
  // TODO(yukawa): Set clause after b/3135804 is implemented.
  static_assert(arraysize(result_reading_clause_) >= 2,
                "|result_reading_clause_| must has at least 2 elements.");
  info.dwResultClauseLen = sizeof(result_clause_[0]) +
                           sizeof(result_clause_[1]);
  result_clause_[0] = 0;
  result_clause_[1] = info.dwResultStrLen;

  if (output.result().has_key()) {
    // Reading string should be stored as half-width katakana like
    // other major IMEs.  See b/1793283 for details.
    const wstring &reading_string =
        StringUtil::KeyToReading(output.result().key());
    result = ::StringCchCopyN(result_reading_,
                              arraysize(result_reading_),
                              reading_string.c_str(),
                              arraysize(result_reading_));
    if (FAILED(result)) {
      return false;
    }
    info.dwResultReadStrLen = reading_string.size();

    // Some applications such as Excel 2003 do not use the result string
    // unless clause information is also available. (b/2959222)
    // Since the Mozc server does not return clause information for the
    // result string, we always declare the result string to be one segment.
    // TODO(yukawa): Set clause after b/3135804 is implemented.
    static_assert(arraysize(result_reading_clause_) >= 2,
                  "|result_reading_clause_| must has at least 2 elements.");
    info.dwResultReadClauseLen = sizeof(result_reading_clause_[0]) +
                                 sizeof(result_reading_clause_[1]);
    result_reading_clause_[0] = 0;
    result_reading_clause_[1] = info.dwResultReadStrLen;
  }

  return true;
}

bool CompositionString::HandlePreedit(const mozc::commands::Output &output) {
  if (!output.has_preedit()) {
    return true;
  }

  const mozc::commands::Preedit &preedit = output.preedit();

  vector<BYTE> reading_attributes;
  vector<DWORD> reading_clauses;
  reading_clauses.push_back(0);

  vector<BYTE> composition_attributes;
  vector<DWORD> composition_clauses;
  composition_clauses.push_back(0);

  wstring reading_string;
  wstring composition_string;

  // As filed in b/2962397, we should use ATTR_CONVERTED as default
  // attribute when the preedit state is 'Convert' ("変換") or 'Prediction'
  // ("サジェスト選択中").  Fortunately, these states can be identified
  // with |has_highlighted_position()| for the moment.  This strategy also
  // satisfies the requirement of b/2955151.
  const BYTE default_attribute =
      (preedit.has_highlighted_position() ? ATTR_CONVERTED : ATTR_INPUT);

  string preedit_utf8;
  for (size_t segment_index = 0;
       segment_index < preedit.segment_size(); ++segment_index) {
    const mozc::commands::Preedit::Segment &segment =
        preedit.segment(segment_index);
    if (segment.has_key()) {
      // Reading string should be stored as half-width katakana like
      // other major IMEs.  See b/1793283 for details.
      const wstring &segment_reading =
          StringUtil::KeyToReading(segment.key());
      reading_string.append(segment_reading);
      for (size_t i = 0; i < segment_reading.size(); ++i) {
        switch (segment.annotation()) {
          case mozc::commands::Preedit::Segment::HIGHLIGHT:
            reading_attributes.push_back(ATTR_TARGET_CONVERTED);
            break;
          case mozc::commands::Preedit::Segment::UNDERLINE:
          case mozc::commands::Preedit::Segment::NONE:
          default:
            reading_attributes.push_back(default_attribute);
            break;
        }
      }
    }
    reading_clauses.push_back(reading_string.size());
    DCHECK(segment.has_value());
    {
      wstring segment_composition;
      mozc::Util::UTF8ToWide(segment.value(), &segment_composition);
      composition_string.append(segment_composition);
      preedit_utf8.append(segment.value());

      for (size_t i = 0; i < segment_composition.size(); ++i) {
        switch (segment.annotation()) {
          case mozc::commands::Preedit::Segment::HIGHLIGHT:
            composition_attributes.push_back(ATTR_TARGET_CONVERTED);
            break;
          case mozc::commands::Preedit::Segment::UNDERLINE:
          case mozc::commands::Preedit::Segment::NONE:
          default:
            composition_attributes.push_back(default_attribute);
            break;
        }
      }
    }
    composition_clauses.push_back(composition_string.size());
  }

  if (preedit.has_cursor()) {
    // |info.dwCursorPos| is supposed to be wide character index but
    // |preedit.cursor()| is the number of Unicode characters. In case
    // surrogate pair appears, use Util::WideCharsLen to calculate the
    // cursor position as wide character index. See b/4163234 for details.
    info.dwCursorPos = Util::WideCharsLen(
        Util::SubString(preedit_utf8, 0, preedit.cursor()));
  }

  if (preedit.has_highlighted_position()) {
    // Calculate the wide char index of the highlight segment so that
    // prediction/candidate windows are aligned to the highlight segment.
    // Note that |preedit.cursor()| is the number of Unicode characters.
    // In case surrogate pair appears, use Util::WideCharsLen to calculate
    // the highlighted position as wide character index.
    // See b/4163234 for details.
    const size_t highlighted_position_as_wchar_index = Util::WideCharsLen(
        Util::SubString(preedit_utf8, 0, preedit.highlighted_position()));

    focused_character_index_ = highlighted_position_as_wchar_index;

    // TODO(yukawa): do not update cursor pos here if target application
    //   suppors IMECHARPOSITION protocol.
    info.dwCursorPos = highlighted_position_as_wchar_index;
  }

  // Currently we can assume the suggest window is always aligned to the
  // first character in the preedit.  Perhaps we might want to have a
  // dedicated field for this purpose in future.
  if (output.has_candidates() && output.candidates().has_category() &&
      output.candidates().category() == commands::SUGGESTION) {
    focused_character_index_ = 0;
  }

  // Always set 0 to |dwDeltaStart| so that Excel updates composition.
  // See b/2959161 for details.
  // TODO(yukawa): Optimize this values so that Excel can optimize redraw
  //   region in the composition string.
  // TODO(yukawa): Use Util::WideCharsLen to support surrogate-pair.
  info.dwDeltaStart = 0;

  DCHECK_EQ(composition_string.size(), composition_attributes.size());
  info.dwCompAttrLen = composition_attributes.size();
  for (size_t i = 0; i < composition_attributes.size(); ++i) {
    composition_attribute_[i] = composition_attributes[i];
  }

  DCHECK_EQ(reading_string.size(), reading_attributes.size());
  info.dwCompReadAttrLen = reading_attributes.size();
  for (size_t i = 0; i < reading_attributes.size(); ++i) {
    composition_reading_attribute_[i] = reading_attributes[i];
  }

  HRESULT result = S_OK;
  result = ::StringCchCopyN(composition_,
                            arraysize(composition_),
                            composition_string.c_str(),
                            arraysize(composition_));
  if (FAILED(result)) {
    return false;
  }
  info.dwCompStrLen = composition_string.size();

  result = ::StringCchCopyN(composition_reading_,
                            arraysize(composition_reading_),
                            reading_string.c_str(),
                            arraysize(composition_reading_));
  if (FAILED(result)) {
    return false;
  }
  info.dwCompReadStrLen = reading_string.size();

  if (arraysize(composition_clause_) <= composition_clauses.size()) {
    return false;
  }
  info.dwCompClauseLen = composition_clauses.size() * sizeof(DWORD);
  for (size_t i = 0; i < composition_clauses.size(); ++i) {
    composition_clause_[i] = composition_clauses[i];
  }

  if (arraysize(composition_reading_clause_) <= reading_clauses.size()) {
    return false;
  }
  info.dwCompReadClauseLen = reading_clauses.size() * sizeof(DWORD);
  for (size_t i = 0; i < reading_clauses.size(); ++i) {
    composition_reading_clause_[i] = reading_clauses[i];
  }

  return true;
}

bool CompositionString::UpdateInternal(const mozc::commands::Output &output,
                                       DWORD *update) {
  info.dwCursorPos = -1;

  if (output.has_result() && !HandleResult(output)) {
    return false;
  }

  if (output.has_preedit() && !HandlePreedit(output)) {
    return false;
  }

  // We always set update flags as predefined combination regardless of which
  // field is actually updated.  Otherwise, some applications such as wordpad
  // OOo Writer 3.0 will update neither composition window nor caret state
  // properly.
  if (output.has_preedit() && output.has_result()) {
    // This situation actually occurs when you type a printable character in
    // candidate selection mode.
    // This situation also occurs by partial commit.
    *update = kPreeditAndResultUpdateFlags;
  } else if (output.has_preedit()) {
    *update = kPreeditUpdateFlags;
  } else if (output.has_result()) {
    *update = kResultUpdateFlags;
  }

  return true;
}

DWORD CompositionString::focused_character_index() const {
  return focused_character_index_;
}
}  // namespace win32
}  // namespace mozc
