// 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/tip/tip_ui_element_delegate.h"

#define _ATL_NO_AUTOMATIC_NAMESPACE
#define _WTL_NO_AUTOMATIC_NAMESPACE
// Workaround against KB813540
#include <atlbase_mozc.h>
#include <atlcom.h>
#include <atlstr.h>
#include <msctf.h>

#include <string>

#include "base/util.h"
#include "renderer/renderer_command.pb.h"
#include "session/commands.pb.h"
#include "win32/base/conversion_mode_util.h"
#include "win32/base/input_state.h"
#include "win32/tip/tip_dll_module.h"
#include "win32/tip/tip_edit_session.h"
#include "win32/tip/tip_private_context.h"
#include "win32/tip/tip_resource.h"
#include "win32/tip/tip_text_service.h"

namespace mozc {
namespace win32 {
namespace tsf {

namespace {

using ATL::CComBSTR;
using ATL::CComPtr;
using ATL::CComQIPtr;
using ATL::CComVariant;
using ATL::CStringW;
using mozc::commands::CompositionMode;
using ::mozc::commands::CandidateList;
using ::mozc::commands::Output;
using ::mozc::commands::Status;
typedef mozc::commands::RendererCommand_IndicatorInfo IndicatorInfo;

const size_t kPageSize = 9;

// This GUID is used in Windows Vista/7/8 by MS-IME to represents if the
// candidate window is visible or not.
// TODO(yukawa): Make sure if it is safe to use this GUID.
// {B7A578D2-9332-438A-A403-4057D05C3958}
const GUID kGuidCUASCandidateMessageCompartment = {
  0xb7a578d2, 0x9332, 0x438a, {0xa4, 0x03, 0x40, 0x57, 0xd0, 0x5c, 0x39, 0x58}
};

#ifdef GOOGLE_JAPANESE_INPUT_BUILD

// {8F51B5E5-5CF9-45D8-83B3-53CE203354C2}
const GUID KGuidNonobservableSuggestWindow = {
  0x8f51b5e5, 0x5cf9, 0x45d8, {0x83, 0xb3, 0x53, 0xce, 0x20, 0x33, 0x54, 0xc2}
};

// {3D53878A-8596-4689-B50D-3338D52B2EFB}
const GUID KGuidObservableSuggestWindow = {
  0x3d53878a, 0x8596, 0x4689, {0xb5, 0xd, 0x33, 0x38, 0xd5, 0x2b, 0x2e, 0xfb}
};

// {FED897F2-940C-40F1-B149-A931E03FB821}
const GUID KGuidCandidateWindow = {
  0xfed897f2, 0x940c, 0x40f1, {0xb1, 0x49, 0xa9, 0x31, 0xe0, 0x3f, 0xb8, 0x21}
};

// {170F6CC4-913D-4FF9-9DEA-432D08DCB0FF}
const GUID KGuidIndicatorWindow = {
  0x170f6cc4, 0x913d, 0x4ff9, { 0x9d, 0xea, 0x43, 0x2d, 0x8, 0xdc, 0xb0, 0xff}
};

#else

// {AD2489FB-D4C4-4632-85A9-7F9F917AB0FD}
const GUID KGuidNonobservableSuggestWindow = {
  0xad2489fb, 0xd4c4, 0x4632, {0x85, 0xa9, 0x7f, 0x9f, 0x91, 0x7a, 0xb0, 0xfd}
};

// {0E2D447F-9B4A-490C-9C4D-61A6A707BE26}
const GUID KGuidObservableSuggestWindow = {
  0xe2d447f, 0x9b4a, 0x490c, {0x9c, 0x4d, 0x61, 0xa6, 0xa7, 0x7, 0xbe, 0x26}
};

// {ED70ECDE-C8AA-4170-96CC-0090DEA8AEC2}
const GUID KGuidCandidateWindow = {
  0xed70ecde, 0xc8aa, 0x4170, {0x96, 0xcc, 0x0, 0x90, 0xde, 0xa8, 0xae, 0xc2}
};

// {0090BF80-5F33-41B1-843C-E3EC79ED25F9}
const GUID KGuidIndicatorWindow = {
  0x90bf80, 0x5f33, 0x41b1, { 0x84, 0x3c, 0xe3, 0xec, 0x79, 0xed, 0x25, 0xf9}
};

#endif  // GOOGLE_JAPANESE_INPUT_BUILD

CComBSTR GetResourceString(UINT resource_id) {
  CStringW str;
  str.LoadStringW(TipDllModule::module_handle(), resource_id);
  return CComBSTR(str.GetLength(), str.GetBuffer());
}

const bool kIsIndicator = true;
const bool kIsNotIndicator = false;

class TipUiElementDelegateImpl : public TipUiElementDelegate {
 public:
  TipUiElementDelegateImpl(
      TipTextService *text_service, ITfContext *context,
      TipUiElementDelegateFactory::ElementType type)
      : text_service_(text_service),
        context_(context),
        type_(type) {
  }

