// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_FLOW_VIEW_HOLDER_H_
#define FLUTTER_FLOW_VIEW_HOLDER_H_

#include <fuchsia/ui/gfx/cpp/fidl.h>
#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/ui/scenic/cpp/id.h>
#include <lib/ui/scenic/cpp/resources.h>
#include <include/core/SkMatrix.h>
#include <include/core/SkPoint.h>
#include <include/core/SkSize.h>
#include <zircon/types.h>

#include <memory>

#include "flutter/flow/scene_update_context.h"
#include "flutter/fml/macros.h"
#include "flutter/fml/memory/ref_counted.h"
#include "flutter/fml/task_runner.h"

namespace flutter {

// Represents a Scenic |ViewHolder| resource that imports a |View| from another
// session.
//
// This object is created and destroyed on the |Rasterizer|'s thread.
class ViewHolder {
 public:
  using BindCallback = std::function<void(scenic::ResourceId)>;

  static void Create(zx_koid_t id,
                     fml::RefPtr<fml::TaskRunner> ui_task_runner,
                     fuchsia::ui::views::ViewHolderToken view_holder_token,
                     BindCallback on_bind_callback);
  static void Destroy(zx_koid_t id);
  static ViewHolder* FromId(zx_koid_t id);

  ViewHolder(fml::RefPtr<fml::TaskRunner> ui_task_runner,
             fuchsia::ui::views::ViewHolderToken view_holder_token,
             BindCallback on_bind_callback);
  ~ViewHolder() = default;

  // Sets the properties/opacity of the child view by issuing a Scenic command.
  void SetProperties(double width,
                     double height,
                     double insetTop,
                     double insetRight,
                     double insetBottom,
                     double insetLeft,
                     bool focusable);
  void SetOpacity(double opacity);

  // Creates or updates the contained ViewHolder resource using the specified
  // |SceneUpdateContext|.
  void UpdateScene(SceneUpdateContext& context,
                   const SkPoint& offset,
                   const SkSize& size,
                   bool hit_testable);

 private:
  fml::RefPtr<fml::TaskRunner> ui_task_runner_;

  std::unique_ptr<scenic::OpacityNodeHACK> opacity_node_;
  std::unique_ptr<scenic::EntityNode> entity_node_;
  std::unique_ptr<scenic::ViewHolder> view_holder_;

  fuchsia::ui::views::ViewHolderToken pending_view_holder_token_;
  BindCallback pending_bind_callback_;

  fuchsia::ui::gfx::ViewProperties pending_properties_;
  double pending_opacity_;
  bool has_pending_properties_ = false;
  bool has_pending_opacity_ = false;

  FML_DISALLOW_COPY_AND_ASSIGN(ViewHolder);
};

}  // namespace flutter

#endif  // FLUTTER_FLOW_VIEW_HOLDER_H_