// 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 "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "mojo/tools/embed/data.h"
#include "services/keyboard_native/kActionIcon.h"
#include "services/keyboard_native/kDeleteIcon.h"
#include "services/keyboard_native/kLowerCaseIcon.h"
#include "services/keyboard_native/kUpperCaseIcon.h"
#include "services/keyboard_native/key_layout.h"
#include "skia/ext/refptr.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkImageDecoder.h"
#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/skia_util.h"

namespace keyboard {

// An implementation of Key that draws itself as ASCII text.
class KeyLayout::TextKey : public Key {
 public:
  TextKey(const char* text,
          base::Callback<void(const TextKey&)> touch_up_callback)
      : text_(text), touch_up_callback_(touch_up_callback) {}

  ~TextKey() override {}

  void Draw(SkCanvas* canvas,
            const SkPaint& paint,
            const gfx::RectF& rect) override {
    float text_baseline_offset = rect.height() / 5.0f;
    canvas->drawText(text_, strlen(text_), rect.x() + (rect.width() / 2.0f),
                     rect.y() + rect.height() - text_baseline_offset, paint);
  }

  const char* ToText() const override { return text_; }

  void OnTouchUp() override { touch_up_callback_.Run(*this); }

 private:
  const char* text_;
  base::Callback<void(const TextKey&)> touch_up_callback_;

  DISALLOW_COPY_AND_ASSIGN(TextKey);
};

// An implementation of Key that draws itself as an image.
class ImageKey : public KeyLayout::Key {
 public:
  ImageKey(const char* text,
           base::Callback<void(const KeyLayout::TextKey&)> touch_up_callback,
           const mojo::embed::Data& data)
      : text_key_(text, touch_up_callback), bitmap_valid_(false), bitmap_() {
    bool result = gfx::PNGCodec::Decode(
        reinterpret_cast<const unsigned char*>(data.data), data.size, &bitmap_);
    bitmap_valid_ = result && bitmap_.width() > 0 && bitmap_.height() > 0;
    DCHECK(bitmap_valid_);
  }
  ~ImageKey() override {}

  // Key implementation.
  void Draw(SkCanvas* canvas,
            const SkPaint& paint,
            const gfx::RectF& rect) override {
    // If our bitmap is somehow invalid, default to drawing the text of the key.
    if (!bitmap_valid_) {
      text_key_.Draw(canvas, paint, rect);
      return;
    }

    float width_scale = rect.width() / bitmap_.width();
    float height_scale = rect.height() / bitmap_.height();
    float scale = width_scale > height_scale ? height_scale : width_scale;
    float target_width = bitmap_.width() * scale;
    float target_height = bitmap_.height() * scale;
    float delta_width = rect.width() - target_width;
    float target_x = rect.x() + (delta_width / 2.0f);
    float delta_height = rect.height() - target_height;
    float target_y = rect.y() + (delta_height / 2.0f);
    canvas->drawBitmapRect(
        bitmap_,
        SkRect::MakeXYWH(target_x, target_y, target_width, target_height),
        &paint);
  }
  const char* ToText() const override { return text_key_.ToText(); }
  void OnTouchUp() override { text_key_.OnTouchUp(); }

 private:
  KeyLayout::TextKey text_key_;
  bool bitmap_valid_;
  SkBitmap bitmap_;