 private:
  ~TipUiElementDelegateImpl() {}

  virtual bool IsObservable() const {
    switch (type_) {
      case TipUiElementDelegateFactory::kConventionalObservableSuggestWindow:
      case TipUiElementDelegateFactory::kConventionalCandidateWindow:
        return true;
      default:
        return false;
    }
  }

  // The ITfUIElement interface methods
  virtual HRESULT GetDescription(BSTR *description) {
    if (description == nullptr) {
      return E_INVALIDARG;
    }
    *description = nullptr;
    switch (type_) {
      case TipUiElementDelegateFactory::kConventionalUnobservableSuggestWindow:
        *description =
            GetResourceString(IDS_UNOBSERVABLE_SUGGEST_WINDOW).Detach();
        return S_OK;
      case TipUiElementDelegateFactory::kConventionalObservableSuggestWindow:
        *description =
            GetResourceString(IDS_OBSERVABLE_SUGGEST_WINDOW).Detach();
        return S_OK;
      case TipUiElementDelegateFactory::kConventionalCandidateWindow:
        *description = GetResourceString(IDS_CANDIDATE_WINDOW).Detach();
        return S_OK;
      case TipUiElementDelegateFactory::kConventionalIndicatorWindow:
        *description = GetResourceString(IDS_INDICATOR_WINDOW).Detach();
        return S_OK;
      case TipUiElementDelegateFactory::kImmersiveCandidateWindow:
        *description = GetResourceString(IDS_CANDIDATE_WINDOW).Detach();
        return S_OK;
      case TipUiElementDelegateFactory::kImmersiveIndicatorWindow:
        *description = GetResourceString(IDS_INDICATOR_WINDOW).Detach();
        return S_OK;
      default:
        return E_UNEXPECTED;
    }
  }

  virtual HRESULT GetGUID(GUID *guid) {
    if (guid == nullptr) {
      return E_INVALIDARG;
    }
    switch (type_) {
      case TipUiElementDelegateFactory::kConventionalUnobservableSuggestWindow:
        *guid = KGuidNonobservableSuggestWindow;
        return S_OK;
      case TipUiElementDelegateFactory::kConventionalObservableSuggestWindow:
        *guid = KGuidObservableSuggestWindow;
        return S_OK;
      case TipUiElementDelegateFactory::kConventionalCandidateWindow:
        *guid = KGuidCandidateWindow;
        return S_OK;
      case TipUiElementDelegateFactory::kConventionalIndicatorWindow:
        *guid = KGuidIndicatorWindow;
        return S_OK;
      case TipUiElementDelegateFactory::kImmersiveCandidateWindow:
        *guid = KGuidCandidateWindow;
        return S_OK;
      case TipUiElementDelegateFactory::kImmersiveIndicatorWindow:
        *guid = KGuidIndicatorWindow;
        return S_OK;
      default:
        *guid = GUID_NULL;
        return E_UNEXPECTED;
    }
  }

