// 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 <math.h>

#include "services/keyboard_native/view_observer_delegate.h"

#include "base/bind.h"
#include "base/sys_info.h"
#include "mojo/public/cpp/application/application_impl.h"
#include "mojo/skia/ganesh_surface.h"
#include "services/keyboard_native/clip_animation.h"
#include "services/keyboard_native/keyboard_service_impl.h"
#include "skia/ext/refptr.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkTypeface.h"

namespace keyboard {

static const base::TimeDelta kAnimationDurationMs =
    base::TimeDelta::FromMilliseconds(1000);

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

ViewObserverDelegate::ViewObserverDelegate()
    : keyboard_service_impl_(nullptr),
      view_(nullptr),
      key_layout_(),
      needs_draw_(false),
      frame_pending_(false),
      weak_factory_(this) {
  key_layout_.SetTextCallback(
      base::Bind(&ViewObserverDelegate::OnText, weak_factory_.GetWeakPtr()));
  key_layout_.SetDeleteCallback(
      base::Bind(&ViewObserverDelegate::OnDelete, weak_factory_.GetWeakPtr()));
}

ViewObserverDelegate::~ViewObserverDelegate() {
}

void ViewObserverDelegate::SetKeyboardServiceImpl(
    KeyboardServiceImpl* keyboard_service_impl) {
  keyboard_service_impl_ = keyboard_service_impl;
}

void ViewObserverDelegate::OnViewCreated(mojo::View* view, mojo::Shell* shell) {
  if (view_ != nullptr) {
    view_->RemoveObserver(this);
  }
  view_ = view;
  view_->AddObserver(this);
  gl_context_ = mojo::GLContext::Create(shell);
  gr_context_.reset(new mojo::GaneshContext(gl_context_));
  texture_uploader_.reset(new mojo::TextureUploader(this, shell, gl_context_));

  IssueDraw();
}

void ViewObserverDelegate::OnText(const std::string& text) {
  keyboard_service_impl_->OnKey(text.c_str());
}

void ViewObserverDelegate::OnDelete() {
  keyboard_service_impl_->OnDelete();
}

void ViewObserverDelegate::UpdateState(int32 pointer_id,
                                       int action,
                                       const gfx::Point& touch_point) {
  base::TimeTicks current_ticks = base::TimeTicks::Now();

  auto it2 = active_pointer_state_.find(pointer_id);
  if (it2 != active_pointer_state_.end()) {
    if (it2->second->last_point_valid) {
      animations_.push_back(make_scoped_ptr(
          new MotionDecayAnimation(current_ticks, kAnimationDurationMs,
                                   it2->second->last_point, touch_point)));
      it2->second->last_point = touch_point;
    } else {
      it2->second->last_point = touch_point;
    }
    it2->second->last_point_valid = action != mojo::EVENT_TYPE_POINTER_UP;
  }

  if (action == mojo::EVENT_TYPE_POINTER_UP ||
      action == mojo::EVENT_TYPE_POINTER_DOWN) {
    animations_.push_back(make_scoped_ptr(new MaterialSplashAnimation(
        current_ticks, kAnimationDurationMs, touch_point)));
  }
}

// mojo::TextureUploader::Client implementation.
void ViewObserverDelegate::OnSurfaceIdAvailable(mojo::SurfaceIdPtr surface_id) {
  view_->SetSurfaceId(surface_id.Pass());
}

void ViewObserverDelegate::DrawKeysToCanvas(const mojo::Size& size,
                                            SkCanvas* canvas) {
  key_layout_.SetSize(size);
  key_layout_.Draw(canvas);
}

void ViewObserverDelegate::DrawState() {
  base::TimeTicks current_ticks = base::TimeTicks::Now();
  mojo::Size size = ToSize(view_->bounds());
  mojo::GaneshContext::Scope scope(gr_context_.get());
  mojo::GaneshSurface surface(
      gr_context_.get(),
      make_scoped_ptr(new mojo::GLTexture(gl_context_, size)));

  gr_context_.get()->gr()->resetContext(kTextureBinding_GrGLBackendState);

  SkCanvas* canvas = surface.canvas();

  // If we have a clip animation it must go first as only things drawn after the
  // clip is set will be clipped.
  if (clip_animation_) {
    if (!clip_animation_->IsDone(current_ticks)) {
      clip_animation_->Draw(canvas, current_ticks);
    } else {
      clip_animation_.reset();
    }
  }
  DrawKeysToCanvas(size, canvas);
  DrawAnimations(canvas, current_ticks);
  DrawFloatingKey(canvas, size);

  canvas->flush();
  texture_uploader_->Upload(surface.TakeTexture());
}

void ViewObserverDelegate::DrawAnimations(
    SkCanvas* canvas,
    const base::TimeTicks& current_ticks) {
  auto first_valid_animation = animations_.end();
  for (auto it = animations_.begin(); it != animations_.end(); ++it) {
    bool done = (*it)->IsDone(current_ticks);
    if (!done) {
      (*it)->Draw(canvas, current_ticks);
      if (first_valid_animation == animations_.end()) {
        first_valid_animation = it;
      }
    }
  }

  // Clean up 'done' animations.
  animations_.erase(animations_.begin(), first_valid_animation);
}

void ViewObserverDelegate::DrawFloatingKey(SkCanvas* canvas,
                                           const mojo::Size& size) {
  if (active_pointer_ids_.empty()) {
    return;
  }

  for (auto& pointer_state : active_pointer_state_) {
    if (pointer_state.second->last_key != nullptr &&
        pointer_state.second->last_point_valid) {
      SkPaint paint;
      paint.setColor(SK_ColorYELLOW);
      float row_height = static_cast<float>(size.height) / 4.0f;
      float floating_key_width = static_cast<float>(size.width) / 7.0f;
      float left =
          pointer_state.second->last_point.x() - (floating_key_width / 2);
      float top = pointer_state.second->last_point.y() - (1.5f * row_height);
      SkRect rect = SkRect::MakeLTRB(left, top, left + floating_key_width,
                                     top + row_height);
      canvas->drawRect(rect, paint);

      skia::RefPtr<SkTypeface> typeface = skia::AdoptRef(
          SkTypeface::CreateFromName("Arial", SkTypeface::kNormal));
      SkPaint text_paint;
      text_paint.setTypeface(typeface.get());
      text_paint.setColor(SK_ColorBLACK);
      text_paint.setTextSize(row_height / 1.7f);
      text_paint.setAntiAlias(true);
      text_paint.setTextAlign(SkPaint::kCenter_Align);
      pointer_state.second->last_key->Draw(
          canvas, text_paint,
          gfx::RectF(left, top, floating_key_width, row_height));
    }
  }
}

void ViewObserverDelegate::IssueDraw() {
  if (!frame_pending_) {
    DrawState();
    frame_pending_ = true;
    needs_draw_ = !animations_.empty() || clip_animation_;
  } else {
    needs_draw_ = true;
  }
}

void ViewObserverDelegate::OnFrameComplete() {
  frame_pending_ = false;
  if (needs_draw_) {
    IssueDraw();
  }
}

// mojo::ViewObserver implementation.
void ViewObserverDelegate::OnViewBoundsChanged(mojo::View* view,
                                               const mojo::Rect& old_bounds,
                                               const mojo::Rect& new_bounds) {
  // Upon resize, kick off a clip animation centered on our new bounds with a
  // radius equal to the length from a corner of to the center of the new
  // bounds.
  base::TimeTicks current_ticks = base::TimeTicks::Now();
  gfx::Point center(new_bounds.width / 2.0f, new_bounds.height / 2.0f);
  float radius = sqrt(new_bounds.width / 2.0f * new_bounds.width / 2.0f +
                      new_bounds.height / 2.0f * new_bounds.height / 2.0f);
  clip_animation_.reset(
      new ClipAnimation(current_ticks, kAnimationDurationMs, center, radius));

  IssueDraw();
}

void ViewObserverDelegate::OnViewInputEvent(mojo::View* view,
                                            const mojo::EventPtr& event) {
  if (event->pointer_data) {
    gfx::Point point(event->pointer_data->x, event->pointer_data->y);

    if (event->action == mojo::EVENT_TYPE_POINTER_UP) {
      key_layout_.OnTouchUp(point);
    }

    if (event->action == mojo::EVENT_TYPE_POINTER_DOWN ||
        event->action == mojo::EVENT_TYPE_POINTER_UP) {
      auto it =
          std::find(active_pointer_ids_.begin(), active_pointer_ids_.end(),
                    event->pointer_data->pointer_id);
      if (it != active_pointer_ids_.end()) {
        active_pointer_ids_.erase(it);
      }

      auto it2 = active_pointer_state_.find(event->pointer_data->pointer_id);
      if (it2 != active_pointer_state_.end()) {
        active_pointer_state_.erase(it2);
      }
      if (event->action == mojo::EVENT_TYPE_POINTER_DOWN) {
        active_pointer_ids_.push_back(event->pointer_data->pointer_id);
        PointerState* pointer_state = new PointerState();
        pointer_state->last_key = nullptr;
        pointer_state->last_point = gfx::Point();
        pointer_state->last_point_valid = false;
        active_pointer_state_[event->pointer_data->pointer_id] =
            make_scoped_ptr(pointer_state);
      }
    }

    auto it2 = active_pointer_state_.find(event->pointer_data->pointer_id);
    if (it2 != active_pointer_state_.end()) {
      active_pointer_state_[event->pointer_data->pointer_id]->last_key =
          key_layout_.GetKeyAtPoint(point);
    }

    UpdateState(event->pointer_data->pointer_id, event->action, point);
    IssueDraw();
  }
}

void ViewObserverDelegate::OnViewDestroyed(mojo::View* view) {
  if (view_ == view) {
    view_->RemoveObserver(this);
    view_ = nullptr;
    gl_context_->Destroy();
  }
}

}  // namespace keyboard
