// Copyright 2017 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 "lib/ui/scenic/cpp/resources.h"

#include <algorithm>

#include "lib/images/cpp/images.h"
#include "lib/ui/scenic/cpp/commands.h"

namespace scenic {
namespace {

template <class T>
constexpr const T& clamp(const T& v, const T& lo, const T& hi) {
  return (v < lo) ? lo : (hi < v) ? hi : v;
}

}  // namespace

Resource::Resource(Session* session)
    : session_(session), id_(session->AllocResourceId()) {}

Resource::Resource(Resource&& moved)
    : session_(moved.session_), id_(moved.id_) {
  auto& moved_session = *const_cast<Session**>(&moved.session_);
  auto& moved_id = *const_cast<uint32_t*>(&moved.id_);
  moved_session = nullptr;
  moved_id = 0;
}

Resource::~Resource() {
  // If this resource was moved, it is not responsible for releasing the ID.
  if (session_)
    session_->ReleaseResource(id_);
}

void Resource::Export(zx::eventpair export_token) {
  session_->Enqueue(NewExportResourceCmd(id(), std::move(export_token)));
}

void Resource::ExportAsRequest(zx::eventpair* out_import_token) {
  session_->Enqueue(NewExportResourceCmdAsRequest(id(), out_import_token));
}

void Resource::SetEventMask(uint32_t event_mask) {
  session_->Enqueue(NewSetEventMaskCmd(id(), event_mask));
}

void Resource::SetLabel(const std::string& label) {
  session_->Enqueue(NewSetLabelCmd(id(), label));
}

Shape::Shape(Session* session) : Resource(session) {}

Shape::Shape(Shape&& moved) : Resource(std::move(moved)) {}

Shape::~Shape() = default;

Circle::Circle(Session* session, float radius) : Shape(session) {
  session->Enqueue(NewCreateCircleCmd(id(), radius));
}

Circle::Circle(Circle&& moved) : Shape(std::move(moved)) {}

Circle::~Circle() = default;

Rectangle::Rectangle(Session* session, float width, float height)
    : Shape(session) {
  session->Enqueue(NewCreateRectangleCmd(id(), width, height));
}

Rectangle::Rectangle(Rectangle&& moved) : Shape(std::move(moved)) {}

Rectangle::~Rectangle() = default;

RoundedRectangle::RoundedRectangle(Session* session, float width, float height,
                                   float top_left_radius,
                                   float top_right_radius,
                                   float bottom_right_radius,
                                   float bottom_left_radius)
    : Shape(session) {
  session->Enqueue(NewCreateRoundedRectangleCmd(
      id(), width, height, top_left_radius, top_right_radius,
      bottom_right_radius, bottom_left_radius));
}

RoundedRectangle::RoundedRectangle(RoundedRectangle&& moved)
    : Shape(std::move(moved)) {}

RoundedRectangle::~RoundedRectangle() = default;

Image::Image(const Memory& memory, off_t memory_offset,
             fuchsia::images::ImageInfo info)
    : Image(memory.session(), memory.id(), memory_offset, std::move(info)) {}

Image::Image(Session* session, uint32_t memory_id, off_t memory_offset,
             fuchsia::images::ImageInfo info)
    : Resource(session), memory_offset_(memory_offset), info_(info) {
  session->Enqueue(
      NewCreateImageCmd(id(), memory_id, memory_offset_, std::move(info)));
}

Image::Image(Image&& moved)
    : Resource(std::move(moved)),
      memory_offset_(moved.memory_offset_),
      info_(moved.info_) {}

Image::~Image() = default;

size_t Image::ComputeSize(const fuchsia::images::ImageInfo& image_info) {
  return images::ImageSize(image_info);
}

Buffer::Buffer(const Memory& memory, off_t memory_offset, size_t num_bytes)
    : Buffer(memory.session(), memory.id(), memory_offset, num_bytes) {}

Buffer::Buffer(Session* session, uint32_t memory_id, off_t memory_offset,
               size_t num_bytes)
    : Resource(session) {
  session->Enqueue(
      NewCreateBufferCmd(id(), memory_id, memory_offset, num_bytes));
}

Buffer::Buffer(Buffer&& moved) : Resource(std::move(moved)) {}

Buffer::~Buffer() = default;

Memory::Memory(Session* session, zx::vmo vmo, uint64_t allocation_size,
               fuchsia::images::MemoryType memory_type)
    : Resource(session), memory_type_(memory_type) {
  session->Enqueue(
      NewCreateMemoryCmd(id(), std::move(vmo), allocation_size, memory_type));
}

Memory::Memory(Memory&& moved)
    : Resource(std::move(moved)), memory_type_(moved.memory_type_) {}

Memory::~Memory() = default;

Mesh::Mesh(Session* session) : Shape(session) {
  session->Enqueue(NewCreateMeshCmd(id()));
}

Mesh::Mesh(Mesh&& moved) : Shape(std::move(moved)) {}

Mesh::~Mesh() = default;

void Mesh::BindBuffers(const Buffer& index_buffer,
                       fuchsia::ui::gfx::MeshIndexFormat index_format,
                       uint64_t index_offset, uint32_t index_count,
                       const Buffer& vertex_buffer,
                       fuchsia::ui::gfx::MeshVertexFormat vertex_format,
                       uint64_t vertex_offset, uint32_t vertex_count,
                       const float bounding_box_min[3],
                       const float bounding_box_max[3]) {
  ZX_DEBUG_ASSERT(session() == index_buffer.session() &&
                  session() == vertex_buffer.session());
  session()->Enqueue(NewBindMeshBuffersCmd(
      id(), index_buffer.id(), index_format, index_offset, index_count,
      vertex_buffer.id(), std::move(vertex_format), vertex_offset, vertex_count,
      bounding_box_min, bounding_box_max));
}

Material::Material(Session* session) : Resource(session) {
  session->Enqueue(NewCreateMaterialCmd(id()));
}

Material::Material(Material&& moved) : Resource(std::move(moved)) {}

Material::~Material() = default;

void Material::SetTexture(uint32_t image_id) {
  session()->Enqueue(NewSetTextureCmd(id(), image_id));
}

void Material::SetColor(uint8_t red, uint8_t green, uint8_t blue,
                        uint8_t alpha) {
  session()->Enqueue(NewSetColorCmd(id(), red, green, blue, alpha));
}

Node::Node(Session* session) : Resource(session) {}

Node::Node(Node&& moved) : Resource(std::move(moved)) {}

Node::~Node() = default;

void Node::SetTranslation(const float translation[3]) {
  session()->Enqueue(NewSetTranslationCmd(id(), translation));
}

void Node::SetTranslation(uint32_t variable_id) {
  session()->Enqueue(NewSetTranslationCmd(id(), variable_id));
}

void Node::SetScale(const float scale[3]) {
  session()->Enqueue(NewSetScaleCmd(id(), scale));
}

void Node::SetScale(uint32_t variable_id) {
  session()->Enqueue(NewSetScaleCmd(id(), variable_id));
}

void Node::SetRotation(const float quaternion[4]) {
  session()->Enqueue(NewSetRotationCmd(id(), quaternion));
}

void Node::SetRotation(uint32_t variable_id) {
  session()->Enqueue(NewSetRotationCmd(id(), variable_id));
}

void Node::SetAnchor(const float anchor[3]) {
  session()->Enqueue(NewSetAnchorCmd(id(), anchor));
}

void Node::SetAnchor(uint32_t variable_id) {
  session()->Enqueue(NewSetAnchorCmd(id(), variable_id));
}

void Node::SendSizeChangeHint(float width_change_factor,
                              float height_change_factor) {
  session()->Enqueue(NewSendSizeChangeHintCmdHACK(id(), width_change_factor,
                                                  height_change_factor));
}

void Node::SetTag(uint32_t tag_value) {
  session()->Enqueue(NewSetTagCmd(id(), tag_value));
}

void Node::SetHitTestBehavior(
    fuchsia::ui::gfx::HitTestBehavior hit_test_behavior) {
  session()->Enqueue(NewSetHitTestBehaviorCmd(id(), hit_test_behavior));
}

void Node::Detach() { session()->Enqueue(NewDetachCmd(id())); }

ShapeNode::ShapeNode(Session* session) : Node(session) {
  session->Enqueue(NewCreateShapeNodeCmd(id()));
}

ShapeNode::ShapeNode(ShapeNode&& moved) : Node(std::move(moved)) {}

ShapeNode::~ShapeNode() = default;

void ShapeNode::SetShape(uint32_t shape_id) {
  session()->Enqueue(NewSetShapeCmd(id(), shape_id));
}

void ShapeNode::SetMaterial(uint32_t material_id) {
  session()->Enqueue(NewSetMaterialCmd(id(), material_id));
}

ContainerNode::ContainerNode(Session* session) : Node(session) {}

ContainerNode::ContainerNode(ContainerNode&& moved) : Node(std::move(moved)) {}

ContainerNode::~ContainerNode() = default;

void ContainerNode::AddChild(uint32_t child_node_id) {
  session()->Enqueue(NewAddChildCmd(id(), child_node_id));
}

void ContainerNode::AddPart(uint32_t part_node_id) {
  session()->Enqueue(NewAddPartCmd(id(), part_node_id));
}

void ContainerNode::DetachChildren() {
  session()->Enqueue(NewDetachChildrenCmd(id()));
}

EntityNode::EntityNode(Session* session) : ContainerNode(session) {
  session->Enqueue(NewCreateEntityNodeCmd(id()));
}

void EntityNode::Attach(const ViewHolder& view_holder) {
  session()->Enqueue(NewAddChildCmd(id(), view_holder.id()));
}

void EntityNode::Snapshot(fuchsia::ui::gfx::SnapshotCallbackHACKPtr callback) {
  session()->Enqueue(NewTakeSnapshotCmdHACK(id(), std::move(callback)));
}

EntityNode::~EntityNode() = default;

void EntityNode::SetClip(uint32_t clip_id, bool clip_to_self) {
  session()->Enqueue(NewSetClipCmd(id(), clip_id, clip_to_self));
}

ImportNode::ImportNode(Session* session) : ContainerNode(session) {}

ImportNode::ImportNode(ImportNode&& moved) : ContainerNode(std::move(moved)) {}

ImportNode::~ImportNode() {
  ZX_DEBUG_ASSERT_MSG(is_bound_, "Import was never bound.");
}

void ImportNode::Bind(zx::eventpair import_token) {
  ZX_DEBUG_ASSERT(!is_bound_);
  session()->Enqueue(NewImportResourceCmd(
      id(), fuchsia::ui::gfx::ImportSpec::NODE, std::move(import_token)));
  is_bound_ = true;
}

void ImportNode::BindAsRequest(zx::eventpair* out_export_token) {
  ZX_DEBUG_ASSERT(!is_bound_);
  session()->Enqueue(NewImportResourceCmdAsRequest(
      id(), fuchsia::ui::gfx::ImportSpec::NODE, out_export_token));
  is_bound_ = true;
}

ViewHolder::ViewHolder(Session* session, zx::eventpair token,
                       const std::string& debug_name)
    : Resource(session) {
  session->Enqueue(NewCreateViewHolderCmd(id(), std::move(token), debug_name));
}

ViewHolder::~ViewHolder() = default;

void ViewHolder::SetViewProperties(const float bounding_box_min[3],
                                   const float bounding_box_max[3],
                                   const float inset_from_min[3],
                                   const float inset_from_max[3]) {
  session()->Enqueue(NewSetViewPropertiesCmd(id(), bounding_box_min,
                                             bounding_box_max, inset_from_min,
                                             inset_from_max));
}

void ViewHolder::SetViewProperties(
    const fuchsia::ui::gfx::ViewProperties& props) {
  session()->Enqueue(NewSetViewPropertiesCmd(id(), props));
}

View::View(Session* session, zx::eventpair token, const std::string& debug_name)
    : Resource(session) {
  session->Enqueue(NewCreateViewCmd(id(), std::move(token), debug_name));
}

View::~View() = default;

void View::AddChild(const Node& child) const {
  ZX_DEBUG_ASSERT(session() == child.session());
  session()->Enqueue(NewAddChildCmd(id(), child.id()));
}

void View::DetachChild(const Node& child) const {
  ZX_DEBUG_ASSERT(session() == child.session());
  session()->Enqueue(NewDetachCmd(child.id()));
}

ClipNode::ClipNode(Session* session) : ContainerNode(session) {
  session->Enqueue(NewCreateClipNodeCmd(id()));
}

ClipNode::ClipNode(ClipNode&& moved) : ContainerNode(std::move(moved)) {}

ClipNode::~ClipNode() = default;

OpacityNode::OpacityNode(Session* session) : ContainerNode(session) {
  session->Enqueue(NewCreateOpacityNodeCmd(id()));
}

OpacityNode::OpacityNode(OpacityNode&& moved)
    : ContainerNode(std::move(moved)) {}

OpacityNode::~OpacityNode() = default;

void OpacityNode::SetOpacity(float opacity) {
  opacity = clamp(opacity, 0.f, 1.f);
  session()->Enqueue(NewSetOpacityCmd(id(), opacity));
}

Variable::Variable(Session* session, fuchsia::ui::gfx::Value initial_value)
    : Resource(session) {
  session->Enqueue(NewCreateVariableCmd(id(), std::move(initial_value)));
}

Variable::Variable(Variable&& moved) : Resource(std::move(moved)) {}

Variable::~Variable() = default;

Scene::Scene(Session* session) : ContainerNode(session) {
  session->Enqueue(NewCreateSceneCmd(id()));
}

Scene::Scene(Scene&& moved) : ContainerNode(std::move(moved)) {}

Scene::~Scene() = default;

void Scene::AddLight(uint32_t light_id) {
  session()->Enqueue(NewAddLightCmd(id(), light_id));
}

void Scene::DetachLights() { session()->Enqueue(NewDetachLightsCmd(id())); }

void CameraBase::SetTransform(const float eye_position[3],
                              const float eye_look_at[3],
                              const float eye_up[3]) {
  session()->Enqueue(
      NewSetCameraTransformCmd(id(), eye_position, eye_look_at, eye_up));
}

void CameraBase::SetPoseBuffer(const Buffer& buffer, uint32_t num_entries,
                               int64_t base_time, uint64_t time_interval) {
  session()->Enqueue(NewSetCameraPoseBufferCmd(id(), buffer.id(), num_entries,
                                               base_time, time_interval));
}

Camera::Camera(const Scene& scene) : Camera(scene.session(), scene.id()) {}

Camera::Camera(Session* session, uint32_t scene_id) : CameraBase(session) {
  session->Enqueue(NewCreateCameraCmd(id(), scene_id));
}

Camera::Camera(Camera&& moved) : CameraBase(std::move(moved)) {}

Camera::~Camera() = default;

void Camera::SetProjection(const float fovy) {
  session()->Enqueue(NewSetCameraProjectionCmd(id(), fovy));
}

StereoCamera::StereoCamera(const Scene& scene)
    : StereoCamera(scene.session(), scene.id()) {}

StereoCamera::StereoCamera(Session* session, uint32_t scene_id)
    : CameraBase(session) {
  session->Enqueue(NewCreateStereoCameraCmd(id(), scene_id));
}

StereoCamera::StereoCamera(StereoCamera&& moved)
    : CameraBase(std::move(moved)) {}

StereoCamera::~StereoCamera() = default;

void StereoCamera::SetStereoProjection(const float left_projection[16],
                                       const float right_projection[16]) {
  session()->Enqueue(
      NewSetStereoCameraProjectionCmd(id(), left_projection, right_projection));
}

Renderer::Renderer(Session* session) : Resource(session) {
  session->Enqueue(NewCreateRendererCmd(id()));
}

Renderer::Renderer(Renderer&& moved) : Resource(std::move(moved)) {}

Renderer::~Renderer() = default;

void Renderer::SetCamera(uint32_t camera_id) {
  session()->Enqueue(NewSetCameraCmd(id(), camera_id));
}

void Renderer::SetParam(fuchsia::ui::gfx::RendererParam param) {
  session()->Enqueue(NewSetRendererParamCmd(id(), std::move(param)));
}

void Renderer::SetShadowTechnique(fuchsia::ui::gfx::ShadowTechnique technique) {
  auto param = fuchsia::ui::gfx::RendererParam();
  param.set_shadow_technique(technique);
  SetParam(std::move(param));
}

void Renderer::SetDisableClipping(bool disable_clipping) {
  session()->Enqueue(NewSetDisableClippingCmd(id(), disable_clipping));
}

Layer::Layer(Session* session) : Resource(session) {
  session->Enqueue(NewCreateLayerCmd(id()));
}

Layer::Layer(Layer&& moved) : Resource(std::move(moved)) {}

Layer::~Layer() = default;

void Layer::SetRenderer(uint32_t renderer_id) {
  session()->Enqueue(NewSetRendererCmd(id(), renderer_id));
}

void Layer::SetSize(const float size[2]) {
  session()->Enqueue(NewSetSizeCmd(id(), size));
}

LayerStack::LayerStack(Session* session) : Resource(session) {
  session->Enqueue(NewCreateLayerStackCmd(id()));
}

LayerStack::LayerStack(LayerStack&& moved) : Resource(std::move(moved)) {}

LayerStack::~LayerStack() = default;

void LayerStack::AddLayer(uint32_t layer_id) {
  session()->Enqueue(NewAddLayerCmd(id(), layer_id));
}

void LayerStack::RemoveLayer(uint32_t layer_id) {
  session()->Enqueue(NewRemoveLayerCmd(id(), layer_id));
}

void LayerStack::RemoveAllLayers() {
  session()->Enqueue(NewRemoveAllLayersCmd(id()));
}

DisplayCompositor::DisplayCompositor(Session* session) : Resource(session) {
  session->Enqueue(NewCreateDisplayCompositorCmd(id()));
}

DisplayCompositor::DisplayCompositor(DisplayCompositor&& moved)
    : Resource(std::move(moved)) {}

DisplayCompositor::~DisplayCompositor() = default;

void DisplayCompositor::SetLayerStack(uint32_t layer_stack_id) {
  session()->Enqueue(NewSetLayerStackCmd(id(), layer_stack_id));
}

Compositor::Compositor(Session* session) : Resource(session) {
  session->Enqueue(NewCreateCompositorCmd(id()));
}

Compositor::Compositor(Compositor&& moved) : Resource(std::move(moved)) {}

Compositor::~Compositor() = default;

void Compositor::SetLayerStack(uint32_t layer_stack_id) {
  session()->Enqueue(NewSetLayerStackCmd(id(), layer_stack_id));
}

Light::Light(Session* session) : Resource(session) {}

Light::Light(Light&& moved) : Resource(std::move(moved)) {}

Light::~Light() = default;

void Light::SetColor(const float rgb[3]) {
  session()->Enqueue(NewSetLightColorCmd(id(), rgb));
}

void Light::SetColor(uint32_t variable_id) {
  session()->Enqueue(NewSetLightColorCmd(id(), variable_id));
}

void Light::Detach() { session()->Enqueue(NewDetachLightCmd(id())); }

AmbientLight::AmbientLight(Session* session) : Light(session) {
  session->Enqueue(NewCreateAmbientLightCmd(id()));
}

AmbientLight::AmbientLight(AmbientLight&& moved) : Light(std::move(moved)) {}

AmbientLight::~AmbientLight() = default;

DirectionalLight::DirectionalLight(Session* session) : Light(session) {
  session->Enqueue(NewCreateDirectionalLightCmd(id()));
}

DirectionalLight::DirectionalLight(DirectionalLight&& moved)
    : Light(std::move(moved)) {}

DirectionalLight::~DirectionalLight() = default;

void DirectionalLight::SetDirection(const float direction[3]) {
  session()->Enqueue(NewSetLightDirectionCmd(id(), direction));
}

void DirectionalLight::SetDirection(uint32_t variable_id) {
  session()->Enqueue(NewSetLightDirectionCmd(id(), variable_id));
}

}  // namespace scenic