  virtual HRESULT Show(BOOL show) {
    const bool old_shown = shown_;
    shown_ = !!show;
    if (old_shown != shown_ && IsObservable()) {
      CComQIPtr<ITfCompartmentMgr> compartment_mgr = context_;
      if (compartment_mgr) {
        // Update a hidden compartment to generate
        // IMN_OPENCANDIDATE/IMN_CLOSECANDIDATE notifications for the
        // application compatibility.
        CComQIPtr<ITfCompartment> compartment;
        if (SUCCEEDED(compartment_mgr->GetCompartment(
                kGuidCUASCandidateMessageCompartment, &compartment))) {
          CComVariant var;
          var.vt = VT_I4;
          var.lVal = shown_ ? TRUE : FALSE;
          compartment->SetValue(text_service_->GetClientID(), &var);
        }
      }
      // TODO(yukawa): Update UI.
    }
    return S_OK;
  }

  virtual HRESULT IsShown(BOOL *show) {
    if (show == nullptr) {
      return E_INVALIDARG;
    }
    *show = (shown_ ? TRUE : FALSE);
    return S_OK;
  }

  // The ITfCandidateListUIElement interface methods
  virtual HRESULT GetUpdatedFlags(DWORD *flags) {
    DCHECK(IsCandidateWindowLike());

    if (flags == nullptr) {
      return E_INVALIDARG;
    }
    *flags = 0;
    // If TF_CLUIE_STRING is included into |flags|, TSF calls back
    // ITfCandidateListUIElement::GetString for all the candidates,
    // which might be a huge bottleneck. So do not include this flag
    // whenever possible.
    if (TestModifiedAndUpdateLastCandidate()) {
      *flags |= (TF_CLUIE_STRING | TF_CLUIE_COUNT);
    }
    *flags |= (TF_CLUIE_SELECTION |
               TF_CLUIE_CURRENTPAGE |
               TF_CLUIE_PAGEINDEX);
    return S_OK;
  }

  virtual HRESULT GetDocumentMgr(ITfDocumentMgr **document_manager) {
    DCHECK(IsCandidateWindowLike());

    if (document_manager == nullptr) {
      return E_INVALIDARG;
    }
    return context_->GetDocumentMgr(document_manager);
  }

  virtual HRESULT GetCount(UINT *count) {
    DCHECK(IsCandidateWindowLike());

    if (count == nullptr) {
      return E_INVALIDARG;
    }
    *count = 0;
    TipPrivateContext *private_context =
        text_service_->GetPrivateContext(context_);
    if (private_context == nullptr) {
      return E_FAIL;
    }
    const Output &output = private_context->last_output();
    if (!output.has_all_candidate_words()) {
      return S_OK;
    }
    *count = output.all_candidate_words().candidates_size();
    return S_OK;
  }

  virtual HRESULT GetSelection(UINT *index) {
    DCHECK(IsCandidateWindowLike());

    if (index == nullptr) {
      return E_INVALIDARG;
    }
    *index = 0;
    TipPrivateContext *private_context =
        text_service_->GetPrivateContext(context_);
    if (private_context == nullptr) {
      return E_FAIL;
    }
    const Output &output = private_context->last_output();
    if (!output.has_all_candidate_words()) {
      return S_OK;
    }
    *index = output.all_candidate_words().focused_index();
    return S_OK;
  }

  virtual HRESULT GetString(UINT index, BSTR *text) {
    DCHECK(IsCandidateWindowLike());

    if (text == nullptr) {
      return E_INVALIDARG;
    }
    *text = nullptr;
    TipPrivateContext *private_context =
        text_service_->GetPrivateContext(context_);
    if (private_context == nullptr) {
      return E_FAIL;
    }
    const Output &output = private_context->last_output();
    if (!output.has_all_candidate_words()) {
      return E_FAIL;
    }
    const CandidateList &list = output.all_candidate_words();
    // Convert |index| to the index within output_->candidates().
    const int visible_index = index;
    if (visible_index >= list.candidates_size()) {
      return E_FAIL;
    }
    wstring wide_text;
    Util::UTF8ToWide(list.candidates(visible_index).value(), &wide_text);
    *text = CComBSTR(wide_text.size(), wide_text.data()).Detach();
    return S_OK;
  }

