// 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_conventional.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 <memory>
#include <string>

#include "base/util.h"
#include "session/commands.pb.h"
#include "win32/tip/tip_dll_module.h"
#include "win32/tip/tip_private_context.h"
#include "win32/tip/tip_ref_count.h"
#include "win32/tip/tip_text_service.h"
#include "win32/tip/tip_ui_element_delegate.h"

namespace mozc {
namespace win32 {
namespace tsf {

namespace {

using ATL::CComBSTR;
using ATL::CComPtr;
using ATL::CComQIPtr;
using ATL::CComVariant;
using ATL::CStringW;
using std::unique_ptr;

class TipCandidateListImpl : public ITfCandidateListUIElementBehavior {
 public:
  TipCandidateListImpl(TipUiElementConventional::UIType type,
                       TipTextService *text_service,
                       ITfContext *context)
      : delegate_(TipUiElementDelegateFactory::Create(
            text_service, context, ToDelegateType(type))) {
  }

 private:
  ~TipCandidateListImpl() {}

  // The IUnknown interface methods.
  virtual STDMETHODIMP QueryInterface(REFIID interface_id, void **object) {
    if (!object) {
      return E_INVALIDARG;
    }
    *object = nullptr;

    // Finds a matching interface from the ones implemented by this object.
    // This object implements IUnknown.
    if (::IsEqualIID(interface_id, IID_IUnknown)) {
      *object = static_cast<IUnknown *>(this);
    } else if (IsEqualIID(interface_id, IID_ITfUIElement)) {
      *object = static_cast<ITfUIElement *>(this);
    } else if (delegate_->IsObservable()) {
      // Following interfaces are available iff the |type_| is observable.
      if (IsEqualIID(interface_id, IID_ITfCandidateListUIElement)) {
        *object = static_cast<ITfCandidateListUIElement *>(this);
      } else if (IsEqualIID(interface_id,
                            IID_ITfCandidateListUIElementBehavior)) {
        *object = static_cast<ITfCandidateListUIElementBehavior *>(this);
      }
    }

    if (*object == nullptr) {
      return E_NOINTERFACE;
    }

    AddRef();
    return S_OK;
  }

  virtual ULONG STDMETHODCALLTYPE AddRef() {
    return ref_count_.AddRefImpl();
  }

  virtual ULONG STDMETHODCALLTYPE Release() {
    const ULONG count = ref_count_.ReleaseImpl();
    if (count == 0) {
      delete this;
    }
    return count;
  }

  // The ITfUIElement interface methods
  virtual HRESULT STDMETHODCALLTYPE GetDescription(BSTR *description) {
    return delegate_->GetDescription(description);
  }
  virtual HRESULT STDMETHODCALLTYPE GetGUID(GUID *guid) {
    return delegate_->GetGUID(guid);
  }
  virtual HRESULT STDMETHODCALLTYPE Show(BOOL show) {
    return delegate_->Show(show);
  }
  virtual HRESULT STDMETHODCALLTYPE IsShown(BOOL *show) {
    return delegate_->IsShown(show);
  }

  // The ITfCandidateListUIElement interface methods
  virtual HRESULT STDMETHODCALLTYPE GetUpdatedFlags(DWORD *flags) {
    return delegate_->GetUpdatedFlags(flags);
  }
  virtual HRESULT STDMETHODCALLTYPE GetDocumentMgr(
      ITfDocumentMgr **document_manager) {
    return delegate_->GetDocumentMgr(document_manager);
  }
  virtual HRESULT STDMETHODCALLTYPE GetCount(UINT *count) {
    return delegate_->GetCount(count);
  }
  virtual HRESULT STDMETHODCALLTYPE GetSelection(UINT *index) {
    return delegate_->GetSelection(index);
  }
  virtual HRESULT STDMETHODCALLTYPE GetString(UINT index, BSTR *text) {
    return delegate_->GetString(index, text);
  }
  virtual HRESULT STDMETHODCALLTYPE GetPageIndex(UINT *index, UINT size,
                                                 UINT *page_count) {
    return delegate_->GetPageIndex(index, size, page_count);
  }
  virtual HRESULT STDMETHODCALLTYPE SetPageIndex(UINT *index,
                                                 UINT page_count) {
    return delegate_->SetPageIndex(index, page_count);
  }
  virtual HRESULT STDMETHODCALLTYPE GetCurrentPage(UINT *current_page) {
    return delegate_->GetCurrentPage(current_page);
  }

