// 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 "renderer/win32/text_renderer.h"

#define _ATL_NO_AUTOMATIC_NAMESPACE
#define _WTL_NO_AUTOMATIC_NAMESPACE
// Workaround against KB813540
#include <atlbase_mozc.h>
#include <atlcom.h>
#include <objbase.h>
#include <d2d1.h>
#include <dwrite.h>

#include <memory>

#include "base/logging.h"
#include "base/system_util.h"
#include "base/win_util.h"
#include "renderer/renderer_style.pb.h"
#include "renderer/renderer_style_handler.h"

namespace mozc {
namespace renderer {
namespace win32 {

using ATL::CComPtr;
using WTL::CDC;
using WTL::CDCHandle;
using WTL::CFont;
using WTL::CFontHandle;
using WTL::CLogFont;
using WTL::CPoint;
using WTL::CRect;
using WTL::CSize;
using ::mozc::renderer::RendererStyle;
using ::mozc::renderer::RendererStyleHandler;

namespace {

COLORREF GetTextColor(TextRenderer::FONT_TYPE type) {
  switch (type) {
    case TextRenderer::FONTSET_SHORTCUT:
      return RGB(0x61, 0x61, 0x61);
    case TextRenderer::FONTSET_CANDIDATE:
      return RGB(0x00, 0x00, 0x00);
    case TextRenderer::FONTSET_DESCRIPTION:
      return RGB(0x88, 0x88, 0x88);
    case TextRenderer::FONTSET_FOOTER_INDEX:
      return RGB(0x4c, 0x4c, 0x4c);
    case TextRenderer::FONTSET_FOOTER_LABEL:
      return RGB(0x4c, 0x4c, 0x4c);
    case TextRenderer::FONTSET_FOOTER_SUBLABEL:
      return RGB(0xA7, 0xA7, 0xA7);
  }

  // TODO(horo): Not only infolist fonts but also candidate fonts
  //             should be created from RendererStyle
  RendererStyle style;
  RendererStyleHandler::GetRendererStyle(&style);
  const auto &infostyle = style.infolist_style();
  switch (type) {
    case TextRenderer::FONTSET_INFOLIST_CAPTION:
      return RGB(infostyle.caption_style().foreground_color().r(),
                 infostyle.caption_style().foreground_color().g(),
                 infostyle.caption_style().foreground_color().b());
    case TextRenderer::FONTSET_INFOLIST_TITLE:
      return RGB(infostyle.title_style().foreground_color().r(),
                 infostyle.title_style().foreground_color().g(),
                 infostyle.title_style().foreground_color().b());
    case TextRenderer::FONTSET_INFOLIST_DESCRIPTION:
      return RGB(infostyle.description_style().foreground_color().r(),
                 infostyle.description_style().foreground_color().g(),
                 infostyle.description_style().foreground_color().b());
  }

  LOG(DFATAL) << "Unknown type: " << type;
  return RGB(0, 0, 0);
}

CLogFont GetLogFont(TextRenderer::FONT_TYPE type) {
  switch (type) {
    case TextRenderer::FONTSET_SHORTCUT: {
      CLogFont font;
      font.SetMessageBoxFont();
      font.MakeLarger(3);
      font.lfWeight = FW_BOLD;
      return font;
    }
    case TextRenderer::FONTSET_CANDIDATE: {
      CLogFont font;
      font.SetMessageBoxFont();
      font.MakeLarger(3);
      font.lfWeight = FW_NORMAL;
      return font;
    }
    case TextRenderer::FONTSET_DESCRIPTION:
    case TextRenderer::FONTSET_FOOTER_INDEX:
    case TextRenderer::FONTSET_FOOTER_LABEL:
    case TextRenderer::FONTSET_FOOTER_SUBLABEL: {
      CLogFont font;
      font.SetMessageBoxFont();
      font.lfWeight = FW_NORMAL;
      return font;
    }
  }

  // TODO(horo): Not only infolist fonts but also candidate fonts
  //             should be created from RendererStyle
  RendererStyle style;
  RendererStyleHandler::GetRendererStyle(&style);
  const auto &infostyle = style.infolist_style();
  switch (type) {
    case TextRenderer::FONTSET_INFOLIST_CAPTION: {
      CLogFont font;
      font.SetMessageBoxFont();
      font.lfHeight = -infostyle.caption_style().font_size();
      return font;
    }
    case TextRenderer::FONTSET_INFOLIST_TITLE: {
      CLogFont font;
      font.SetMessageBoxFont();
      font.lfHeight = -infostyle.title_style().font_size();
      return font;
    }
    case TextRenderer::FONTSET_INFOLIST_DESCRIPTION: {
      CLogFont font;
      font.SetMessageBoxFont();
      font.lfHeight = -infostyle.description_style().font_size();
      return font;
    }
  }

  LOG(DFATAL) << "Unknown type: " << type;
  CLogFont font;
  font.SetMessageBoxFont();
  return font;
}

DWORD GetGdiDrawTextStyle(TextRenderer::FONT_TYPE type) {
  switch (type) {
    case TextRenderer::FONTSET_CANDIDATE:
      return DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX;
    case TextRenderer::FONTSET_DESCRIPTION:
      return DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX;
    case TextRenderer::FONTSET_FOOTER_INDEX:
      return DT_RIGHT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX;
    case TextRenderer::FONTSET_FOOTER_LABEL:
      return DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX;
    case TextRenderer::FONTSET_FOOTER_SUBLABEL:
      return DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX;
    case TextRenderer::FONTSET_SHORTCUT:
      return DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX;
    case TextRenderer::FONTSET_INFOLIST_CAPTION:
      return DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX;
    case TextRenderer::FONTSET_INFOLIST_TITLE:
      return DT_LEFT | DT_SINGLELINE | DT_WORDBREAK | DT_EDITCONTROL |
          DT_NOPREFIX;
    case TextRenderer::FONTSET_INFOLIST_DESCRIPTION:
      return DT_LEFT | DT_WORDBREAK | DT_EDITCONTROL | DT_NOPREFIX;
    default:
      LOG(DFATAL) << "Unknown type: " << type;
      return 0;
  }
}

class GdiTextRenderer : public TextRenderer {
 public:
  GdiTextRenderer()
      : render_info_(new RenderInfo[SIZE_OF_FONT_TYPE]) {
    mem_dc_.CreateCompatibleDC();
    OnThemeChanged();
  }

