/*
 * Copyright 2016 Google Inc. 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_RENDERER_RASTERIZER_COMMON_STREAMING_BEST_FIT_LINE_H_
#define COBALT_RENDERER_RASTERIZER_COMMON_STREAMING_BEST_FIT_LINE_H_

#include <math.h>

#include <vector>

#include "cobalt/math/exponential_moving_average.h"
#include "cobalt/math/point_f.h"

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace common {

// Represents a line that is a valid function (i.e. its slope is not infinity).
// Primarily used as the result of StreamingBestFitLine.
class Line {
 public:
  Line(float y_intercept, float slope)
      : y_intercept_(y_intercept), slope_(slope) {}

  float value_at(float x) const { return y_intercept_ + slope_ * x; }
  float y_intercept() const { return y_intercept_; }
  float slope() const { return slope_; }

 private:
  float y_intercept_;
  float slope_;
};

// StreamingBestFitLine takes a sequence of points provided via calls to
// AddValue() and internally fits a line to these points, which can be obtained
// by a call to line().  Every time AddValue() is called, a sliding window of
// a constant number of points is updated and a best fit line that minimizes
// the sum of squared differences from the points to the line is calculated.
// The new best fit line's parameters are then used to slightly adjust
// exponential moving averages for |y_intercept_| and |line_angle_radians_|, to
// smooth out changes to the line.
class StreamingBestFitLine {
 public:
  // |new_value_weight| is forwarded into the constructors for the
  // ExponentialMovingAverage members of this class and affects how slowly the
  // line estimate adjusts to new data.  If |force_non_negative_slope| is true,
  // the best estimate line's slope will be clamped to non-negative values.
  // If |force_non_negative_y_intercept| is true, the best estimate line's
  // y intercept will be clamped to non-negative values.
  explicit StreamingBestFitLine(float new_value_weight,
                                bool force_non_negative_slope,
                                bool force_non_negative_y_intercept)
      : force_non_negative_slope_(force_non_negative_slope),
        force_non_negative_y_intercept_(force_non_negative_y_intercept),
        y_intercept_(new_value_weight),
        line_angle_radians_(new_value_weight),
        next_point_position_(0) {}

  // Returns our current best estimate at the line.  Note that we translate
  // the internally stored line angle back into slope.
  Line best_estimate() const {
    return Line(*y_intercept_.average(), tan(*line_angle_radians_.average()));
  }

  // Adds a new point and updates the internal line estimate to reflect the new
  // data.
  void AddValue(float x, float y) { AddValue(math::PointF(x, y)); }
  void AddValue(const math::PointF& point);

 private:
  // Helper function to add a new point to the list of points.
  void InsertPoint(const math::PointF& point);

  const bool force_non_negative_slope_;
  const bool force_non_negative_y_intercept_;

  math::ExponentialMovingAverage<float> y_intercept_;
  math::ExponentialMovingAverage<float> line_angle_radians_;

  // Our set of recent points.
  std::vector<math::PointF> points_;

  // Describes where within |points_| the next unique point should be inserted.
  int next_point_position_;
};

}  // namespace common
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt

#endif  // COBALT_RENDERER_RASTERIZER_COMMON_STREAMING_BEST_FIT_LINE_H_
