// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "apps/moterm/moterm_view.h"

#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES
#endif

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include <algorithm>
#include <string>
#include <utility>

#include "apps/moterm/key_util.h"
#include "base/bind.h"
#include "base/logging.h"
#include "mojo/public/cpp/application/connect.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/services/files/interfaces/file.mojom.h"
#include "mojo/services/files/interfaces/types.mojom.h"
#include "mojo/services/terminal/interfaces/terminal_client.mojom.h"
#include "mojo/skia/ganesh_texture_surface.h"
#include "third_party/dejavu-fonts-ttf-2.34/kDejaVuSansMonoRegular.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkXfermode.h"

constexpr uint32_t kMotermImageResourceId = 1;
constexpr uint32_t kRootNodeId = mojo::gfx::composition::kSceneRootNodeId;

MotermView::MotermView(
    mojo::ApplicationImpl* app_impl,
    mojo::InterfaceRequest<mojo::ui::ViewOwner> view_owner_request,
    mojo::InterfaceRequest<mojo::ServiceProvider> service_provider_request)
    : GaneshView(app_impl, view_owner_request.Pass(), "Moterm"),
      choreographer_(scene(), this),
      input_handler_(view_service_provider(), this),
      model_(MotermModel::Size(240, 160), MotermModel::Size(24, 80), this),
      force_next_draw_(false),
      ascent_(0),
      line_height_(0),
      advance_width_(0),
      keypad_application_mode_(false) {
  // TODO(vtl): |service_provider_impl_|'s ctor doesn't like an invalid request,
  // so we have to conditionally, explicitly bind.
  if (service_provider_request.is_pending()) {
    service_provider_impl_.Bind(service_provider_request.Pass());
    service_provider_impl_.AddService<mojo::terminal::Terminal>(this);
  }

  regular_typeface_ = skia::AdoptRef(SkTypeface::CreateFromStream(
      new SkMemoryStream(font_data::kDejaVuSansMonoRegular.data,
                         font_data::kDejaVuSansMonoRegular.size)));

  // TODO(vtl): This duplicates some code.
  SkPaint fg_paint;
  fg_paint.setTypeface(regular_typeface_.get());
  fg_paint.setTextSize(16);
  // Figure out appropriate metrics.
  SkPaint::FontMetrics fm = {};
  fg_paint.getFontMetrics(&fm);
  ascent_ = static_cast<int>(ceilf(-fm.fAscent));
  line_height_ = ascent_ + static_cast<int>(ceilf(fm.fDescent + fm.fLeading));
  DCHECK_GT(line_height_, 0);
  // To figure out the advance width, measure an X. Better hope the font is
  // monospace.
  advance_width_ = static_cast<int>(ceilf(fg_paint.measureText("X", 1)));
  DCHECK_GT(advance_width_, 0);
}

MotermView::~MotermView() {
  if (driver_)
    driver_->Detach();
}

void MotermView::OnLayout(mojo::ui::ViewLayoutParamsPtr layout_params,
                          mojo::Array<uint32_t> children_needing_layout,
                          const OnLayoutCallback& callback) {
  view_size_.width = layout_params->constraints->max_width;
  view_size_.height = layout_params->constraints->max_height;

  ScheduleDraw(true);

  auto info = mojo::ui::ViewLayoutResult::New();
  info->size = view_size_.Clone();
  callback.Run(info.Pass());
}

void MotermView::OnEvent(mojo::EventPtr event,
                         const OnEventCallback& callback) {
  if (event->action == mojo::EventType::KEY_PRESSED) {
    OnKeyPressed(event.Pass());
    callback.Run(true);
  } else {
    callback.Run(false);
  }
}

void MotermView::OnResponse(const void* buf, size_t size) {
  if (driver_)
    driver_->SendData(buf, size);
}

void MotermView::OnSetKeypadMode(bool application_mode) {
  keypad_application_mode_ = application_mode;
}