  virtual ~GdiTextRenderer() {
  }

 private:
  // TextRenderer overrides:
  virtual void OnThemeChanged() {
    // delete old fonts
    for (size_t i = 0; i < SIZE_OF_FONT_TYPE; ++i) {
      if (!render_info_[i].font.IsNull()) {
        render_info_[i].font.DeleteObject();
      }
    }

    for (size_t i = 0; i < SIZE_OF_FONT_TYPE; ++i) {
      const auto font_type = static_cast<FONT_TYPE>(i);
      const auto &log_font = GetLogFont(font_type);
      render_info_[i].style = GetGdiDrawTextStyle(font_type);
      render_info_[i].font.CreateFontIndirectW(&log_font);
      render_info_[i].color = GetTextColor(font_type);
    }
  }

  virtual Size MeasureString(FONT_TYPE font_type, const wstring &str) const {
    const auto previous_font = mem_dc_.SelectFont(render_info_[font_type].font);
    CRect rect;
    mem_dc_.DrawTextW(str.c_str(), str.length(), &rect,
                      DT_NOPREFIX | DT_LEFT | DT_SINGLELINE | DT_CALCRECT);
    mem_dc_.SelectFont(previous_font);
    return Size(rect.Width(), rect.Height());
  }

  virtual Size MeasureStringMultiLine(
      FONT_TYPE font_type, const wstring &str, const int width) const {
    const auto previous_font = mem_dc_.SelectFont(render_info_[font_type].font);
    CRect rect(0, 0, width, 0);
    mem_dc_.DrawTextW(str.c_str(), str.length(), &rect,
                      DT_NOPREFIX | DT_LEFT | DT_WORDBREAK | DT_CALCRECT);
    mem_dc_.SelectFont(previous_font);
    return Size(rect.Width(), rect.Height());
  }

  virtual void RenderText(CDCHandle dc,
                          const wstring &text,
                          const Rect &rect,
                          FONT_TYPE font_type) const {
    vector<TextRenderingInfo> infolist;
    infolist.push_back(TextRenderingInfo(text, rect));
    RenderTextList(dc, infolist, font_type);
  }

