// 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 "apps/moterm/key_util.h"
#include "base/logging.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/services/files/public/interfaces/file.mojom.h"
#include "mojo/services/files/public/interfaces/types.mojom.h"
#include "mojo/services/input_events/public/interfaces/input_event_constants.mojom.h"
#include "mojo/services/input_events/public/interfaces/input_events.mojom.h"
#include "mojo/services/terminal/public/interfaces/terminal_client.mojom.h"
#include "skia/ext/refptr.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"

namespace {

const GLint kTextureFormat =
    (kN32_SkColorType == kRGBA_8888_SkColorType) ? GL_RGBA : GL_BGRA_EXT;

mojo::Size RectToSize(const mojo::Rect& rect) {
  mojo::Size size;
  size.width = rect.width;
  size.height = rect.height;
  return size;
}

}  // namespace

MotermView::MotermView(
    mojo::Shell* shell,
    mojo::View* view,
    mojo::InterfaceRequest<mojo::ServiceProvider> service_provider_request)
    : view_(view),
      gl_helper_(this, shell, kTextureFormat, RectToSize(view->bounds())),
      model_(MotermModel::Size(240, 160), MotermModel::Size(24, 80)),
      frame_pending_(false),
      force_next_draw_(false),
      ascent_(0),
      line_height_(0),
      advance_width_(0) {
  // 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);

  view_->AddObserver(this);

  // Force an initial draw.
  Draw(true);
}

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

void MotermView::OnViewDestroyed(mojo::View* view) {
  DCHECK(view == view_);
  view_->RemoveObserver(this);
  delete this;
}

void MotermView::OnViewBoundsChanged(mojo::View* view,
                                     const mojo::Rect& old_bounds,
                                     const mojo::Rect& new_bounds) {
  DCHECK_EQ(view, view_);
  gl_helper_.SetSurfaceSize(RectToSize(view_->bounds()));
  bitmap_device_.clear();
  Draw(true);
}

void MotermView::OnViewInputEvent(mojo::View* view,
                                  const mojo::EventPtr& event) {
  if (event->action == mojo::EVENT_TYPE_KEY_PRESSED)
    OnKeyPressed(event);
}

void MotermView::OnSurfaceIdChanged(mojo::SurfaceIdPtr surface_id) {
  view_->SetSurfaceId(surface_id.Pass());
}

void MotermView::OnContextLost() {
  // TODO(vtl): We'll need to force a draw when we regain a context.
}

void MotermView::OnFrameDisplayed(uint32_t frame_id) {
  DCHECK(frame_pending_);
  frame_pending_ = false;
  Draw(false);
}

void MotermView::OnDataReceived(const void* bytes, size_t num_bytes) {
  model_.ProcessInput(bytes, num_bytes, &model_state_changes_);
  Draw(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::terminal::TerminalClientPtr 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::files::FilePtr file;
  driver_ = MotermDriver::Create(this, GetProxy(&file));
  terminal_client->ConnectToTerminal(file.Pass());
  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_->bounds().height) /
                                     line_height_));
  }
  if (!columns) {
    columns =
        std::max(1u, std::min(MotermModel::kMaxColumns,
                              static_cast<uint32_t>(view_->bounds().width) /
                                  advance_width_));
  }

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

  Draw(false);
}

void MotermView::Draw(bool force) {
  // TODO(vtl): See TODO above |frame_pending_| in the class declaration.
  if (frame_pending_) {
    force_next_draw_ |= force;
    return;
  }

  force |= force_next_draw_;
  force_next_draw_ = false;

  if (!force && !model_state_changes_.IsDirty())
    return;

  // TODO(vtl): If |!force|, draw only the dirty region(s)?
  model_state_changes_.Reset();

  int32_t width = view_->bounds().width;
  int32_t height = view_->bounds().height;
  DCHECK_GT(width, 0);
  DCHECK_GT(height, 0);

  if (!bitmap_device_) {
    bitmap_device_ = skia::AdoptRef(SkBitmapDevice::Create(SkImageInfo::Make(
        width, height, kN32_SkColorType, kOpaque_SkAlphaType)));
  }

  SkCanvas canvas(bitmap_device_.get());
  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);
      }
    }
  }

  // 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();

  const SkBitmap& bitmap(bitmap_device_->accessBitmap(false));
  // TODO(vtl): Do we need really need to lock/unlock pixels?
  SkAutoLockPixels pixel_locker(bitmap);

  gl_helper_.StartFrame();
  // (The texture is already bound.)
  glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, kTextureFormat,
                  GL_UNSIGNED_BYTE, bitmap.getPixels());
  gl_helper_.EndFrame();
  frame_pending_ = true;
}

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

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