void MotermView::OnDataReceived(const void* bytes, size_t num_bytes) {
  model_.ProcessInput(bytes, num_bytes, &model_state_changes_);
  ScheduleDraw(false);
}

void MotermView::OnClosed() {
  DCHECK(driver_);
  driver_->Detach();
  driver_.reset();

  OnDestroyed();
}

void MotermView::OnDestroyed() {
  DCHECK(!driver_);
  if (!on_closed_callback_.is_null()) {
    mojo::Closure callback;
    std::swap(callback, on_closed_callback_);
    callback.Run();
  }
}

void MotermView::Create(
    mojo::ApplicationConnection* connection,
    mojo::InterfaceRequest<mojo::terminal::Terminal> request) {
  terminal_bindings_.AddBinding(this, request.Pass());
}

void MotermView::Connect(
    mojo::InterfaceRequest<mojo::files::File> terminal_file,
    bool force,
    const ConnectCallback& callback) {
  if (driver_) {
    // We already have a connection.
    if (force) {
      OnClosed();
    } else {
      // TODO(vtl): Is this error code right?
      callback.Run(mojo::files::Error::UNAVAILABLE);
      return;
    }
  }

  driver_ = MotermDriver::Create(this, terminal_file.Pass());
  DCHECK(on_closed_callback_.is_null());
  on_closed_callback_ = [callback] { callback.Run(mojo::files::Error::OK); };
}

void MotermView::ConnectToClient(
    mojo::InterfaceHandle<mojo::terminal::TerminalClient> terminal_client,
    bool force,
    const ConnectToClientCallback& callback) {
  if (driver_) {
    // We already have a connection.
    if (force) {
      OnClosed();
    } else {
      // TODO(vtl): Is this error code right?
      callback.Run(mojo::files::Error::UNAVAILABLE);
      return;
    }
  }

  mojo::InterfaceHandle<mojo::files::File> file;
  driver_ = MotermDriver::Create(this, GetProxy(&file));
  mojo::terminal::TerminalClientPtr::Create(std::move(terminal_client))
      ->ConnectToTerminal(std::move(file));
  DCHECK(on_closed_callback_.is_null());
  on_closed_callback_ = [callback] { callback.Run(mojo::files::Error::OK); };
}

void MotermView::GetSize(const GetSizeCallback& callback) {
  MotermModel::Size size = model_.GetSize();
  callback.Run(mojo::files::Error::OK, size.rows, size.columns);
}

void MotermView::SetSize(uint32_t rows,
                         uint32_t columns,
                         bool reset,
                         const SetSizeCallback& callback) {
  if (!rows) {
    rows = std::max(
        1u, std::min(MotermModel::kMaxRows,
                     static_cast<uint32_t>(view_size_.height) / line_height_));
  }
  if (!columns) {
    columns = std::max(
        1u, std::min(MotermModel::kMaxColumns,
                     static_cast<uint32_t>(view_size_.width) / advance_width_));
  }

  model_.SetSize(MotermModel::Size(rows, columns), reset);
  callback.Run(mojo::files::Error::OK, rows, columns);

  ScheduleDraw(false);
}

void MotermView::ScheduleDraw(bool force) {
  if (view_size_.width == 0 || view_size_.height == 0 ||
      (!model_state_changes_.IsDirty() && !force && !force_next_draw_)) {
    force_next_draw_ |= force;
    return;
  }
  force_next_draw_ = false;
  choreographer_.ScheduleDraw();
}

