// Copyright (c) 2022 Dominic Masters
// 
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

#pragma once
#include "dawn.hpp"

namespace Dawn {
  enum MeshDrawMode {
    TRIANGLES,
    TRIANGLE_STRIP,
    TRIANGLE_FAN,
    LINES,
    POINTS
    // LINE_STRIP,
  };

  class IMesh {
    protected:
      /** How many vertices are in the mesh */
      int32_t verticeCount = -1;
      /** How many indices are in the mesh */
      int32_t indiceCount = -1;

    public:
      /**
       * Create a new set of buffers for the mesh to use.
       * 
       * @param verticeCount How many Vertices will this buffer support.
       * @param indiceCount How many Indices will this buffer support.
       */
      virtual void createBuffers(
        const int32_t verticeCount,
        const int32_t indiceCount
      ) = 0;
      
      /**
       * Cleanup the buffers on a given mesh. This is useful if you intend to
       * expand the count of vertices your mesh supports.
       */
      virtual void disposeBuffers() = 0;

      /**
       * Write vertice positions to the mesh.
       * 
       * @param pos Position, within the buffer, to write to.
       * @param vertices Array of positions to write.
       * @param len How many positions are in the array.
       */
      virtual void bufferPositions(
        const int32_t pos,
        const glm::vec3 positions[],
        const int32_t len
      ) = 0;

      /**
       * Write vertice coordinates to the mesh.
       * 
       * @param pos Position, within the buffer, to write to.
       * @param coordinates Array of coordinates to write.
       * @param len How many coordinates are in the array.
       */
      virtual void bufferCoordinates(
        const int32_t pos,
        const glm::vec2 coordinates[],
        const int32_t len
      ) = 0;

      /**
       * Write indices to the mesh.
       * 
       * @param pos Position, within the buffer, to write to.
       * @param indices Array of indices to write.
       * @param len How many indices are in the array.
       */
      virtual void bufferIndices(
        const int32_t pos,
        const int32_t indices[],
        const int32_t len
      ) = 0;

      /**
       * Draw a primitive. Primitives are drawn by their indices.
       * 
       * @param drawMode Which drawing mode to use to draw the primitive.
       * @param start Start indice (index) to draw.
       * @param count Count of indices to draw. Use -1 to draw all.
       */
      virtual void draw(
        const enum MeshDrawMode drawMode,
        const int32_t start,
        const int32_t count
      ) = 0;

      /**
       * Cleanup a previously initiated mesh.
       */
      virtual ~IMesh() {
      }
  };
}