  virtual HRESULT GetPageIndex(UINT *index, UINT size, UINT *page_count) {
    DCHECK(IsCandidateWindowLike());

    if (page_count == nullptr) {
      return E_INVALIDARG;
    }
    TipPrivateContext *private_context =
        text_service_->GetPrivateContext(context_);
    if (private_context == nullptr) {
      return E_FAIL;
    }
    const Output &output = private_context->last_output();
    if (!output.has_all_candidate_words()) {
      return E_FAIL;
    }
    const CandidateList &list = output.all_candidate_words();
    const size_t max_page = (list.candidates_size() / kPageSize);
    *page_count = max_page + 1;

    if (index == nullptr) {
      // An application can pass nullptr as |index| to obtain only page_count.
      return S_OK;
    }

    if (size < *page_count) {
      return E_NOT_SUFFICIENT_BUFFER;
    }
    for (size_t i = 0; i < *page_count; ++i) {
      index[i] = i * kPageSize;
    }
    return S_OK;
  }

  virtual HRESULT SetPageIndex(UINT *index, UINT page_count) {
    DCHECK(IsCandidateWindowLike());

    return E_NOTIMPL;
  }

  virtual HRESULT GetCurrentPage(UINT *current_page) {
    DCHECK(IsCandidateWindowLike());

    if (current_page == nullptr) {
      return E_INVALIDARG;
    }
    *current_page = 0;
    TipPrivateContext *private_context =
        text_service_->GetPrivateContext(context_);
    if (private_context == nullptr) {
      return E_FAIL;
    }
    const Output &output = private_context->last_output();
    if (!output.has_all_candidate_words()) {
      return S_OK;
    }
    *current_page = output.all_candidate_words().focused_index() / kPageSize;
    return S_OK;
  }

  // The ITfCandidateListUIElementBehavior interface methods
  virtual HRESULT SetSelection(UINT index) {
    DCHECK(IsCandidateWindowLike());

    TipPrivateContext *private_context =
        text_service_->GetPrivateContext(context_);
    if (private_context == nullptr) {
      return E_FAIL;
    }
    const Output &output = private_context->last_output();
    if (!output.has_all_candidate_words()) {
      return E_FAIL;
    }
    const CandidateList &list = output.all_candidate_words();
    if (list.candidates_size() <= index) {
      return E_INVALIDARG;
    }
    const int id = list.candidates(index).id();
    if (!TipEditSession::SelectCandidateAsync(text_service_, context_, id)) {
      return E_FAIL;
    }
    return S_OK;
  }

  virtual HRESULT Finalize() {
    DCHECK(IsCandidateWindowLike());

    if (!TipEditSession::SubmitAsync(text_service_, context_)) {
      return E_FAIL;
    }
    return S_OK;
  }

  virtual HRESULT Abort() {
    DCHECK(IsCandidateWindowLike());

    // Currently equals to Finalize().
    if (!TipEditSession::SubmitAsync(text_service_, context_)) {
      return E_FAIL;
    }
    return S_OK;
  }