  DISALLOW_COPY_AND_ASSIGN(ImageKey);
};

KeyLayout::KeyLayout()
    : on_text_callback_(),
      layout_(&letters_layout_),
      key_map_(&lower_case_key_map_),
      weak_factory_(this) {
  InitLayouts();
  InitKeyMaps();
}

KeyLayout::~KeyLayout() {
  for (auto& row : lower_case_key_map_) {
    for (auto& key : row) {
      delete key;
    }
  }
  for (auto& row : upper_case_key_map_) {
    for (auto& key : row) {
      delete key;
    }
  }
  for (auto& row : symbols_key_map_) {
    for (auto& key : row) {
      delete key;
    }
  }
}

void KeyLayout::SetTextCallback(
    base::Callback<void(const std::string&)> on_text_callback) {
  on_text_callback_ = on_text_callback;
}

void KeyLayout::SetDeleteCallback(base::Callback<void()> on_delete_callback) {
  on_delete_callback_ = on_delete_callback;
}

void KeyLayout::SetKeyArea(const gfx::RectF& key_area) {
  key_area_ = key_area;
}

void KeyLayout::Draw(SkCanvas* canvas) {
  float row_height = key_area_.height() / static_cast<float>(layout_->size());

  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 / 2);
  text_paint.setAntiAlias(true);
  text_paint.setTextAlign(SkPaint::kCenter_Align);

  SkPaint background_paint;
  background_paint.setColor(SK_ColorLTGRAY);
  canvas->drawRect(RectFToSkRect(key_area_), background_paint);

  SkPaint paint;
  for (size_t row_index = 0; row_index < layout_->size(); row_index++) {
    float current_top = key_area_.y() + row_index * row_height;
    float current_left = key_area_.x();
    for (size_t key_index = 0; key_index < (*layout_)[row_index].size();
         key_index++) {
      float key_width = static_cast<float>(key_area_.width()) *
                        (*layout_)[row_index][key_index];

      (*key_map_)[row_index][key_index]->Draw(
          canvas, text_paint,
          gfx::RectF(current_left, current_top, key_width, row_height));
      current_left += key_width;
    }
  }
}

KeyLayout::Key* KeyLayout::GetKeyAtPoint(const gfx::PointF& point) {
  if (!key_area_.Contains(point)) {
    return nullptr;
  }

  int row_index =
      (point.y() - key_area_.y()) / (key_area_.height() / layout_->size());
  float width_percent = static_cast<float>(point.x() - key_area_.x()) /
                        static_cast<float>(key_area_.width());

  int key_index = 0;
  while (width_percent >= (*layout_)[row_index][key_index]) {
    width_percent -= (*layout_)[row_index][key_index];
    key_index++;
  }
  return (*key_map_)[row_index][key_index];
}

void KeyLayout::OnTouchUp(const gfx::PointF& touch_up) {
  Key* key = GetKeyAtPoint(touch_up);
  if (key != nullptr) {
    key->OnTouchUp();
  }
}

void KeyLayout::InitLayouts() {
  // Row layouts are specified by a vector of floats which indicate the percent
  // width a given key takes up in that row.  The floats of a given row *MUST*
  // add up to 1.
  std::vector<float> ten_key_row_layout = {
      0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f};
  std::vector<float> nine_key_row_layout = {
      0.15f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.15f};
  std::vector<float> seven_key_row_layout = {
      0.15f, 0.1f, 0.1f, 0.3f, 0.1f, 0.1f, 0.15f};
  std::vector<float> five_key_row_layout = {0.15f, 0.1f, 0.5f, 0.1f, 0.15f};

  letters_layout_.push_back(ten_key_row_layout);
  letters_layout_.push_back(nine_key_row_layout);
  letters_layout_.push_back(nine_key_row_layout);
  letters_layout_.push_back(five_key_row_layout);

  symbols_layout_.push_back(ten_key_row_layout);
  symbols_layout_.push_back(nine_key_row_layout);
  symbols_layout_.push_back(nine_key_row_layout);
  symbols_layout_.push_back(seven_key_row_layout);
}

void KeyLayout::OnKeyDoNothing(const TextKey& key) {
  // do nothing
}

void KeyLayout::OnKeyEmitText(const TextKey& key) {
  on_text_callback_.Run(std::string(key.ToText()));
}

void KeyLayout::OnKeyDelete(const TextKey& key) {
  on_delete_callback_.Run();
}

void KeyLayout::OnKeySwitchToUpperCase(const TextKey& key) {
  layout_ = &letters_layout_;
  key_map_ = &upper_case_key_map_;
}

