// Copyright 2018 The Fuchsia 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 "garnet/bin/ui/snapshot/view.h"

#include "garnet/lib/ui/gfx/resources/snapshot/version.h"
#include "lib/fsl/vmo/vector.h"
#include "lib/fxl/logging.h"
#include "lib/ui/scenic/cpp/host_memory.h"

namespace snapshot {

View::View(scenic::ViewContext view_context)
    : V1BaseView(std::move(view_context), "Snapshot View") {
  outgoing_services().AddService(loader_bindings_.GetHandler(this));
}

void View::Load(::fuchsia::mem::Buffer payload) {
  std::vector<uint8_t> data;
  if (!fsl::VectorFromVmo(payload, &data)) {
    FXL_LOG(ERROR) << "VectorFromVmo failed";
    return;
  }

  using SnapshotData = scenic_impl::gfx::SnapshotData;
  auto snapshot = (const SnapshotData*)data.data();
  if (snapshot->type != SnapshotData::SnapshotType::kFlatBuffer ||
      snapshot->version != SnapshotData::SnapshotVersion::v1_0) {
    FXL_LOG(ERROR) << "Invalid snapshot format encountered. Aborting.";
    return;
  }

  auto flat_node = flatbuffers::GetRoot<snapshot::Node>(snapshot->data);
  LoadNode(parent_node(), flat_node);
}

void View::LoadNode(scenic::ContainerNode& parent_node,
                    const snapshot::Node* flat_node) {
  scenic::EntityNode entity_node(session());

  if (flat_node->transform()) {
    auto transform = flat_node->transform();
    entity_node.SetTranslation(transform->translation()->x(),   // x
                               transform->translation()->y(),   // y
                               transform->translation()->z());  // z
    entity_node.SetScale(transform->scale()->x(),               // x
                         transform->scale()->y(),               // y
                         transform->scale()->z());              // z
    entity_node.SetRotation(transform->rotation()->x(),         // x
                            transform->rotation()->y(),         // y
                            transform->rotation()->z(),         // z
                            transform->rotation()->w());        // w
    entity_node.SetAnchor(transform->anchor()->x(),             // x
                          transform->anchor()->y(),             // y
                          transform->anchor()->z());            // z
  }

  if (flat_node->shape()) {
    LoadShape(entity_node, flat_node);
  }

  parent_node.AddChild(entity_node);

  if (flat_node->children()) {
    for (auto child : *flat_node->children()) {
      LoadNode(entity_node, child);
    }
  }
}

void View::LoadShape(scenic::EntityNode& parent_node,
                     const snapshot::Node* flat_node) {
  scenic::ShapeNode shape_node(session());

  switch (flat_node->shape_type()) {
    case snapshot::Shape_NONE:
      return;
    case snapshot::Shape_Mesh:
      // TODO(sanjayc): Implement mesh.
      return;

    case snapshot::Shape_Circle: {
      auto shape = static_cast<const snapshot::Circle*>(flat_node->shape());
      scenic::Circle circle(session(), shape->radius());
      shape_node.SetShape(circle);
    } break;

    case snapshot::Shape_Rectangle: {
      auto shape = static_cast<const snapshot::Rectangle*>(flat_node->shape());
      scenic::Rectangle rectangle(session(),
                                  shape->width(),    // width
                                  shape->height());  // height
      shape_node.SetShape(rectangle);
    } break;

    case snapshot::Shape_RoundedRectangle: {
      auto shape =
          static_cast<const snapshot::RoundedRectangle*>(flat_node->shape());
      scenic::RoundedRectangle rounded_rectangle(
          session(),
          shape->width(),                // width
          shape->height(),               // height
          shape->top_left_radius(),      // top-left
          shape->top_right_radius(),     // top-right
          shape->bottom_right_radius(),  // bottom-right
          shape->bottom_left_radius());  // bottom-left
      shape_node.SetShape(rounded_rectangle);
    } break;

    default:
      // TODO(SCN-978): Return an error to the caller for invalid data.
      FXL_DCHECK(false) << "Unknown node type encountered. Corrupt flatbuffer?";
      return;
  }

  if (flat_node->material()) {
    LoadMaterial(shape_node, flat_node);
  }

  parent_node.AddPart(shape_node);
}

void View::LoadMaterial(scenic::ShapeNode& shape_node,
                        const snapshot::Node* flat_node) {
  if (flat_node->material_type() == snapshot::Material_Color) {
    auto color = static_cast<const snapshot::Color*>(flat_node->material());

    scenic::Material material(session());
    material.SetColor(255 * color->red(),     // red
                      255 * color->green(),   // green
                      255 * color->blue(),    // blue
                      255 * color->alpha());  // alpha
    shape_node.SetMaterial(material);
  } else if (flat_node->material_type() == snapshot::Material_Image) {
    auto image = static_cast<const snapshot::Image*>(flat_node->material());

    scenic::HostMemory memory(session(), image->data()->Length());
    memcpy(memory.data_ptr(), image->data()->Data(), image->data()->Length());

    // Create an ImageInfo to wrap the memory.
    fuchsia::images::ImageInfo image_info;
    image_info.width = image->width();
    image_info.height = image->height();
    const size_t kBytesPerPixel = 4u;
    image_info.stride = image->width() * kBytesPerPixel;
    image_info.pixel_format = fuchsia::images::PixelFormat::BGRA_8;
    image_info.color_space = fuchsia::images::ColorSpace::SRGB;
    image_info.tiling = fuchsia::images::Tiling::LINEAR;
    scenic::HostImage host_image(memory, 0, std::move(image_info));

    scenic::Material material(session());
    material.SetTexture(host_image.id());
    shape_node.SetMaterial(material);
  }
}

}  // namespace snapshot
