// Copyright 2024 SquareBlock Inc. All Rights Reserved.
// Author: tianlei.richard@qq.com (tianlei.richard)

#pragma once

#include "mesh.h"
#include "util/math_util.h"
#include <opencv2/core/core.hpp>

class MinusRenderer {
public:
  MinusRenderer(float near, float far, float fov, float aspect_ratio);

public:
  void set_meshes(const std::vector<Mesh> &meshes);

  cv::Mat render(const int resolution_width, const int resolution_height);

public:
  void model_transform(const TransformMatrix &mtx);
  void view_transform(const TransformMatrix &mtx);

private:
  static float calculate_height(const float fov, const float near);
  static float calculate_width(const float height, const float ratio);
  static TransformMatrix view_port_transform(const float width,
                                             const float height);
  static std::tuple<double, double, double>
  calculate_barycentric_coordinate(const Triangle &t, const Point2d &p);

private:
  TransformMatrix squish_transform();
  TransformMatrix orthographic_transform();

private:
  float near_;
  float far_;
  float fov_; // In radian
  float aspect_ratio_;

  TransformMatrix projection_matrix_;

  std::vector<Mesh> meshes_;
};
