// 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/interfaces/file.mojom.h"
#include "mojo/services/files/interfaces/types.mojom.h"
#include "mojo/services/input_events/interfaces/input_event_constants.mojom.h"
#include "mojo/services/input_events/interfaces/input_events.mojom.h"
#include "mojo/services/terminal/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,
                 false,
                 RectToSize(view->bounds())),
      model_(MotermModel::Size(240, 160), MotermModel::Size(24, 80), this),
      frame_pending_(false),
      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);

  view_->AddObserver(this);

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

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

void MotermView::OnViewDestroyed(mojo::View* view) {
  DCHECK_EQ(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::EventType::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::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_);
  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);
      }
    }
  }

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

  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, keypad_application_mode_);
  if (input_sequence.empty())
    return;

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