  virtual void RenderTextList(CDCHandle dc,
                              const vector<TextRenderingInfo> &display_list,
                              FONT_TYPE font_type) const {
    const auto &render_info = render_info_[font_type];
    const auto old_font = dc.SelectFont(render_info.font);
    const auto previous_color = dc.SetTextColor(render_info.color);
    for (auto it = display_list.begin(); it != display_list.end(); ++it) {
      const auto &info = *it;
      CRect rect(info.rect.Left(), info.rect.Top(),
                 info.rect.Right(), info.rect.Bottom());
      const auto &text = info.text;
      dc.DrawTextW(text.data(), text.size(), &rect, render_info.style);
    }
    dc.SetTextColor(previous_color);
    dc.SelectFont(old_font);
  }

  struct RenderInfo {
    RenderInfo() : color(0), style(0) {}
    COLORREF color;
    DWORD style;
    CFont font;
  };
  unique_ptr<RenderInfo[]> render_info_;
  mutable CDC mem_dc_;

  DISALLOW_COPY_AND_ASSIGN(GdiTextRenderer);
};

const D2D1_DRAW_TEXT_OPTIONS kD2D1DrawTextOptions =
    static_cast<D2D1_DRAW_TEXT_OPTIONS>(4);

class DirectWriteTextRenderer : public TextRenderer {
 public:
  static DirectWriteTextRenderer *Create() {
    const auto d2d1 = WinUtil::LoadSystemLibrary(L"d2d1.dll");
    const auto d2d1_create_factory  =
        reinterpret_cast<D2D1CreateFactoryPtr>(
            ::GetProcAddress(d2d1, "D2D1CreateFactory"));
    if (d2d1_create_factory == nullptr) {
      return nullptr;
    }

    const auto dwrite = WinUtil::LoadSystemLibrary(L"dwrite.dll");
    const auto dwrite_create_factory  =
        reinterpret_cast<DWriteCreateFactoryPtr>(
            ::GetProcAddress(dwrite, "DWriteCreateFactory"));
    if (dwrite_create_factory == nullptr) {
      return nullptr;
    }

    HRESULT hr = S_OK;
    CComPtr<ID2D1Factory> d2d_factory;
    hr = d2d1_create_factory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
                             __uuidof(ID2D1Factory),
                             nullptr,
                             reinterpret_cast<void **>(&d2d_factory));
    if (FAILED(hr)) {
      return nullptr;
    }
    CComPtr<IDWriteFactory> dwrite_factory;
    hr = dwrite_create_factory(
        DWRITE_FACTORY_TYPE_SHARED,
        __uuidof(IDWriteFactory),
        reinterpret_cast<IUnknown **>(&dwrite_factory));
    if (FAILED(hr)) {
      return nullptr;
    }
    CComPtr<IDWriteGdiInterop> interop;
    hr = dwrite_factory->GetGdiInterop(&interop);
    if (FAILED(hr)) {
      return nullptr;
    }
    const auto kernel32 = WinUtil::GetSystemModuleHandle(L"kernel32.dll");
    const auto get_user_default_locale_name =
        reinterpret_cast<GetUserDefaultLocaleNamePtr>(
            ::GetProcAddress(kernel32, "GetUserDefaultLocaleName"));
    if (get_user_default_locale_name == nullptr) {
      return nullptr;
    }
    return new DirectWriteTextRenderer(
        d2d_factory, dwrite_factory, interop, get_user_default_locale_name);
  }
  virtual ~DirectWriteTextRenderer() {
  }

 private:
  typedef int (WINAPI *GetUserDefaultLocaleNamePtr)(LPWSTR locale_name,
                                                    int locale_name_buffer_len);

  typedef HRESULT (WINAPI *D2D1CreateFactoryPtr)(
      D2D1_FACTORY_TYPE factory_type,
      const IID &iid,
      const D2D1_FACTORY_OPTIONS *factory_options,
      void **factory);

  typedef HRESULT (WINAPI *DWriteCreateFactoryPtr)(
      DWRITE_FACTORY_TYPE factory_type,
      const IID &iid,
      IUnknown **factory);

  DirectWriteTextRenderer(
      ID2D1Factory *d2d2_factory,
      IDWriteFactory *dwrite_factory,
      IDWriteGdiInterop *dwrite_interop,
      GetUserDefaultLocaleNamePtr get_user_default_locale_name)
      : d2d2_factory_(d2d2_factory),
        dwrite_factory_(dwrite_factory),
        dwrite_interop_(dwrite_interop),
        get_user_default_locale_name_(get_user_default_locale_name) {
    OnThemeChanged();
  }

