// Copyright 2019 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_DOM_INTERSECTION_OBSERVER_H_
#define COBALT_DOM_INTERSECTION_OBSERVER_H_

#include <string>
#include <vector>

#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "cobalt/cssom/property_list_value.h"
#include "cobalt/dom/intersection_observer_entry.h"
#include "cobalt/script/callback_function.h"
#include "cobalt/script/environment_settings.h"
#include "cobalt/script/exception_state.h"
#include "cobalt/script/script_value.h"
#include "cobalt/script/sequence.h"
#include "cobalt/script/union_type.h"
#include "cobalt/script/wrappable.h"

namespace cobalt {
namespace dom {

class Element;
class IntersectionObserverInit;
class IntersectionObserverTaskManager;

// The IntersectionObserver can be used to observe changes in the intersection
// of an intersection root and one or more target Elements.
// https://www.w3.org/TR/intersection-observer/#intersection-observer-interfaces
class IntersectionObserver : public script::Wrappable {
 public:
  typedef script::Sequence<scoped_refptr<IntersectionObserverEntry>>
      IntersectionObserverEntrySequence;

  typedef script::CallbackFunction<void(
      const IntersectionObserverEntrySequence&,
      const scoped_refptr<IntersectionObserver>&)>
      IntersectionObserverCallback;
  typedef script::ScriptValue<IntersectionObserverCallback>
      IntersectionObserverCallbackArg;

  typedef script::UnionType2<double, script::Sequence<double>> ThresholdType;

  // Web API: IntersectionObserver
  IntersectionObserver(script::EnvironmentSettings* settings,
                       const IntersectionObserverCallbackArg& callback,
                       script::ExceptionState* exception_state);
  IntersectionObserver(script::EnvironmentSettings* settings,
                       const IntersectionObserverCallbackArg& callback,
                       const IntersectionObserverInit& options,
                       script::ExceptionState* exception_state);
  ~IntersectionObserver();

  const scoped_refptr<Element>& root() { return root_; }
  // Part of the IntersectionObserver interface, but differs from the web spec
  // in that it returns the exact string passed into |options|, regardless of
  // whether it is formatted as four space-separated pixels lengths/percentages.
  std::string root_margin() const { return root_margin_; }
  // Not part of the IntersectionObserver interface. Returns the root margin
  // parsed as a PropertyListValue.
  const scoped_refptr<cssom::PropertyListValue>& root_margin_property_value() {
    return root_margin_property_value_;
  }
  script::Sequence<double> const thresholds();
  void Observe(const scoped_refptr<Element>& target);
  void Unobserve(const scoped_refptr<Element>& target);
  void Disconnect();
  IntersectionObserverEntrySequence TakeRecords();

  // Not part of the IntersectionObserver interface. Implements the "queue an
  // IntersectionObserverEntry" algorithm.
  // https://www.w3.org/TR/intersection-observer/#queue-intersection-observer-entry-algo
  void QueueIntersectionObserverEntry(
      const scoped_refptr<IntersectionObserverEntry>& entry);

  // Not part of the IntersectionObserver interface. Implements step (2) of the
  // "run the update intersection observations steps" algorithm.
  // https://www.w3.org/TR/intersection-observer/#notify-intersection-observers-algo
  void UpdateObservationTargets();

  // Not part of the the IntersectionObserver interface. Implements step (3) of
  // the "notify intersection observers" algorithm.
  // https://www.w3.org/TR/intersection-observer/#notify-intersection-observers-algo
  bool Notify();

  // Internal helper class to allow creation of a IntersectionObserver with a
  // script callback. Must be public so it can be inherited from in the .cc
  // file.
  class CallbackInternal;

  DEFINE_WRAPPABLE_TYPE(IntersectionObserver);
  void TraceMembers(script::Tracer* tracer) override;

 private:
  IntersectionObserverTaskManager* task_manager();
  void InitIntersectionObserverInternal(
      script::EnvironmentSettings* settings,
      const IntersectionObserverCallbackArg& callback,
      const IntersectionObserverInit& options,
      script::ExceptionState* exception_state);
  void TrackObservationTarget(const scoped_refptr<Element>& target);
  void UntrackObservationTarget(const scoped_refptr<Element>& target);

  std::unique_ptr<CallbackInternal> callback_;
  scoped_refptr<Element> root_;
  std::string root_margin_;
  scoped_refptr<cssom::PropertyListValue> root_margin_property_value_;
  std::vector<double> thresholds_;
  typedef std::vector<scoped_refptr<Element>> ElementVector;
  ElementVector observation_targets_;
  IntersectionObserverEntrySequence queued_entries_;
};

}  // namespace dom
}  // namespace cobalt

#endif  // COBALT_DOM_INTERSECTION_OBSERVER_H_