void MotermView::OnDraw(const mojo::gfx::composition::FrameInfo& frame_info,
                        const base::TimeDelta& time_delta) {
  // TODO(vtl): Draw only the dirty region(s)?
  model_state_changes_.Reset();

  mojo::RectF bounds;
  bounds.width = view_size_.width;
  bounds.height = view_size_.height;

  auto update = mojo::gfx::composition::SceneUpdate::New();
  mojo::gfx::composition::ResourcePtr moterm_resource =
      ganesh_renderer()->DrawCanvas(
          view_size_,
          base::Bind(&MotermView::DrawContent, base::Unretained(this)));
  DCHECK(moterm_resource);
  update->resources.insert(kMotermImageResourceId, moterm_resource.Pass());

  auto root_node = mojo::gfx::composition::Node::New();
  root_node->hit_test_behavior = mojo::gfx::composition::HitTestBehavior::New();
  root_node->op = mojo::gfx::composition::NodeOp::New();
  root_node->op->set_image(mojo::gfx::composition::ImageNodeOp::New());
  root_node->op->get_image()->content_rect = bounds.Clone();
  root_node->op->get_image()->image_resource_id = kMotermImageResourceId;
  update->nodes.insert(kRootNodeId, root_node.Pass());

  auto metadata = mojo::gfx::composition::SceneMetadata::New();
  metadata->presentation_time = frame_info.presentation_time;

  scene()->Update(update.Pass());
  scene()->Publish(metadata.Pass());
}

void MotermView::DrawContent(SkCanvas* canvas) {
  canvas->clear(SK_ColorBLACK);

  SkPaint bg_paint;
  bg_paint.setStyle(SkPaint::kFill_Style);

  SkPaint fg_paint;
  fg_paint.setTypeface(regular_typeface_.get());
  fg_paint.setTextSize(16);
  fg_paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);

  MotermModel::Size size = model_.GetSize();
  int y = 0;
  for (unsigned i = 0; i < size.rows; i++, y += line_height_) {
    int x = 0;
    for (unsigned j = 0; j < size.columns; j++, x += advance_width_) {
      MotermModel::CharacterInfo ch =
          model_.GetCharacterInfoAt(MotermModel::Position(i, j));

      // Paint the background.
      bg_paint.setColor(SkColorSetRGB(ch.background_color.red,
                                      ch.background_color.green,
                                      ch.background_color.blue));
      canvas->drawRect(SkRect::MakeXYWH(x, y, advance_width_, line_height_),
                       bg_paint);

      // Paint the foreground.
      if (ch.code_point) {
        uint32_t flags = SkPaint::kAntiAlias_Flag;
        // TODO(vtl): Use real bold font?
        if ((ch.attributes & MotermModel::kAttributesBold))
          flags |= SkPaint::kFakeBoldText_Flag;
        if ((ch.attributes & MotermModel::kAttributesUnderline))
          flags |= SkPaint::kUnderlineText_Flag;
        // TODO(vtl): Handle blink, because that's awesome.
        fg_paint.setFlags(flags);
        fg_paint.setColor(SkColorSetRGB(ch.foreground_color.red,
                                        ch.foreground_color.green,
                                        ch.foreground_color.blue));

        canvas->drawText(&ch.code_point, sizeof(ch.code_point), x, y + ascent_,
                         fg_paint);
      }
    }
  }

  if (model_.GetCursorVisibility()) {
    // Draw the cursor.
    MotermModel::Position cursor_pos = model_.GetCursorPosition();
    // Reuse the background paint, but don't just paint over.
    // TODO(vtl): Consider doing other things. Maybe make it blink, to be extra
    // annoying.
    // TODO(vtl): Maybe vary how we draw the cursor, depending on if we're
    // focused and/or active.
    bg_paint.setColor(SK_ColorWHITE);
    bg_paint.setXfermodeMode(SkXfermode::kDifference_Mode);
    canvas->drawRect(SkRect::MakeXYWH(cursor_pos.column * advance_width_,
                                      cursor_pos.row * line_height_,
                                      advance_width_, line_height_),
                     bg_paint);
  }
  canvas->flush();
}

void MotermView::OnKeyPressed(mojo::EventPtr key_event) {
  std::string input_sequence =
      GetInputSequenceForKeyPressedEvent(*key_event, keypad_application_mode_);
  if (input_sequence.empty())
    return;

  if (driver_)
    driver_->SendData(input_sequence.data(), input_sequence.size());
}