  // TextRenderer overrides:
  virtual void OnThemeChanged() {
    // delete old fonts
    render_info_.clear();
    render_info_.resize(SIZE_OF_FONT_TYPE);

    for (size_t i = 0; i < SIZE_OF_FONT_TYPE; ++i) {
      const auto font_type = static_cast<FONT_TYPE>(i);
      const auto &log_font = GetLogFont(font_type);
      render_info_[i].color = GetTextColor(font_type);
      render_info_[i].format = CreateFormat(log_font);
      render_info_[i].format_to_render = CreateFormat(log_font);
      const auto style = GetGdiDrawTextStyle(font_type);
      const auto render_font = render_info_[i].format_to_render;
      if ((style & DT_VCENTER) == DT_VCENTER) {
        render_font->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
      }
      if ((style & DT_LEFT) == DT_LEFT) {
        render_font->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING);
      }
      if ((style & DT_CENTER) == DT_CENTER) {
        render_font->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
      }
      if ((style & DT_LEFT) == DT_RIGHT) {
        render_font->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_TRAILING);
      }
    }
  }

  // Retrieves the bounding box for a given string.
  virtual Size MeasureString(FONT_TYPE font_type, const wstring &str) const {
    return MeasureStringImpl(font_type, str, 0, false);
  }

  virtual Size MeasureStringMultiLine(FONT_TYPE font_type, const wstring &str,
                                      const int width) const {
    return MeasureStringImpl(font_type, str, width, true);
  }

  virtual void RenderText(CDCHandle dc, const wstring &text,
                          const Rect &rect, FONT_TYPE font_type) const {
    vector<TextRenderingInfo> infolist;
    infolist.push_back(TextRenderingInfo(text, rect));
    RenderTextList(dc, infolist, font_type);
  }

  virtual void RenderTextList(CDCHandle dc,
                              const vector<TextRenderingInfo> &display_list,
                              FONT_TYPE font_type) const {
    CreateRenderTargetIfNecessary();
    if (dc_render_target_ == nullptr) {
      return;
    }
    CRect total_rect;
    for (size_t i = 0; i < display_list.size(); ++i) {
      const auto &item = display_list[i];
      total_rect.right = max(total_rect.right, item.rect.Right());
      total_rect.bottom = max(total_rect.right, item.rect.Bottom());
    }
    HRESULT hr = S_OK;
    hr = dc_render_target_->BindDC(dc, &total_rect);
    if (FAILED(hr)) {
      return;
    }
    CComPtr<ID2D1SolidColorBrush> brush;
    hr = dc_render_target_->CreateSolidColorBrush(
        ToD2DColor(render_info_[font_type].color),
        &brush);
    if (FAILED(hr)) {
      return;
    }
    D2D1_DRAW_TEXT_OPTIONS option = D2D1_DRAW_TEXT_OPTIONS_NONE;
    if (SystemUtil::IsWindows8_1OrLater()) {
      option |= kD2D1DrawTextOptions;
    }
    dc_render_target_->BeginDraw();
    dc_render_target_->SetTransform(D2D1::Matrix3x2F::Identity());
    for (size_t i = 0; i < display_list.size(); ++i) {
      const auto &item = display_list[i];
      const D2D1_RECT_F render_rect = {
        item.rect.Left(), item.rect.Top(), item.rect.Right(),
        item.rect.Bottom(),
      };
      dc_render_target_->DrawText(item.text.data(),
                                  item.text.size(),
                                  render_info_[font_type].format_to_render,
                                  render_rect,
                                  brush,
                                  option);
    }
    hr = dc_render_target_->EndDraw();
    if (hr == D2DERR_RECREATE_TARGET) {
      dc_render_target_.Release();
    }
  }

  Size MeasureStringImpl(FONT_TYPE font_type, const wstring &str,
                         const int width, bool use_width) const {
    HRESULT hr = S_OK;
    const FLOAT kLayoutLimit = 100000.0f;
    CComPtr<IDWriteTextLayout> layout;
    hr = dwrite_factory_->CreateTextLayout(str.data(),
                                           str.size(),
                                           render_info_[font_type].format,
                                           (use_width ? width : kLayoutLimit),
                                           kLayoutLimit,
                                           &layout);
    if (FAILED(hr)) {
      return Size();
    }
    DWRITE_TEXT_METRICS metrix = {};
    hr = layout->GetMetrics(&metrix);
    if (FAILED(hr)) {
      return Size();
    }
    return Size(ceilf(metrix.widthIncludingTrailingWhitespace),
                ceilf(metrix.height));
  }

