#include "math/math.hpp"

#include "platform/ta_parameter_presets.hpp"
#include "platform/texture.hpp"

#define _fsrra(n) (1.0f / (sqrt<float>(n)))
static inline void draw_line(ta_parameter_writer& writer,
                             const vec3& p1,
                             const vec3& p2)
{
  float dy = p2.y - p1.y;
  float dx = p2.x - p1.x;
  float d = _fsrra(dx * dx + dy * dy) * 0.5f;
  float dy1 = dy * d;
  float dx1 = dx * d;

  vec3 ap = { p1.x +  dy1, p1.y + -dx1, p1.z };
  vec3 bp = { p1.x + -dy1, p1.y +  dx1, p1.z };
  vec3 cp = { p2.x + -dy1, p2.y +  dx1, p2.z };
  vec3 dp = { p2.x +  dy1, p2.y + -dx1, p2.z };

  const float intensity = 1.0f;
  quad_type_2(writer,
              ap,
              bp,
              cp,
              dp,
              intensity);
}
#undef _fsrra

static inline void draw_grid(ta_parameter_writer& writer,
                             const mat4x4& trans)
{
  const vec3 color = {0, 1, 1};
  global_polygon_intensity(writer, color);

  for (int i = 1; i < 10; i++) {
    float x = (float)i * 0.1f - 0.5f;

    if (0) {
      vec3 p1 = screen_transform(trans * vec3(x, 0, 0.5));
      vec3 p2 = screen_transform(trans * vec3(x, 0, -0.5));
      draw_line(writer, p1, p2);
    }
    {
      vec3 p1 = screen_transform(trans * vec3(0.5, 0, x));
      vec3 p2 = screen_transform(trans * vec3(-0.5, 0, x));
      draw_line(writer, p1, p2);
    }
  }
}

static inline void draw_axis(ta_parameter_writer& writer,
                             const mat4x4& trans)
{

  vec3 origin = screen_transform(trans * vec3(0, 0, 0));
  vec3 x_axis = screen_transform(trans * vec3(1, 0, 0));
  vec3 y_axis = screen_transform(trans * vec3(0, 1, 0));
  vec3 z_axis = screen_transform(trans * vec3(0, 0, 1));

  global_polygon_intensity(writer, {1, 0, 0});
  draw_line(writer,
            origin,
            x_axis);

  global_polygon_intensity(writer, {0, 1, 0});
  draw_line(writer,
            origin,
            y_axis);

  global_polygon_intensity(writer, {0, 0, 1});
  draw_line(writer,
            origin,
            z_axis);
}

void draw_cube(ta_parameter_writer& writer,
               const mat4x4& trans,
               const vec3& color);

void draw_textured_cube(ta_parameter_writer& writer,
                        const mat4x4& trans,
                        const vec3& scale,
                        const texture::cube_texture_offsets& offsets,
                        const vec3& base_color,
                        float intensity_offset);

void draw_textured_cube2(ta_parameter_writer& writer,
                         const mat4x4& trans,
                         int texture_offset1,
                         int texture_offset2,
                         float transition);

void draw_icosphere(ta_parameter_writer& writer,
                    const mat4x4& trans,
                    const vec3& color);

void draw_plane(ta_parameter_writer& writer,
                const vec3& k,
                const vec3& n,
                const mat4x4& trans,
                const vec3& color);

void draw_halfspace(ta_parameter_writer& writer,
                    const vec3& k,
                    const vec3& n,
                    const mat4x4& trans,
                    const vec3& color);

void draw_textured_voxel(ta_parameter_writer& writer,
                         const mat4x4& trans,
                         int texture_offset);

void draw_lizard_mv(ta_parameter_writer& writer,
                    const mat4x4& trans);
