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

#include "cobalt/renderer/rasterizer/common/streaming_best_fit_line.h"

#include <math.h>

#include <algorithm>

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

namespace {
const int kMaxPointWindowSize = 4;

Line FindBestFitLineFromPoints(const std::vector<math::PointF>& points) {
  DCHECK_LT(1, points.size());

  // Find the best fit least squares line through our set of |points|.
  // http://mathworld.wolfram.com/LeastSquaresFitting.html
  float sum_x = 0;
  float sum_xx = 0;
  float sum_y = 0;
  float sum_xy = 0;
  for (size_t i = 0; i < points.size(); ++i) {
    const math::PointF& point = points[i];
    sum_x += point.x();
    sum_y += point.y();
    sum_xx += point.x() * point.x();
    sum_xy += point.x() * point.y();
  }
  float denom = (points.size() * sum_xx - sum_x * sum_x);
  DCHECK_NE(0.0f, denom) << "It must be guaranteed that the points do not all "
                            "form a vertical line.";
  float inv_denom = 1.0f / denom;
  float best_fit_y_intercept = (sum_y * sum_xx - sum_x * sum_xy) * inv_denom;
  float best_fit_slope = (points.size() * sum_xy - sum_x * sum_y) * inv_denom;

  return Line(best_fit_y_intercept, best_fit_slope);
}
}  // namespace

void StreamingBestFitLine::AddValue(const math::PointF& point) {
  // First add the point to our point set.
  InsertPoint(point);

  DCHECK(!points_.empty());
  if (points_.size() > 1) {
    // Determine the best fit line based only on the points in our point set.
    Line best_fit_line = FindBestFitLineFromPoints(points_);

    // Possibly clamp the best fit line's y intercept and slope to non-negative
    // values.
    float new_y_intercept = force_non_negative_y_intercept_
                                ? std::max(0.0f, best_fit_line.y_intercept())
                                : best_fit_line.y_intercept();
    float new_slope = force_non_negative_slope_
                          ? std::max(0.0f, best_fit_line.slope())
                          : best_fit_line.slope();

    // Update our best estimate line's parameters.  Note that slope is
    // internally stored as an angle since linear combination is more stable
    // in that space.
    y_intercept_.AddValue(new_y_intercept);
    line_angle_radians_.AddValue(atan(new_slope));
  }
}

void StreamingBestFitLine::InsertPoint(const math::PointF& point) {
  // Our sliding window of points isn't exactly a simple sliding window.  In
  // order to ensure a diverse set of points in our point set, we first check
  // if an existing point shares our x coordinate and if so, we simply replace
  // that point.
  for (size_t i = 0; i < points_.size(); ++i) {
    if (points_[i].x() == point.x()) {
      // Shuffle all points down.
      size_t shuffle_to = i;
      size_t shuffle_from = (i + 1) % kMaxPointWindowSize;
      while (shuffle_from != next_point_position_) {
        points_[shuffle_to] = points_[shuffle_from];
        shuffle_to = shuffle_from;
        shuffle_from = (shuffle_from + 1) % kMaxPointWindowSize;
      }
      // Add our new point.
      points_[shuffle_to] = point;
      return;
    }
  }

  // If we get here, we have a point with a unique x-coordinate, so add it to
  // the end of our point window.
  if (points_.size() < kMaxPointWindowSize) {
    points_.push_back(point);
  } else {
    points_[next_point_position_] = point;
    next_point_position_ = (next_point_position_ + 1) % kMaxPointWindowSize;
  }
}

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