  static D2D1_COLOR_F ToD2DColor(COLORREF color_ref) {
    D2D1_COLOR_F color;
    color.a = 1.0;
    color.r = GetRValue(color_ref) / 255.0f;
    color.g = GetGValue(color_ref) / 255.0f;
    color.b = GetBValue(color_ref) / 255.0f;
    return color;
  }

  CComPtr<IDWriteTextFormat> CreateFormat(CLogFont logfont) {
    HRESULT hr = S_OK;
    CComPtr<IDWriteFont> font;
    hr = dwrite_interop_->CreateFontFromLOGFONT(&logfont, &font);
    if (FAILED(hr)) {
      return nullptr;
    }
    CComPtr<IDWriteFontFamily> font_family;
    hr = font->GetFontFamily(&font_family);
    if (FAILED(hr)) {
      return nullptr;
    }
    CComPtr<IDWriteLocalizedStrings> localized_family_names;
    hr = font_family->GetFamilyNames(&localized_family_names);
    if (FAILED(hr)) {
      return nullptr;
    }
    UINT32 length = 0;
    hr = localized_family_names->GetStringLength(0, &length);
    if (FAILED(hr)) {
      return nullptr;
    }
    length += 1;  // for NUL.
    unique_ptr<wchar_t[]> family_name(new wchar_t[length]);
    hr = localized_family_names->GetString(0, family_name.get(), length);
    if (FAILED(hr)) {
      return nullptr;
    }
    auto font_size = logfont.lfHeight;
    if (font_size < 0) {
      font_size = -font_size;
    } else {
      DWRITE_FONT_METRICS font_metrix = {};
      font->GetMetrics(&font_metrix);
      const auto cell_height =
          static_cast<float>(font_metrix.ascent + font_metrix.descent) /
          font_metrix.designUnitsPerEm;
      font_size /= cell_height;
    }

    wchar_t locale_name[LOCALE_NAME_MAX_LENGTH] = {};
    if (get_user_default_locale_name_(locale_name, arraysize(locale_name))
        == 0) {
      return nullptr;
    }

    CComPtr<IDWriteTextFormat> format;
    hr = dwrite_factory_->CreateTextFormat(family_name.get(),
                                           nullptr,
                                           font->GetWeight(),
                                           font->GetStyle(),
                                           font->GetStretch(),
                                           font_size,
                                           locale_name,
                                           &format);
    return format;
  }

  void CreateRenderTargetIfNecessary() const {
    if (dc_render_target_) {
      return;
    }
    const auto property = D2D1::RenderTargetProperties(
        D2D1_RENDER_TARGET_TYPE_DEFAULT,
        D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE),
        0,
        0,
        D2D1_RENDER_TARGET_USAGE_NONE,
        D2D1_FEATURE_LEVEL_DEFAULT);
    d2d2_factory_->CreateDCRenderTarget(&property, &dc_render_target_);
  }

  struct RenderInfo {
    RenderInfo() : color(0) {}
    COLORREF color;
    CComPtr<IDWriteTextFormat> format;
    CComPtr<IDWriteTextFormat> format_to_render;
  };

  CComPtr<ID2D1Factory> d2d2_factory_;
  CComPtr<IDWriteFactory> dwrite_factory_;
  mutable CComPtr<ID2D1DCRenderTarget> dc_render_target_;
  CComPtr<IDWriteGdiInterop> dwrite_interop_;
  vector<RenderInfo> render_info_;
  GetUserDefaultLocaleNamePtr get_user_default_locale_name_;

  DISALLOW_COPY_AND_ASSIGN(DirectWriteTextRenderer);
};

}  // namespace

TextRenderer::~TextRenderer() {
}

// static
TextRenderer *TextRenderer::Create() {
  auto *dwrite_text_renderer = DirectWriteTextRenderer::Create();
  if (dwrite_text_renderer != nullptr) {
    return dwrite_text_renderer;
  }
  return new GdiTextRenderer();
}

}  // namespace win32
}  // namespace renderer
}  // namespace mozc