  // The ITfCandidateListUIElementBehavior interface methods
  virtual HRESULT STDMETHODCALLTYPE SetSelection(UINT index) {
    return delegate_->SetSelection(index);
  }
  virtual HRESULT STDMETHODCALLTYPE Finalize() {
    return delegate_->Finalize();
  }
  virtual HRESULT STDMETHODCALLTYPE Abort() {
    return delegate_->Abort();
  }

  static TipUiElementDelegateFactory::ElementType ToDelegateType(
      TipUiElementConventional::UIType type) {
    switch (type) {
      case TipUiElementConventional::kUnobservableSuggestWindow:
        return TipUiElementDelegateFactory::
            kConventionalUnobservableSuggestWindow;
      case TipUiElementConventional::kObservableSuggestWindow:
        return
            TipUiElementDelegateFactory::kConventionalObservableSuggestWindow;
      case TipUiElementConventional::kCandidateWindow:
        return TipUiElementDelegateFactory::kConventionalCandidateWindow;
      default:
        LOG(FATAL) << "must not reach here.";
        return TipUiElementDelegateFactory::kConventionalCandidateWindow;
    }
  }

  TipRefCount ref_count_;
  unique_ptr<TipUiElementDelegate> delegate_;
  DISALLOW_COPY_AND_ASSIGN(TipCandidateListImpl);
};

class TipIndicatorImpl : public ITfToolTipUIElement {
 public:
  TipIndicatorImpl(TipTextService *text_service, ITfContext *context)
      : delegate_(TipUiElementDelegateFactory::Create(
            text_service, context,
            TipUiElementDelegateFactory::kConventionalIndicatorWindow)) {}

 private:
  ~TipIndicatorImpl() {}

  // The IUnknown interface methods.
  virtual STDMETHODIMP QueryInterface(REFIID interface_id, void **object) {
    if (!object) {
      return E_INVALIDARG;
    }
    *object = nullptr;

    // Finds a matching interface from the ones implemented by this object.
    // This object implements IUnknown.
    if (::IsEqualIID(interface_id, IID_IUnknown)) {
      *object = static_cast<IUnknown *>(this);
    } else if (::IsEqualIID(interface_id, IID_ITfUIElement)) {
      *object = static_cast<ITfUIElement *>(this);
    } else if (::IsEqualIID(interface_id, IID_ITfToolTipUIElement)) {
      *object = static_cast<ITfToolTipUIElement *>(this);
    }

    if (*object == nullptr) {
      return E_NOINTERFACE;
    }

    AddRef();
    return S_OK;
  }

  virtual ULONG STDMETHODCALLTYPE AddRef() {
    return ref_count_.AddRefImpl();
  }

  virtual ULONG STDMETHODCALLTYPE Release() {
    const ULONG count = ref_count_.ReleaseImpl();
    if (count == 0) {
      delete this;
    }
    return count;
  }

  // The ITfUIElement interface methods
  virtual HRESULT STDMETHODCALLTYPE GetDescription(BSTR *description) {
    return delegate_->GetDescription(description);
  }
  virtual HRESULT STDMETHODCALLTYPE GetGUID(GUID *guid) {
    return delegate_->GetGUID(guid);
  }
  virtual HRESULT STDMETHODCALLTYPE Show(BOOL show) {
    return delegate_->Show(show);
  }
  virtual HRESULT STDMETHODCALLTYPE IsShown(BOOL *show) {
    return delegate_->IsShown(show);
  }

  // The ITfToolTipUIElement interface methods
  virtual HRESULT STDMETHODCALLTYPE GetString(BSTR *str) {
    return delegate_->GetString(str);
  }

  TipRefCount ref_count_;
  unique_ptr<TipUiElementDelegate> delegate_;
  DISALLOW_COPY_AND_ASSIGN(TipIndicatorImpl);
};

}  // namespace

ITfUIElement *TipUiElementConventional::New(
    TipUiElementConventional::UIType type,
    TipTextService *text_service,
    ITfContext *context) {
  if (text_service == nullptr) {
    return nullptr;
  }
  if (context == nullptr) {
    return nullptr;
  }
  switch (type) {
    case TipUiElementConventional::kUnobservableSuggestWindow:
      return new TipCandidateListImpl(type, text_service, context);
    case TipUiElementConventional::kObservableSuggestWindow:
      return new TipCandidateListImpl(type, text_service, context);
    case TipUiElementConventional::kCandidateWindow:
      return new TipCandidateListImpl(type, text_service, context);
    case TipUiElementConventional::KIndicatorWindow:
      return new TipIndicatorImpl(text_service, context);
    default:
      return nullptr;
  }
}

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