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

#include "base/logging.h"
#include "base/mutex.h"
#include "renderer/renderer_command.pb.h"
#include "renderer/renderer_style.pb.h"
#include "renderer/renderer_style_handler.h"
#include "renderer/unix/cairo_wrapper.h"
#include "renderer/unix/const.h"
#include "renderer/unix/draw_tool.h"
#include "renderer/unix/font_spec.h"
#include "renderer/unix/text_renderer.h"

namespace mozc {
namespace renderer {
namespace gtk {

using mozc::commands::Candidates;
using mozc::commands::Information;
using mozc::commands::InformationList;
using mozc::commands::Output;
using mozc::commands::SessionCommand;
using mozc::renderer::RendererStyle;
using mozc::renderer::RendererStyleHandler;

namespace {
RGBA StyleColorToRGBA(const RendererStyle::RGBAColor &rgbacolor) {
  const RGBA rgba = { static_cast<uint8>(rgbacolor.r()),
                      static_cast<uint8>(rgbacolor.g()),
                      static_cast<uint8>(rgbacolor.b()),
                      0xFF };
  return rgba;
}
}  // namespace

InfolistWindow::InfolistWindow(
    TextRendererInterface *text_renderer,
    DrawToolInterface *draw_tool,
    GtkWrapperInterface *gtk,
    CairoFactoryInterface *cairo_factory)
    : GtkWindowBase(gtk),
      text_renderer_(text_renderer),
      style_(new RendererStyle()),
      draw_tool_(draw_tool),
      cairo_factory_(cairo_factory) {
  mozc::renderer::RendererStyleHandler::GetRendererStyle(style_.get());
}

Size InfolistWindow::Update(const commands::Candidates &candidates) {
  candidates_.CopyFrom(candidates);

  const RendererStyle::InfolistStyle &infostyle = style_->infolist_style();
  const InformationList &usages = candidates_.usages();

  int ypos = infostyle.window_border();
  ypos += infostyle.caption_height();

  for (int i = 0; i < usages.information_size(); ++i) {
    ypos += GetRowRects(i, ypos).whole_rect.Height();
  }
  ypos += infostyle.window_border();

  const Size result_size(style_->infolist_style().window_width(), ypos);
  Resize(result_size);
  Redraw();
  return result_size;
}

// We do not use this function. So following code makes no sense.
Rect InfolistWindow::GetCandidateColumnInClientCord() const {
  DCHECK(false) << "Do not call this function without CandidateWindow.";
  return Rect(0, 0, 0, 0);
}

bool InfolistWindow::OnPaint(GtkWidget *widget, GdkEventExpose *event) {
  draw_tool_->Reset(cairo_factory_->CreateCairoInstance(
      GetCanvasWidget()->window));
  Draw();
  return true;
}

int InfolistWindow::DrawCaption() {
  const RendererStyle::InfolistStyle &infostyle = style_->infolist_style();
  if (!infostyle.has_caption_string()) {
    return 0;
  }
  const RendererStyle::TextStyle &caption_style = infostyle.caption_style();
  const int caption_height = infostyle.caption_height();
  const Rect background_rect(
      infostyle.window_border(),
      infostyle.window_border(),
      infostyle.window_width() - infostyle.window_border() * 2,
      caption_height);

  const RGBA bgcolor = StyleColorToRGBA(infostyle.caption_background_color());
  draw_tool_->FillRect(background_rect, bgcolor);

  const Rect caption_rect(
      background_rect.Left()
          + infostyle.caption_padding() + caption_style.left_padding(),
      background_rect.Top() + infostyle.caption_padding(),
      background_rect.Width()
          - infostyle.caption_padding() - caption_style.left_padding(),
      caption_height - infostyle.caption_padding());
  text_renderer_->RenderText(infostyle.caption_string(), caption_rect,
                             FontSpec::FONTSET_INFOLIST_CAPTION);
  return infostyle.caption_height();
}

void InfolistWindow::DrawFrame(int height) {
  const RendererStyle::InfolistStyle &infostyle = style_->infolist_style();
  const Rect rect(0, 0, infostyle.window_width(), height);
  const RGBA framecolor = StyleColorToRGBA(infostyle.border_color());
  draw_tool_->FrameRect(rect, framecolor, 1);
}

void InfolistWindow::Draw() {
  const RendererStyle::InfolistStyle &infostyle = style_->infolist_style();
  const InformationList &usages = candidates_.usages();
  int ypos = infostyle.window_border();
  ypos += DrawCaption();
  for (int i = 0; i < usages.information_size(); ++i) {
    ypos += DrawRow(i, ypos);
  }
  DrawFrame(ypos);
}

void InfolistWindow::GetRenderingRects(
    const renderer::RendererStyle::TextStyle &style,
    const string &text,
    FontSpec::FONT_TYPE font_type,
    int top,
    Rect *background_rect,
    Rect *textarea_rect) {
  const RendererStyle::InfolistStyle &infostyle = style_->infolist_style();
  const int text_width = infostyle.window_width()
      - style.left_padding() - style.right_padding()
      - infostyle.window_border() * 2 - infostyle.row_rect_padding() * 2;

  const Size text_size = text_renderer_->GetMultiLinePixelSize(font_type,
                                                               text,
                                                               text_width);

  background_rect->origin.x = infostyle.window_border();
  background_rect->origin.y = top;
  background_rect->size.width =
      infostyle.window_width() - infostyle.window_border() * 2;
  background_rect->size.height =
      text_size.height + infostyle.row_rect_padding() * 2;

  *textarea_rect = *background_rect;

  textarea_rect->origin.x +=
      infostyle.row_rect_padding() + style.left_padding();
  textarea_rect->origin.y += infostyle.row_rect_padding();
  textarea_rect->size.width = text_width;
  textarea_rect->size.height = text_size.height;
}

InfolistWindow::RenderingRowRects InfolistWindow::GetRowRects(int row,
                                                              int ypos) {
  const RendererStyle::InfolistStyle &infostyle = style_->infolist_style();
  const InformationList &usages = candidates_.usages();
  const RendererStyle::TextStyle &title_style = infostyle.title_style();
  const RendererStyle::TextStyle &desc_style = infostyle.description_style();
  DCHECK_GT(usages.information_size(), row);
  const Information &info = usages.information(row);

  RenderingRowRects result;

  GetRenderingRects(title_style,
                    info.title(),
                    FontSpec::FONTSET_INFOLIST_TITLE,
                    ypos,
                    &result.title_back_rect,
                    &result.title_rect);
  ypos += result.title_back_rect.size.height;
  GetRenderingRects(desc_style,
                    info.description(),
                    FontSpec::FONTSET_INFOLIST_DESCRIPTION,
                    ypos,
                    &result.desc_back_rect,
                    &result.desc_rect);
  result.whole_rect = result.title_back_rect;
  result.whole_rect.size.height += result.desc_back_rect.Height();
  return result;
}

int InfolistWindow::DrawRow(int row, int ypos) {
  const RendererStyle::InfolistStyle &infostyle = style_->infolist_style();
  const InformationList &usages = candidates_.usages();
  const RendererStyle::TextStyle &title_style = infostyle.title_style();
  const RendererStyle::TextStyle &desc_style = infostyle.description_style();
  DCHECK_GT(usages.information_size(), row);
  const Information &info = usages.information(row);
  const RenderingRowRects row_rects = GetRowRects(row, ypos);

  if (usages.has_focused_index() && (row == usages.focused_index())) {
    const RGBA bgcol = StyleColorToRGBA(infostyle.focused_background_color());
    draw_tool_->FillRect(row_rects.whole_rect, bgcol);

    const RGBA frcol = StyleColorToRGBA(infostyle.focused_border_color());
    draw_tool_->FrameRect(row_rects.whole_rect, frcol, 1);
  } else {
    if (title_style.has_background_color()) {
      draw_tool_->FillRect(row_rects.title_back_rect,
                           StyleColorToRGBA(title_style.background_color()));
    } else {
      draw_tool_->FillRect(row_rects.title_back_rect, kWhite);
    }
    if (desc_style.has_background_color()) {
      draw_tool_->FillRect(row_rects.desc_back_rect,
                           StyleColorToRGBA(desc_style.background_color()));
    } else {
      draw_tool_->FillRect(row_rects.desc_back_rect, kWhite);
    }
  }

  text_renderer_->RenderText(info.title(), row_rects.title_rect,
                             FontSpec::FONTSET_INFOLIST_TITLE);
  text_renderer_->RenderText(info.description(), row_rects.desc_rect,
                             FontSpec::FONTSET_INFOLIST_DESCRIPTION);
  return row_rects.whole_rect.Height();
}

void InfolistWindow::Initialize() {
  text_renderer_->Initialize(GetCanvasWidget()->window);
}

void InfolistWindow::ReloadFontConfig(const string &font_description) {
  text_renderer_->ReloadFontConfig(font_description);
}

}  // namespace gtk
}  // namespace renderer
}  // namespace mozc