void KeyLayout::OnKeySwitchToLowerCase(const TextKey& key) {
  layout_ = &letters_layout_;
  key_map_ = &lower_case_key_map_;
}

void KeyLayout::OnKeySwitchToSymbols(const TextKey& key) {
  layout_ = &symbols_layout_;
  key_map_ = &symbols_key_map_;
}

void KeyLayout::InitKeyMaps() {
  base::Callback<void(const TextKey&)> do_nothing_callback =
      base::Bind(&KeyLayout::OnKeyDoNothing, weak_factory_.GetWeakPtr());
  base::Callback<void(const TextKey&)> emit_text_callback =
      base::Bind(&KeyLayout::OnKeyEmitText, weak_factory_.GetWeakPtr());
  base::Callback<void(const TextKey&)> delete_callback =
      base::Bind(&KeyLayout::OnKeyDelete, weak_factory_.GetWeakPtr());
  base::Callback<void(const TextKey&)> switch_to_upper_case_callback =
      base::Bind(&KeyLayout::OnKeySwitchToUpperCase,
                 weak_factory_.GetWeakPtr());
  base::Callback<void(const TextKey&)> switch_to_lower_case_callback =
      base::Bind(&KeyLayout::OnKeySwitchToLowerCase,
                 weak_factory_.GetWeakPtr());
  base::Callback<void(const TextKey&)> switch_to_symbols_callback =
      base::Bind(&KeyLayout::OnKeySwitchToSymbols, weak_factory_.GetWeakPtr());

  ImageKey* switch_to_upper_case_image_key = new ImageKey(
      "/\\", switch_to_upper_case_callback, keyboard_native::kUpperCaseIcon);
  ImageKey* switch_to_lower_case_image_key = new ImageKey(
      "\\/", switch_to_lower_case_callback, keyboard_native::kLowerCaseIcon);
  ImageKey* delete_image_key =
      new ImageKey("<-", delete_callback, keyboard_native::kDeleteIcon);
  ImageKey* action_image_key =
      new ImageKey(":)", do_nothing_callback, keyboard_native::kActionIcon);

  std::vector<Key*> lower_case_key_map_row_one = {
      new TextKey("q", emit_text_callback),
      new TextKey("w", emit_text_callback),
      new TextKey("e", emit_text_callback),
      new TextKey("r", emit_text_callback),
      new TextKey("t", emit_text_callback),
      new TextKey("y", emit_text_callback),
      new TextKey("u", emit_text_callback),
      new TextKey("o", emit_text_callback),
      new TextKey("i", emit_text_callback),
      new TextKey("p", emit_text_callback)};

  std::vector<Key*> lower_case_key_map_row_two = {
      new TextKey("a", emit_text_callback),
      new TextKey("s", emit_text_callback),
      new TextKey("d", emit_text_callback),
      new TextKey("f", emit_text_callback),
      new TextKey("g", emit_text_callback),
      new TextKey("h", emit_text_callback),
      new TextKey("j", emit_text_callback),
      new TextKey("k", emit_text_callback),
      new TextKey("l", emit_text_callback)};

  std::vector<Key*> lower_case_key_map_row_three = {
      switch_to_upper_case_image_key,
      new TextKey("z", emit_text_callback),
      new TextKey("x", emit_text_callback),
      new TextKey("c", emit_text_callback),
      new TextKey("v", emit_text_callback),
      new TextKey("b", emit_text_callback),
      new TextKey("n", emit_text_callback),
      new TextKey("m", emit_text_callback),
      delete_image_key};

  std::vector<Key*> lower_case_key_map_row_four = {
      new TextKey("sym", switch_to_symbols_callback),
      new TextKey(",", emit_text_callback),
      new TextKey(" ", emit_text_callback),
      new TextKey(".", emit_text_callback),
      action_image_key};

  lower_case_key_map_ = {lower_case_key_map_row_one,
                         lower_case_key_map_row_two,
                         lower_case_key_map_row_three,
                         lower_case_key_map_row_four};

  std::vector<Key*> upper_case_key_map_row_one = {
      new TextKey("Q", emit_text_callback),
      new TextKey("W", emit_text_callback),
      new TextKey("E", emit_text_callback),
      new TextKey("R", emit_text_callback),
      new TextKey("T", emit_text_callback),
      new TextKey("Y", emit_text_callback),
      new TextKey("U", emit_text_callback),
      new TextKey("O", emit_text_callback),
      new TextKey("I", emit_text_callback),
      new TextKey("P", emit_text_callback)};

  std::vector<Key*> upper_case_key_map_row_two = {
      new TextKey("A", emit_text_callback),
      new TextKey("S", emit_text_callback),
      new TextKey("D", emit_text_callback),
      new TextKey("F", emit_text_callback),
      new TextKey("G", emit_text_callback),
      new TextKey("H", emit_text_callback),
      new TextKey("J", emit_text_callback),
      new TextKey("K", emit_text_callback),
      new TextKey("L", emit_text_callback)};

  std::vector<Key*> upper_case_key_map_row_three = {
      switch_to_lower_case_image_key,
      new TextKey("Z", emit_text_callback),
      new TextKey("X", emit_text_callback),
      new TextKey("C", emit_text_callback),
      new TextKey("V", emit_text_callback),
      new TextKey("B", emit_text_callback),
      new TextKey("N", emit_text_callback),
      new TextKey("M", emit_text_callback),
      delete_image_key};

  std::vector<Key*> upper_case_key_map_row_four = {
      new TextKey("SYM", switch_to_symbols_callback),
      new TextKey(",", emit_text_callback),
      new TextKey(" ", emit_text_callback),
      new TextKey(".", emit_text_callback),
      action_image_key};

  upper_case_key_map_ = {upper_case_key_map_row_one,
                         upper_case_key_map_row_two,
                         upper_case_key_map_row_three,
                         upper_case_key_map_row_four};

  std::vector<Key*> symbols_key_map_row_one = {
      new TextKey("1", emit_text_callback),
      new TextKey("2", emit_text_callback),
      new TextKey("3", emit_text_callback),
      new TextKey("4", emit_text_callback),
      new TextKey("5", emit_text_callback),
      new TextKey("6", emit_text_callback),
      new TextKey("7", emit_text_callback),
      new TextKey("8", emit_text_callback),
      new TextKey("9", emit_text_callback),
      new TextKey("0", emit_text_callback)};

  std::vector<Key*> symbols_key_map_row_two = {
      new TextKey("@", emit_text_callback),
      new TextKey("#", emit_text_callback),
      new TextKey("$", emit_text_callback),
      new TextKey("%", emit_text_callback),
      new TextKey("&", emit_text_callback),
      new TextKey("-", emit_text_callback),
      new TextKey("+", emit_text_callback),
      new TextKey("(", emit_text_callback),
      new TextKey(")", emit_text_callback)};

  std::vector<Key*> symbols_key_map_row_three = {
      new TextKey("=\\<", switch_to_symbols_callback),
      new TextKey("*", emit_text_callback),
      new TextKey("\"", emit_text_callback),
      new TextKey("'", emit_text_callback),
      new TextKey(":", emit_text_callback),
      new TextKey(";", emit_text_callback),
      new TextKey("!", emit_text_callback),
      new TextKey("?", emit_text_callback),
      delete_image_key};

  std::vector<Key*> symbols_key_map_row_four = {
      new TextKey("ABC", switch_to_lower_case_callback),
      new TextKey(",", emit_text_callback),
      new TextKey("_", emit_text_callback),
      new TextKey(" ", emit_text_callback),
      new TextKey("/", emit_text_callback),
      new TextKey(".", emit_text_callback),
      action_image_key};

  symbols_key_map_ = {symbols_key_map_row_one,
                      symbols_key_map_row_two,
                      symbols_key_map_row_three,
                      symbols_key_map_row_four};
}
}
// namespace keyboard