  virtual HRESULT GetString(BSTR *text) {
    DCHECK(IsIndicator());

    if (text == nullptr) {
      return E_INVALIDARG;
    }

    CStringW msg = L"";

    TipPrivateContext *private_context =
        text_service_->GetPrivateContext(context_);
    if (private_context == nullptr) {
      *text = CComBSTR(msg.GetLength(), msg.GetBuffer()).Detach();
      return S_OK;
    }
    if (!private_context->last_output().has_status()) {
      *text = CComBSTR(msg.GetLength(), msg.GetBuffer()).Detach();
      return S_OK;
    }
    const Status &status = private_context->last_output().status();
    if (status.has_activated() && !status.activated()) {
      msg = L"A";
      *text = CComBSTR(msg.GetLength(), msg.GetBuffer()).Detach();
      return S_OK;
    }
    if (!status.has_mode()) {
      *text = CComBSTR(msg.GetLength(), msg.GetBuffer()).Detach();
      return S_OK;
    }

    switch (status.mode()) {
      case commands::DIRECT:
        DLOG(FATAL) << "Must not reach here.";
        break;
      case commands::HIRAGANA:
        msg = L"\u3042";
        break;
      case commands::FULL_KATAKANA:
        msg = L"\u30AB";
        break;
      case commands::HALF_ASCII:
        msg = L"_A";
        break;
      case commands::FULL_ASCII:
        msg = L"\uFF21";
        break;
      case commands::HALF_KATAKANA:
        msg = L"_\uFF76";
        break;
      default:
        break;
    }

    *text = CComBSTR(msg.GetLength(), msg.GetBuffer()).Detach();
    return S_OK;
  }

  // Returns true if the candidate list is updated. When this function returns
  // false, you need not update the list of candidate strings at this time.
  // Note that this function updates |last_candidate_list_| internally.
  bool TestModifiedAndUpdateLastCandidate() {
    TipPrivateContext *private_context =
        text_service_->GetPrivateContext(context_);
    if (private_context == nullptr) {
      return true;
    }
    const Output &output = private_context->last_output();
    if (!output.has_all_candidate_words()) {
      return true;
    }
    const CandidateList &list = output.all_candidate_words();
    if (last_candidate_list_.candidates_size() != list.candidates_size()) {
      last_candidate_list_.CopyFrom(list);
      return true;
    }
    for (int i = 0; i < list.candidates_size(); ++i) {
      if (last_candidate_list_.candidates(i).value() !=
          list.candidates(i).value()) {
        last_candidate_list_.CopyFrom(list);
        return true;
      }
    }
    return false;
  }

  bool IsCandidateWindowLike() const {
    switch (type_) {
      case TipUiElementDelegateFactory::kConventionalUnobservableSuggestWindow:
        return true;
      case TipUiElementDelegateFactory::kConventionalObservableSuggestWindow:
        return true;
      case TipUiElementDelegateFactory::kConventionalCandidateWindow:
        return true;
      case TipUiElementDelegateFactory::kConventionalIndicatorWindow:
        return false;
      case TipUiElementDelegateFactory::kImmersiveCandidateWindow:
        return true;
      case TipUiElementDelegateFactory::kImmersiveIndicatorWindow:
        return false;
      default:
        return false;
    }
  }

  bool IsIndicator() const {
    switch (type_) {
      case TipUiElementDelegateFactory::kConventionalUnobservableSuggestWindow:
        return false;
      case TipUiElementDelegateFactory::kConventionalObservableSuggestWindow:
        return false;
      case TipUiElementDelegateFactory::kConventionalCandidateWindow:
        return false;
      case TipUiElementDelegateFactory::kConventionalIndicatorWindow:
        return true;
      case TipUiElementDelegateFactory::kImmersiveCandidateWindow:
        return false;
      case TipUiElementDelegateFactory::kImmersiveIndicatorWindow:
        return true;
      default:
        return false;
    }
  }

  CComPtr<TipTextService> text_service_;
  CComPtr<ITfContext> context_;
  const TipUiElementDelegateFactory::ElementType type_;
  CandidateList last_candidate_list_;
  bool shown_;
  DISALLOW_COPY_AND_ASSIGN(TipUiElementDelegateImpl);
};

}  // namespace

TipUiElementDelegate::TipUiElementDelegate() {}
TipUiElementDelegate::~TipUiElementDelegate() {}

TipUiElementDelegate *TipUiElementDelegateFactory::Create(
      TipTextService *text_service, ITfContext *context, ElementType type) {
  return new TipUiElementDelegateImpl(text_service, context, type);
}

}  // namespace tsf
}  // namespace win32
}  // namespace mozc
