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

#include <windows.h>

#include <sstream>

#include "base/coordinates.h"
#include "base/logging.h"
#include "base/util.h"
#include "client/client_interface.h"
#include "renderer/renderer_command.pb.h"
#include "renderer/renderer_style_handler.h"
#include "renderer/table_layout.h"
#include "renderer/win32/text_renderer.h"
#include "renderer/win_resource.h"

namespace mozc {
namespace renderer {
namespace win32 {

using WTL::CBitmap;
using WTL::CDC;
using WTL::CDCHandle;
using WTL::CMemoryDC;
using WTL::CPaintDC;
using WTL::CPenHandle;
using WTL::CPoint;
using WTL::CRect;
using WTL::CSize;

namespace {

// 96 DPI is the default DPI in Windows.
const int kDefaultDPI = 96;

// layout size constants in pixel unit in the default DPI.
const int kIndicatorWidthInDefaultDPI = 4;

// DPI-invariant layout size constants in pixel unit.
const int kWindowBorder = 1;
const int kFooterSeparatorHeight = 1;
const int kRowRectPadding = 1;

// usage type for each column.
enum COLUMN_TYPE {
  COLUMN_SHORTCUT = 0,  // show shortcut key
  COLUMN_GAP1,          // padding region
  COLUMN_CANDIDATE,     // show candidate string
  COLUMN_GAP2,          // padding region
  COLUMN_DESCRIPTION,   // show description message
  NUMBER_OF_COLUMNS,    // number of columns. (this item should be last)
};

// "そのほかの文字種"
const char kMinimumCandidateAndDescriptionWidthAsString[] =
    "\xe3\x81\x9d\xe3\x81\xae\xe3\x81\xbb\xe3\x81\x8b\xe3\x81\xae\xe6\x96\x87"
    "\xe5\xad\x97\xe7\xa8\xae";

// Color scheme
const COLORREF kFrameColor = RGB(0x96, 0x96, 0x96);
const COLORREF kShortcutBackgroundColor = RGB(0xf3, 0xf4, 0xff);
const COLORREF kSelectedRowBackgroundColor = RGB(0xd1, 0xea, 0xff);
const COLORREF kDefaultBackgroundColor = RGB(0xff, 0xff, 0xff);
const COLORREF kSelectedRowFrameColor = RGB(0x7f, 0xac, 0xdd);
const COLORREF kIndicatorBackgroundColor = RGB(0xe0, 0xe0, 0xe0);
const COLORREF kIndicatorColor = RGB(0x75, 0x90, 0xb8);
const COLORREF kFooterTopColor = RGB(0xff, 0xff, 0xff);
const COLORREF kFooterBottomColor = RGB(0xee, 0xee, 0xee);

// ------------------------------------------------------------------------
// Utility functions
// ------------------------------------------------------------------------
WTL::CRect ToCRect(const Rect &rect) {
  return WTL::CRect(rect.Left(), rect.Top(), rect.Right(), rect.Bottom());
}

// Returns the smallest index of the given candidate list which satisfies
// candidates.candidate(i) == |candidate_index|.
// This function returns the size of the given candidate list when there
// aren't any candidates satisfying the above condition.
int GetCandidateArrayIndexByCandidateIndex(
    const commands::Candidates &candidates,
    int candidate_index) {

  for (size_t i = 0; i < candidates.candidate_size(); ++i) {
    const commands::Candidates::Candidate &candidate = candidates.candidate(i);

    if (candidate.index() == candidate_index) {
      return i;
    }
  }

  return candidates.candidate_size();
}

// Returns a text which includes the selected index number and
// the number of the candidates. For example, "13/123" means
// the selected index is "13" (in 1-origin) and the number of
// candidates is "123"
// Returns an empty string if index string should not be displayed.
string GetIndexGuideString(const commands::Candidates &candidates) {
  if (!candidates.has_footer() || !candidates.footer().index_visible()) {
    return "";
  }

  const int focused_index = candidates.focused_index();
  const int total_items = candidates.size();

  stringstream footer_string;
  footer_string << focused_index + 1
                << "/"
                << total_items
                << " ";  // for padding.

  return footer_string.str();
}

// Returns the smallest index of the given candidate list which satisfies
// |candidates.focused_index| == |candidates.candidate(i).index()|.
// This function returns the size of the given candidate list when there
// aren't any candidates satisfying the above condition.
int GetFocusedArrayIndex(const commands::Candidates &candidates) {
  const int kInvalidIndex = candidates.candidate_size();

  if (!candidates.has_focused_index()) {
    return kInvalidIndex;
  }

  const int focused_index = candidates.focused_index();

  return GetCandidateArrayIndexByCandidateIndex(candidates, focused_index);
}

// Retrieves the display string from the specified candidate for the specified
// column and returns it.
wstring GetDisplayStringByColumn(
    const commands::Candidates::Candidate &candidate,
    COLUMN_TYPE column_type) {
  wstring display_string;

  switch (column_type) {
    case COLUMN_SHORTCUT:
      if (candidate.has_annotation()) {
        const commands::Annotation &annotation = candidate.annotation();
        if (annotation.has_shortcut()) {
          mozc::Util::UTF8ToWide(annotation.shortcut().c_str(),
                                 &display_string);
        }
      }
      break;
    case COLUMN_CANDIDATE:
      if (candidate.has_value()) {
        mozc::Util::UTF8ToWide(candidate.value().c_str(), &display_string);
      }
      if (candidate.has_annotation()) {
        const commands::Annotation &annotation = candidate.annotation();
        if (annotation.has_prefix()) {
          wstring annotation_prefix;
          mozc::Util::UTF8ToWide(annotation.prefix().c_str(),
                                 &annotation_prefix);
          display_string = annotation_prefix + display_string;
        }
        if (annotation.has_suffix()) {
          wstring annotation_suffix;
          mozc::Util::UTF8ToWide(annotation.suffix().c_str(),
                                 &annotation_suffix);
          display_string += annotation_suffix;
        }
      }
      break;
    case COLUMN_DESCRIPTION:
      if (candidate.has_annotation()) {
        const commands::Annotation &annotation = candidate.annotation();
        if (annotation.has_description()) {
          mozc::Util::UTF8ToWide(annotation.description().c_str(),
                                 &display_string);
        }
      }
      break;
    default:
      LOG(ERROR) << "Unknown column type: " << column_type;
      break;
  }

  return display_string;
}

// Loads a DIB from a Win32 resource in the specified module and returns its
// handle.  This function will fail if you try to load a top-down bitmap in
// Windows XP.
// Returns nullptr if failed to load the image.
// Caller must delete the object if this function returns non-null value.
HBITMAP LoadBitmapFromResource(HMODULE module, int resource_id) {
  // We can use LR_CREATEDIBSECTION to load a 32-bpp bitmap.
  // You cannot load a a top-down DIB with LoadImage in Windows XP.
  // http://b/2076264
  return reinterpret_cast<HBITMAP>(
      ::LoadImage(module, MAKEINTRESOURCE(resource_id), IMAGE_BITMAP,
                  0, 0, LR_CREATEDIBSECTION));
}

}  // namespace

// ------------------------------------------------------------------------
// CandidateWindow
// ------------------------------------------------------------------------

CandidateWindow::CandidateWindow()
    : candidates_(new commands::Candidates),
      indicator_width_(0),
      footer_logo_display_size_(0, 0),
      metrics_changed_(false),
      mouse_moving_(true),
      text_renderer_(TextRenderer::Create()),
      table_layout_(new TableLayout),
      send_command_interface_(nullptr) {
  double scale_factor_x = 1.0;
  double scale_factor_y = 1.0;
  RendererStyleHandler::GetDPIScalingFactor(&scale_factor_x,
                                            &scale_factor_y);
  double image_scale_factor = 1.0;
  if (scale_factor_x < 1.125 || scale_factor_y < 1.125) {
    footer_logo_.Attach(LoadBitmapFromResource(
      ::GetModuleHandle(nullptr), IDB_FOOTER_LOGO_COLOR_100));
    image_scale_factor = 1.0;
  } else if (scale_factor_x < 1.375 || scale_factor_y < 1.375) {
    footer_logo_.Attach(LoadBitmapFromResource(
      ::GetModuleHandle(nullptr), IDB_FOOTER_LOGO_COLOR_125));
    image_scale_factor = 1.25;
  } else if (scale_factor_x < 1.75 || scale_factor_y < 1.75) {
    footer_logo_.Attach(LoadBitmapFromResource(
      ::GetModuleHandle(nullptr), IDB_FOOTER_LOGO_COLOR_150));
    image_scale_factor = 1.5;
  } else {
    footer_logo_.Attach(LoadBitmapFromResource(
      ::GetModuleHandle(nullptr), IDB_FOOTER_LOGO_COLOR_200));
    image_scale_factor = 2.0;
  }

  // If DPI is not default value, re-calculate the size based on the DPI.
  if (!footer_logo_.IsNull()) {
    CSize size;
    footer_logo_.GetSize(size);
    size.cx *= (scale_factor_x / image_scale_factor);
    size.cy *= (scale_factor_y / image_scale_factor);
    footer_logo_display_size_ = Size(size.cx, size.cy);
  }

  indicator_width_ = kIndicatorWidthInDefaultDPI * scale_factor_x;
}

CandidateWindow::~CandidateWindow() {}

LRESULT CandidateWindow::OnCreate(LPCREATESTRUCT create_struct) {
  EnableOrDisableWindowForWorkaround();
  return 0;
}

void CandidateWindow::EnableOrDisableWindowForWorkaround() {
  // Disable the window if SPI_GETACTIVEWINDOWTRACKING is enabled.
  // See b/2317702 for details.
  // TODO(yukawa): Support mouse operations before we add a GUI feature which
  //   requires UI interaction by mouse and/or touch. (b/2954874)
  BOOL is_tracking_enabled = FALSE;
  if (::SystemParametersInfo(SPI_GETACTIVEWINDOWTRACKING,
                             0, &is_tracking_enabled, 0)) {
    EnableWindow(!is_tracking_enabled);
  }
}

void CandidateWindow::OnDestroy() {
  // PostQuitMessage may stop the message loop even though other
  // windows are not closed. WindowManager should close these windows
  // before process termination.
  ::PostQuitMessage(0);
}

BOOL CandidateWindow::OnEraseBkgnd(CDCHandle dc) {
  // We do not have to erase background
  // because all pixels in client area will be drawn in the DoPaint method.
  return TRUE;
}

void CandidateWindow::OnGetMinMaxInfo(MINMAXINFO *min_max_info) {
  // Do not restrict the window size in case the candidate window must be
  // very small size.
  min_max_info->ptMinTrackSize.x = 1;
  min_max_info->ptMinTrackSize.y = 1;
  SetMsgHandled(TRUE);
}

void CandidateWindow::HandleMouseEvent(
    UINT nFlags, const WTL::CPoint &point, bool close_candidatewindow) {
  if (send_command_interface_ == nullptr) {
    LOG(ERROR) << "send_command_interface_ is nullptr";
    return;
  }

  const int focused_array_index = GetFocusedArrayIndex(*candidates_);

  for (size_t i = 0; i < candidates_->candidate_size(); ++i) {
    const commands::Candidates::Candidate &candidate
        = candidates_->candidate(i);

    const CRect rect = ToCRect(table_layout_->GetRowRect(i));
    if (rect.PtInRect(point)) {
      commands::SessionCommand command;
      if (close_candidatewindow) {
        command.set_type(commands::SessionCommand::SELECT_CANDIDATE);
      } else {
        command.set_type(commands::SessionCommand::HIGHLIGHT_CANDIDATE);
      }
      command.set_id(candidate.id());
      commands::Output output;
      send_command_interface_->SendCommand(command, &output);
      return;
    }
  }
}

void CandidateWindow::OnLButtonDown(UINT nFlags, CPoint point) {
  HandleMouseEvent(nFlags, point, false);
}

void CandidateWindow::OnLButtonUp(UINT nFlags, CPoint point) {
  HandleMouseEvent(nFlags, point, true);
}

void CandidateWindow::OnMouseMove(UINT nFlags, WTL::CPoint point) {
  // Window manager sometimes generates WM_MOUSEMOVE message when the contents
  // under the mouse cursor has been changed (e.g. the window is moved) so that
  // the mouse handler can change its cursor image based on the contents to
  // which the cursor is newly pointing.  In order to filter these pseudo
  // WM_MOUSEMOVE out, |mouse_moving_| is checked here.
  // See http://blogs.msdn.com/b/oldnewthing/archive/2003/10/01/55108.aspx for
  // details about such an artificial WM_MOUSEMOVE.  See also b/3104996.
  if (!mouse_moving_) {
    return;
  }
  if ((nFlags & MK_LBUTTON) != MK_LBUTTON) {
    return;
  }

  HandleMouseEvent(nFlags, point, false);
}

void CandidateWindow::OnPaint(CDCHandle dc) {
  CRect client_rect;
  this->GetClientRect(&client_rect);

  if (dc != nullptr) {
    CMemoryDC memdc(dc, client_rect);
    DoPaint(memdc.m_hDC);
  } else  {
    CPaintDC paint_dc(this->m_hWnd);
    { // Create a copy of |paint_dc| and render the candidate strings in it.
      // The image rendered to this |memdc| is to be copied into the original
      // |paint_dc| in its destructor. So, we don't have to explicitly call
      // any functions that copy this |memdc| to the |paint_dc| but putting
      // the following code into a local block.
      CMemoryDC memdc(paint_dc, client_rect);
      DoPaint(memdc.m_hDC);
    }
  }
}

void CandidateWindow::OnPrintClient(CDCHandle dc, UINT uFlags) {
  OnPaint(dc);
}

void CandidateWindow::DoPaint(CDCHandle dc) {
  switch (candidates_->category()) {
    case commands::CONVERSION:
    case commands::PREDICTION:
    case commands::TRANSLITERATION:
    case commands::SUGGESTION:
    case commands::USAGE:
      break;
    default:
      LOG(INFO) << "Unknown candidates category: " << candidates_->category();
      return;
  }

  if (!table_layout_->IsLayoutFrozen()) {
    LOG(WARNING) << "Table layout is not frozen.";
    return;
  }

  dc.SetBkMode(TRANSPARENT);

  DrawBackground(dc);
  DrawShortcutBackground(dc);
  DrawSelectedRect(dc);
  DrawCells(dc);
  DrawInformationIcon(dc);
  DrawVScrollBar(dc);
  DrawFooter(dc);
  DrawFrame(dc);
}

void CandidateWindow::OnSettingChange(UINT uFlags, LPCTSTR /*lpszSection*/) {
  // Since TextRenderer uses dialog font to render,
  // we monitor font-related parameters to know when the font style is changed.
  switch (uFlags) {
    case 0x1049:  // = SPI_SETCLEARTYPE
    case SPI_SETFONTSMOOTHING:
    case SPI_SETFONTSMOOTHINGCONTRAST:
    case SPI_SETFONTSMOOTHINGORIENTATION:
    case SPI_SETFONTSMOOTHINGTYPE:
    case SPI_SETNONCLIENTMETRICS:
      metrics_changed_ = true;
      break;
    case SPI_SETACTIVEWINDOWTRACKING:
      EnableOrDisableWindowForWorkaround();
    default:
      // We ignore other changes.
      break;
  }
}

void CandidateWindow::UpdateLayout(const commands::Candidates &candidates) {
  candidates_->CopyFrom(candidates);

  // If we detect any change of font parameters, update text renderer
  if (metrics_changed_) {
    text_renderer_->OnThemeChanged();
    metrics_changed_ = false;
  }

  switch (candidates_->category()) {
    case commands::CONVERSION:
    case commands::PREDICTION:
    case commands::TRANSLITERATION:
    case commands::SUGGESTION:
    case commands::USAGE:
      break;
    default:
      LOG(INFO) << "Unknown candidates category: " << candidates_->category();
      return;
  }

  table_layout_->Initialize(candidates_->candidate_size(), NUMBER_OF_COLUMNS);

  table_layout_->SetWindowBorder(kWindowBorder);

  // Add a vertical scroll bar if candidate list consists of more than
  // one page.
  if (candidates_->candidate_size() < candidates_->size()) {
    table_layout_->SetVScrollBar(indicator_width_);
  }

  if (candidates_->has_footer()) {
    Size footer_size(0, 0);

    // Calculate the size to display a label string.
    if (candidates_->footer().has_label()) {
      wstring footer_label;
      mozc::Util::UTF8ToWide(candidates_->footer().label().c_str(),
                             &footer_label);
      const Size label_string_size = text_renderer_->MeasureString(
          TextRenderer::FONTSET_FOOTER_LABEL,
          L" " + footer_label + L" ");
      footer_size.width += label_string_size.width;
      footer_size.height = max(footer_size.height, label_string_size.height);
    } else if (candidates_->footer().has_sub_label()) {
      // Currently the sub label will not be shown unless (main) label is
      // absent.
      // TODO(yukawa): Refactor the layout system for the footer.
      wstring footer_sub_label;
      mozc::Util::UTF8ToWide(candidates_->footer().sub_label().c_str(),
                             &footer_sub_label);
      const Size label_string_size = text_renderer_->MeasureString(
          TextRenderer::FONTSET_FOOTER_SUBLABEL,
          L" " + footer_sub_label + L" ");
      footer_size.width += label_string_size.width;
      footer_size.height = max(footer_size.height, label_string_size.height);
    }

    // Calculate the size to display a index string.
    if (candidates_->footer().index_visible()) {
      wstring index_guide_string;
      mozc::Util::UTF8ToWide(
          GetIndexGuideString(*candidates_).c_str(), &index_guide_string);
      const Size index_guide_size = text_renderer_->MeasureString(
          TextRenderer::FONTSET_FOOTER_INDEX, index_guide_string);
      footer_size.width += index_guide_size.width;
      footer_size.height = max(footer_size.height, index_guide_size.height);
    }

    // Calculate the size to display a Footer logo.
    if (!footer_logo_.IsNull()) {
      if (candidates_->footer().logo_visible()) {
        footer_size.width += footer_logo_display_size_.width;
        footer_size.height = max(footer_size.height,
                                 footer_logo_display_size_.height);
      } else if (footer_size.height > 0) {
        // Ensure the footer height is greater than the Footer logo height
        // even if the Footer logo is absent.  This hack prevents the footer
        // from changing its height too frequently.
        footer_size.height = max(footer_size.height,
                                 footer_logo_display_size_.height);
      }
    }

    // Ensure minimum columns width if candidate list consists of more than
    // one page.
    if (candidates_->candidate_size() < candidates_->size()) {
      // We use FONTSET_CANDIDATE for calculating the minimum width.
      wstring minimum_width_as_wstring;
      mozc::Util::UTF8ToWide(
          kMinimumCandidateAndDescriptionWidthAsString,
          &minimum_width_as_wstring);
      const Size minimum_size = text_renderer_->MeasureString(
          TextRenderer::FONTSET_CANDIDATE, minimum_width_as_wstring.c_str());
      table_layout_->EnsureColumnsWidth(
          COLUMN_CANDIDATE, COLUMN_DESCRIPTION, minimum_size.width);
    }

    // Add separator height
    footer_size.height += kFooterSeparatorHeight;

    table_layout_->EnsureFooterSize(footer_size);
  }

  table_layout_->SetRowRectPadding(kRowRectPadding);

  // put a padding in COLUMN_GAP1.
  // the width is determined to be equal to the width of " ".
  const Size gap1_size =
      text_renderer_->MeasureString(TextRenderer::FONTSET_CANDIDATE, L" ");
  table_layout_->EnsureCellSize(COLUMN_GAP1, gap1_size);

  bool description_found = false;

  // calculate table size.
  for (size_t i = 0; i < candidates_->candidate_size(); ++i) {
    const commands::Candidates::Candidate &candidate =
        candidates_->candidate(i);
    const wstring shortcut =
        GetDisplayStringByColumn(candidate, COLUMN_SHORTCUT);
    const wstring description =
        GetDisplayStringByColumn(candidate, COLUMN_DESCRIPTION);
    const wstring candidate_string =
        GetDisplayStringByColumn(candidate, COLUMN_CANDIDATE);

    if (!shortcut.empty()) {
      wstring text;
      text.push_back(L' ');  // put a space for padding
      text.append(shortcut);
      text.push_back(L' ');  // put a space for padding
      const Size rendering_size = text_renderer_->MeasureString(
          TextRenderer::FONTSET_SHORTCUT, text);
      table_layout_->EnsureCellSize(COLUMN_SHORTCUT, rendering_size);
    }

    if (!candidate_string.empty()) {
      wstring text;
      text.append(candidate_string);

      const Size rendering_size = text_renderer_->MeasureString(
          TextRenderer::FONTSET_CANDIDATE, text);
      table_layout_->EnsureCellSize(COLUMN_CANDIDATE, rendering_size);
    }

    if (!description.empty()) {
      wstring text;
      text.append(description);
      text.push_back(L' ');  // put a space for padding
      const Size rendering_size = text_renderer_->MeasureString(
          TextRenderer::FONTSET_DESCRIPTION, text);
      table_layout_->EnsureCellSize(COLUMN_DESCRIPTION, rendering_size);

      description_found = true;
    }
  }

  // Put a padding in COLUMN_GAP2.
  // We use wide padding if there is any description column.
  const wchar_t *gap2_string = (description_found ? L"   " : L" ");
  const Size gap2_size = text_renderer_->MeasureString(
      TextRenderer::FONTSET_CANDIDATE, gap2_string);
  table_layout_->EnsureCellSize(COLUMN_GAP2, gap2_size);

  table_layout_->FreezeLayout();
}

void CandidateWindow::SetSendCommandInterface(
  client::SendCommandInterface *send_command_interface) {
  send_command_interface_ = send_command_interface;
}

Size CandidateWindow::GetLayoutSize() const {
  DCHECK(table_layout_->IsLayoutFrozen()) << "Table layout is not frozen.";

  return table_layout_->GetTotalSize();
}

Rect CandidateWindow::GetSelectionRectInScreenCord() const {
  const int focused_array_index = GetFocusedArrayIndex(*candidates_);

  if (0 <= focused_array_index &&
      focused_array_index < candidates_->candidate_size()) {
    const commands::Candidates::Candidate &candidate =
        candidates_->candidate(focused_array_index);

    CRect rect = ToCRect(table_layout_->GetRowRect(focused_array_index));
    ClientToScreen(&rect);
    return Rect(rect.left, rect.top, rect.Width(), rect.Height());
  }

  return Rect();
}

Rect CandidateWindow::GetCandidateColumnInClientCord() const {
  DCHECK(table_layout_->IsLayoutFrozen()) << "Table layout is not frozen.";

  return table_layout_->GetCellRect(0, COLUMN_CANDIDATE);
}

Rect CandidateWindow::GetFirstRowInClientCord() const {
  DCHECK(table_layout_->IsLayoutFrozen()) << "Table layout is not frozen.";
  DCHECK_GT(table_layout_->number_of_rows(), 0)
      << "number of rows should be positive";
  return table_layout_->GetRowRect(0);
}

void CandidateWindow::DrawCells(CDCHandle dc) {
  COLUMN_TYPE kColumnTypes[] =
      {COLUMN_SHORTCUT, COLUMN_CANDIDATE, COLUMN_DESCRIPTION};
  TextRenderer::FONT_TYPE kFontTypes[] =
      {TextRenderer::FONTSET_SHORTCUT, TextRenderer::FONTSET_CANDIDATE,
       TextRenderer::FONTSET_DESCRIPTION};

  DCHECK_EQ(arraysize(kColumnTypes), arraysize(kFontTypes));
  for (size_t type_index = 0;
       type_index < arraysize(kColumnTypes); ++type_index) {
    const COLUMN_TYPE column_type = kColumnTypes[type_index];
    const TextRenderer::FONT_TYPE font_type = kFontTypes[type_index];

    vector<TextRenderingInfo> display_list;
    for (size_t i = 0; i < candidates_->candidate_size(); ++i) {
      const commands::Candidates::Candidate &candidate =
          candidates_->candidate(i);
      const wstring display_string =
          GetDisplayStringByColumn(candidate, column_type);
      const Rect text_rect =
          table_layout_->GetCellRect(i, column_type);
      display_list.push_back(TextRenderingInfo(display_string, text_rect));
    }
    text_renderer_->RenderTextList(dc, display_list, font_type);
  }
}

void CandidateWindow::DrawVScrollBar(CDCHandle dc) {
  const Rect &vscroll_rect = table_layout_->GetVScrollBarRect();

  if (!vscroll_rect.IsRectEmpty() && candidates_->candidate_size() > 0) {
    const int begin_index = candidates_->candidate(0).index();
    const int candidates_in_page = candidates_->candidate_size();
    const int candidates_total = candidates_->size();
    const int end_index =
        candidates_->candidate(candidates_in_page - 1).index();

    const CRect background_crect = ToCRect(vscroll_rect);
    dc.FillSolidRect(&background_crect, kIndicatorBackgroundColor);

    const mozc::Rect &indicator_rect =
        table_layout_->GetVScrollIndicatorRect(
            begin_index, end_index, candidates_total);

    const CRect indicator_crect = ToCRect(indicator_rect);
    dc.FillSolidRect(&indicator_crect, kIndicatorColor);
  }
}

void CandidateWindow::DrawShortcutBackground(CDCHandle dc) {
  if (table_layout_->number_of_columns() > 0) {
    Rect shortcut_colmun_rect = table_layout_->GetColumnRect(0);
    if (!shortcut_colmun_rect.IsRectEmpty()) {
      // Due to the mismatch of the implementation of the TableLayout class
      // and the design requiement, we have to *fix* the width and origin
      // of the rectangle.
      // If you remove this *fix*, an empty region appears between the
      // left window border and the colored region of the shortcut column.
      const Rect row_rect = table_layout_->GetRowRect(0);
      const int width = shortcut_colmun_rect.Right() - row_rect.Left();
      shortcut_colmun_rect.origin.x = row_rect.Left();
      shortcut_colmun_rect.size.width = width;
      const CRect shortcut_colmun_crect = ToCRect(shortcut_colmun_rect);
      dc.FillSolidRect(&shortcut_colmun_crect, kShortcutBackgroundColor);
    }
  }
}

void CandidateWindow::DrawFooter(CDCHandle dc) {
  const Rect &footer_rect = table_layout_->GetFooterRect();
  if (!candidates_->has_footer() || footer_rect.IsRectEmpty()) {
    return;
  }

  const COLORREF kFooterSeparatorColors[kFooterSeparatorHeight] = {
      kFrameColor };

  // DC pen is available in Windows 2000 and later.
  CPenHandle prev_pen(dc.SelectPen(static_cast<HPEN>(GetStockObject(DC_PEN))));
  for (size_t i = 0, y = footer_rect.Top();
       i < kFooterSeparatorHeight; y++, i++) {
    if (i < ARRAYSIZE(kFooterSeparatorColors)) {
      dc.SetDCPenColor(kFooterSeparatorColors[i]);
      dc.MoveTo(footer_rect.Left(), y, nullptr);
      dc.LineTo(footer_rect.Right(), y);
    }
  }
  dc.SelectPen(prev_pen);

  const Rect footer_content_rect(
      footer_rect.Left(),
      footer_rect.Top() + kFooterSeparatorHeight,
      footer_rect.Width(),
      footer_rect.Height() - kFooterSeparatorHeight);

  // Draw gradient rect in the footer area
  {
    TRIVERTEX vertices[] = {
      { footer_content_rect.Left(),
        footer_content_rect.Top(),
        GetRValue(kFooterTopColor) << 8,
        GetGValue(kFooterTopColor) << 8,
        GetBValue(kFooterTopColor) << 8,
        0xff00 },
      { footer_content_rect.Right(),
        footer_content_rect.Bottom(),
        GetRValue(kFooterBottomColor) << 8,
        GetGValue(kFooterBottomColor) << 8,
        GetBValue(kFooterBottomColor) << 8,
        0xff00 }
    };
    GRADIENT_RECT indices[] = { {0, 1} };
    dc.GradientFill(&vertices[0], ARRAYSIZE(vertices),
                    &indices[0],  ARRAYSIZE(indices), GRADIENT_FILL_RECT_V);
  }

  int left_used = 0;

  if (candidates_->footer().logo_visible() && !footer_logo_.IsNull()) {
    const int top_offset =
        (footer_content_rect.Height() - footer_logo_display_size_.height) / 2;
    CDC src_dc;
    src_dc.CreateCompatibleDC(dc);
    const HBITMAP old_bitmap = src_dc.SelectBitmap(footer_logo_);

    CSize src_size;
    footer_logo_.GetSize(src_size);

    // NOTE: AC_SRC_ALPHA requires PBGRA (pre-multiplied alpha) DIB.
    const BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
    dc.AlphaBlend(footer_content_rect.Left(),
                  footer_content_rect.Top() + top_offset,
                  footer_logo_display_size_.width,
                  footer_logo_display_size_.height,
                  src_dc, 0, 0, src_size.cx, src_size.cy, bf);

    src_dc.SelectBitmap(old_bitmap);
    left_used = footer_content_rect.Left() + footer_logo_display_size_.width;
  }

  int right_used = 0;
  if (candidates_->footer().index_visible()) {
    wstring index_guide_string;
    mozc::Util::UTF8ToWide(
        GetIndexGuideString(*candidates_).c_str(), &index_guide_string);
    const Size index_guide_size = text_renderer_->MeasureString(
        TextRenderer::FONTSET_FOOTER_INDEX, index_guide_string);
    const Rect index_rect(footer_content_rect.Right() - index_guide_size.width,
                          footer_content_rect.Top(),
                          index_guide_size.width,
                          footer_content_rect.Height());
    text_renderer_->RenderText(dc, index_guide_string, index_rect,
                               TextRenderer::FONTSET_FOOTER_INDEX);
    right_used = index_guide_size.width;
  }

  if (candidates_->footer().has_label()) {
    const Rect label_rect(left_used,
                          footer_content_rect.Top(),
                          footer_content_rect.Width() - left_used - right_used,
                          footer_content_rect.Height());
    wstring footer_label;
    mozc::Util::UTF8ToWide(candidates_->footer().label().c_str(),
                           &footer_label);
    text_renderer_->RenderText(dc,
                               L" " + footer_label + L" ",
                               label_rect,
                               TextRenderer::FONTSET_FOOTER_LABEL);
  } else if (candidates_->footer().has_sub_label()) {
    wstring footer_sub_label;
    mozc::Util::UTF8ToWide(candidates_->footer().sub_label().c_str(),
                     &footer_sub_label);
    const Rect label_rect(left_used,
                          footer_content_rect.Top(),
                          footer_content_rect.Width() - left_used - right_used,
                          footer_content_rect.Height());
    const wstring text = L" " + footer_sub_label + L" ";
    text_renderer_->RenderText(dc,
                               text,
                               label_rect,
                               TextRenderer::FONTSET_FOOTER_SUBLABEL);
  }
}

void CandidateWindow::DrawSelectedRect(CDCHandle dc) {
  DCHECK(table_layout_->IsLayoutFrozen()) << "Table layout is not frozen.";

  const int focused_array_index = GetFocusedArrayIndex(*candidates_);

  if (0 <= focused_array_index &&
      focused_array_index < candidates_->candidate_size()) {
    const commands::Candidates::Candidate &candidate
        = candidates_->candidate(focused_array_index);

    const CRect selected_rect =
        ToCRect(table_layout_->GetRowRect(focused_array_index));
    dc.FillSolidRect(&selected_rect, kSelectedRowBackgroundColor);

    dc.SetDCBrushColor(kSelectedRowFrameColor);
    dc.FrameRect(&selected_rect,
                 static_cast<HBRUSH>(GetStockObject(DC_BRUSH)));
  }
}

void CandidateWindow::DrawInformationIcon(CDCHandle dc) {
  DCHECK(table_layout_->IsLayoutFrozen()) << "Table layout is not frozen.";
  double scale_factor_x = 1.0;
  double scale_factor_y = 1.0;
  RendererStyleHandler::GetDPIScalingFactor(&scale_factor_x,
                                            &scale_factor_y);
  for (size_t i = 0; i < candidates_->candidate_size(); ++i) {
    if (candidates_->candidate(i).has_information_id()) {
      CRect rect = ToCRect(table_layout_->GetRowRect(i));
      rect.left = rect.right - (6.0 * scale_factor_x);
      rect.right = rect.right - (2.0 * scale_factor_x);
      rect.top += (2.0 * scale_factor_y);
      rect.bottom -= (2.0 * scale_factor_y);
      dc.FillSolidRect(&rect, kIndicatorColor);
      dc.SetDCBrushColor(kIndicatorColor);
      dc.FrameRect(&rect,
                   static_cast<HBRUSH>(GetStockObject(DC_BRUSH)));
    }
  }
}

void CandidateWindow::DrawBackground(CDCHandle dc) {
  const Rect client_rect(Point(0, 0), table_layout_->GetTotalSize());
  const CRect client_crect = ToCRect(client_rect);
  dc.FillSolidRect(&client_crect, kDefaultBackgroundColor);
}

void CandidateWindow::DrawFrame(CDCHandle dc) {
  const Rect client_rect(Point(0, 0), table_layout_->GetTotalSize());
  const CRect client_crect = ToCRect(client_rect);

  // DC brush is available in Windows 2000 and later.
  dc.SetDCBrushColor(kFrameColor);
  dc.FrameRect(&client_crect,
               static_cast<HBRUSH>(GetStockObject(DC_BRUSH)));
}

void CandidateWindow::set_mouse_moving(bool moving) {
  mouse_moving_ = moving;
}
}  // namespace win32
}  // namespace renderer
}  // namespace mozc
