// Copyright 2016 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.

#ifndef LIB_MEDIA_CPP_TIMELINE_FUNCTION_H_
#define LIB_MEDIA_CPP_TIMELINE_FUNCTION_H_

#include <lib/media/cpp/timeline_rate.h>
#include <zircon/assert.h>

namespace media {

// TODO(dalesat): Consider always allowing inexact results.

// A linear function from int64_t to int64_t with non-negative slope that
// translates reference timeline values into subject timeline values (the
// 'subject' being the timeline that's represented by the function). The
// representation is in point-slope form. The point is represented as two
// int64_t time values (subject_time, reference_time), and the slope (rate) is
// represented as a TimelineRate, the ratio of two uint32_t values
// (subject_delta / reference_delta).
class TimelineFunction final {
 public:
  // Applies a timeline function.
  static int64_t Apply(int64_t subject_time, int64_t reference_time,
                       TimelineRate rate,  // subject_delta / reference_delta
                       int64_t reference_input);

  // Applies the inverse of a timeline function.
  static int64_t ApplyInverse(int64_t subject_time, int64_t reference_time,
                              TimelineRate rate,  // subject_delta / reference_delta
                              int64_t subject_input) {
    ZX_DEBUG_ASSERT(rate.reference_delta() != 0u);
    return Apply(reference_time, subject_time, rate.Inverse(), subject_input);
  }

  // Composes two timeline functions B->C and A->B producing A->C. If exact is
  // true, DCHECKs on loss of precision.
  static TimelineFunction Compose(const TimelineFunction& bc, const TimelineFunction& ab,
                                  bool exact = true);

  TimelineFunction() : subject_time_(0), reference_time_(0) {}

  TimelineFunction(int64_t subject_time, int64_t reference_time, uint32_t subject_delta,
                   uint32_t reference_delta)
      : subject_time_(subject_time),
        reference_time_(reference_time),
        rate_(subject_delta, reference_delta) {}

  TimelineFunction(int64_t subject_time, int64_t reference_time, TimelineRate rate)
      : subject_time_(subject_time), reference_time_(reference_time), rate_(rate) {}

  explicit TimelineFunction(TimelineRate rate)
      : subject_time_(0), reference_time_(0), rate_(rate) {}

  // Determines whether this |TimelineFunction| is invertible.
  bool invertible() const { return rate_.invertible(); }

  // Applies the function. Returns TimelineRate::kOverflow on overflow.
  int64_t Apply(int64_t reference_input) const {
    return Apply(subject_time_, reference_time_, rate_, reference_input);
  }

  // Applies the inverse of the function. Returns TimelineRate::kOverflow on
  // overflow.
  int64_t ApplyInverse(int64_t subject_input) const {
    ZX_DEBUG_ASSERT(rate_.reference_delta() != 0u);
    return ApplyInverse(subject_time_, reference_time_, rate_, subject_input);
  }

  // Applies the function.  Returns TimelineRate::kOverflow on overflow.
  int64_t operator()(int64_t reference_input) const { return Apply(reference_input); }

  // Returns a timeline function that is the inverse of this timeline function.
  TimelineFunction Inverse() const {
    ZX_DEBUG_ASSERT(rate_.reference_delta() != 0u);
    return TimelineFunction(reference_time_, subject_time_, rate_.Inverse());
  }

  int64_t subject_time() const { return subject_time_; }

  int64_t reference_time() const { return reference_time_; }

  const TimelineRate& rate() const { return rate_; }

  uint32_t subject_delta() const { return rate_.subject_delta(); }

  uint32_t reference_delta() const { return rate_.reference_delta(); }

 private:
  int64_t subject_time_;
  int64_t reference_time_;
  TimelineRate rate_;  // subject_delta / reference_delta
};

// Tests two timeline functions for equality. Equality requires equal basis
// values.
inline bool operator==(const TimelineFunction& a, const TimelineFunction& b) {
  return a.subject_time() == b.subject_time() && a.reference_time() == b.reference_time() &&
         a.rate() == b.rate();
}

// Tests two timeline functions for inequality. Equality requires equal basis
// values.
inline bool operator!=(const TimelineFunction& a, const TimelineFunction& b) { return !(a == b); }

// Composes two timeline functions B->C and A->B producing A->C. DCHECKs on
// loss of precision.
inline TimelineFunction operator*(const TimelineFunction& bc, const TimelineFunction& ab) {
  return TimelineFunction::Compose(bc, ab);
}

}  // namespace media

#endif  // LIB_MEDIA_CPP_TIMELINE_FUNCTION_H_
