// Copyright 2015 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_WEB_ANIMATIONS_ANIMATION_EFFECT_TIMING_READ_ONLY_H_
#define COBALT_WEB_ANIMATIONS_ANIMATION_EFFECT_TIMING_READ_ONLY_H_

#include <string>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "cobalt/cssom/timing_function.h"
#include "cobalt/script/union_type.h"
#include "cobalt/script/wrappable.h"

namespace cobalt {
namespace web_animations {

// Implements the Web Animations API AnimationEffectTimingReadOnly interface.
//   https://www.w3.org/TR/2015/WD-web-animations-1-20150707/#the-animationeffecttimingreadonly-interface
// Specifies animation timing details, such as delay, number of iterations,
// duration, etc...
class AnimationEffectTimingReadOnly : public script::Wrappable {
 public:
  enum FillMode { kNone, kForwards, kBackwards, kBoth };
  enum PlaybackDirection { kNormal, kReverse, kAlternate, kAlternateReverse };

  AnimationEffectTimingReadOnly(
      const base::TimeDelta& delay, const base::TimeDelta& end_delay,
      FillMode fill, double iteration_start, double iterations,
      const base::TimeDelta& duration, PlaybackDirection direction,
      const scoped_refptr<cssom::TimingFunction>& easing)
      : data_(delay, end_delay, fill, iteration_start, iterations, duration,
              direction, easing) {}

  double delay() const { return data_.delay().InMillisecondsF(); }

  double end_delay() const { return data_.end_delay().InMillisecondsF(); }

  FillMode fill() const { return data_.fill(); }

  double iteration_start() const { return data_.iteration_start(); }

  double iterations() const { return data_.iterations(); }

  double duration() const { return data_.duration().InMillisecondsF(); }

  PlaybackDirection direction() const { return data_.direction(); }

  std::string easing() const {
    NOTIMPLEMENTED();
    return std::string("linear");
  }

  // Custom, not in any spec.

  // Package all the core data members provided by this class so that they can
  // easily be copied out of AnimationEffectTimingReadOnly and used elsewhere.
  class Data {
   public:
    Data()
        : iteration_start_(0.0),
          iterations_(1.0),
          easing_(cssom::TimingFunction::GetLinear()) {}
    Data(const base::TimeDelta& delay, const base::TimeDelta& end_delay,
         AnimationEffectTimingReadOnly::FillMode fill, double iteration_start,
         double iterations, const base::TimeDelta& duration,
         PlaybackDirection direction,
         const scoped_refptr<cssom::TimingFunction>& easing)
        : delay_(delay),
          end_delay_(end_delay),
          fill_(fill),
          iteration_start_(iteration_start),
          iterations_(iterations),
          duration_(duration),
          direction_(direction),
          easing_(easing) {}

    base::TimeDelta delay() const { return delay_; }
    base::TimeDelta end_delay() const { return end_delay_; }
    AnimationEffectTimingReadOnly::FillMode fill() const { return fill_; }
    double iteration_start() const { return iteration_start_; }
    double iterations() const { return iterations_; }
    base::TimeDelta duration() const { return duration_; }
    PlaybackDirection direction() const { return direction_; }
    const scoped_refptr<cssom::TimingFunction> easing() const {
      return easing_;
    }

    // Given a local time (computed from an Animation object), it can be passed
    // to ComputeIterationProgressFromLocalTime() in order to produce an
    // iteration progress and current iteration, which can be subsequently
    // passed into KeyframeEffectReadOnly::Data::ComputeAnimatedPropertyValue()
    // to animate property values.
    struct IterationProgress {
      base::Optional<double> iteration_progress;
      base::Optional<double> current_iteration;
    };
    IterationProgress ComputeIterationProgressFromLocalTime(
        const base::Optional<base::TimeDelta>& local_time) const;

    // These methods are all based off of functionality defined by the Web
    // Animations specification.  They are all called internally by
    // ComputeIterationProgressFromLocalTime(), and are public primarily so that
    // they can be tested.
    base::Optional<base::TimeDelta> ComputeActiveTimeFromLocalTime(
        const base::Optional<base::TimeDelta>& local_time) const;
    base::Optional<base::TimeDelta> ComputeScaledActiveTimeFromActiveTime(
        const base::Optional<base::TimeDelta>& active_time) const;
    base::Optional<base::TimeDelta> ComputeIterationTimeFromScaledActiveTime(
        const base::Optional<base::TimeDelta>& scaled_active_time) const;
    base::Optional<base::TimeDelta> ComputeDirectedTimeFromIterationTime(
        const base::Optional<base::TimeDelta>& iteration_time,
        const base::Optional<double>& current_iteration) const;
    base::Optional<base::TimeDelta> ComputeTransformedTimeFromDirectedTime(
        const base::Optional<base::TimeDelta>& directed_time) const;
    base::Optional<double> ComputeIterationProgressFromTransformedTime(
        const base::Optional<base::TimeDelta>& transformed_time) const;

    base::Optional<double> ComputeCurrentIteration(
        const base::Optional<base::TimeDelta>& active_time,
        const base::Optional<base::TimeDelta>& scaled_active_time,
        const base::Optional<base::TimeDelta>& iteration_time) const;

    base::TimeDelta time_until_after_phase(base::TimeDelta local_time) const;

   private:
    enum Phase {
      kBeforePhase,
      kActivePhase,
      kAfterPhase,
      kNoPhase,
    };
    Phase GetPhase(const base::Optional<base::TimeDelta>& local_time) const;
    base::TimeDelta active_duration() const;
    base::TimeDelta start_offset() const;

    // delay_ here is sometimes referred to in the specs as "start delay".
    base::TimeDelta delay_;
    base::TimeDelta end_delay_;
    AnimationEffectTimingReadOnly::FillMode fill_;
    double iteration_start_;
    // iterations_ here is sometimes referred to in the specs as
    // "iteration count".
    double iterations_;
    // Note that the specs refer to duration here as "iteration duration".
    base::TimeDelta duration_;
    PlaybackDirection direction_;
    scoped_refptr<cssom::TimingFunction> easing_;
  };

  const Data& data() const { return data_; }

  DEFINE_WRAPPABLE_TYPE(AnimationEffectTimingReadOnly);

 protected:
  // While this is a read-only class, the data is not const because the
  // "ReadOnly" applies to the interface only, and non-read-only subclasses
  // may exist which extend the interface and allow writing.
  Data data_;

 private:
  ~AnimationEffectTimingReadOnly() override {}

  DISALLOW_COPY_AND_ASSIGN(AnimationEffectTimingReadOnly);
};

}  // namespace web_animations
}  // namespace cobalt

#endif  // COBALT_WEB_ANIMATIONS_ANIMATION_EFFECT_TIMING_READ_ONLY_H_
