#include "demo.h"

/*
  Allocate a big pile of everything we need.

  The get_new_* functions will pick the next unused entry.

  polys in particular benefit from this, as we can use plain pointers
  to set the render range.
*/

int max_verts = 1000000;
int used_verts = 0;
vert_t * all_verts = NULL;

int max_edges = 1000000;
int used_edges = 0;
edge_t * all_edges = NULL;

int max_polys = 1000000;
int used_polys = 0;
poly_t * all_polys = NULL;

int max_trans = 1000000;
int used_trans = 0;
trans_t * all_trans = NULL;



void alloc_all()
{
  all_verts = malloc(sizeof(vert_t) * max_verts);
  all_edges = malloc(sizeof(edge_t) * max_edges);
  all_polys = malloc(sizeof(poly_t) * max_polys);
  all_trans = malloc(sizeof(trans_t) * max_trans);

  if (!all_verts || !all_edges || !all_polys || !all_trans)
  {
    free_all();
    
    gfx_shutdown();
  }

  return;
}



void free_all()
{
  free(all_verts);
  free(all_edges);
  free(all_polys);
  free(all_trans);
}



vert_t * get_new_vert()
{
  if (used_verts >= max_verts)
  {
    printf("ERROR: Ran out of vertices");
    exit(1);
  }

  return &all_verts[used_verts++];
}



edge_t * get_new_edge()
{
  if (used_edges >= max_edges)
  {
    printf("ERROR: Ran out of edges");
    exit(1);
  }

  return &all_edges[used_edges++];
}



poly_t * get_new_poly()
{
  if (used_polys >= max_polys)
  {
    printf("ERROR: Ran out of polys");
    exit(1);
  }

  return &all_polys[used_polys++];
}



trans_t * get_new_trans(void)
{
  if (used_trans >= max_trans)
  {
    printf("ERROR: Ran out of trans");
    exit(1);
  }

  trans_t * ret = &all_trans[used_trans++];

  ret->frame = 0;
  ret->delay = 1;
  ret->length = 1;

  ret->custom_func = NULL;
  ret->custom_arg = NULL;

  ret->dest_i = NULL;
  ret->dest_f = NULL;
  ret->dest_c = NULL;
  
  ret->inertia_chain = NULL;
  ret->inertia = false;

  ret->curve = CURVE_LINEAR;
  
  ret->vel_f = 0;
  ret->acc_f = 0;
  
  return ret;
}
