#include "defines.h"

/****************************************************************/
/*	Quad-edge storage allocation
/****************************************************************/

/******************** Overall storage allocation ****************/

s_alloc(n)
int n;
{
    static int s_alloced = 0;

    if (s_alloced)   free((char*)sa);
    my_alloc( sa, struct SITE, n );
    s_alloced = 1;
}

ef_alloc(n)
int n;
{
    static int ef_alloced = 0;

    if (ef_alloced)
    {
        free((char*)org);
        free((char*)next);
        free((char*)ei);
	free((char*)fa);
    }
        /*  Allocate space for  3n  edges,  2n  triangles */
    my_alloc(org, SITE_PTR, 12*n );
    my_alloc(next, EDGE_PTR, 12*n );
    my_alloc(ei, struct EDGE_INFO, 3*n );
    my_alloc(fa, struct TRI, 2*n);
    ef_alloced = 1;
}

/*************************** Edge storage management *************************/

static EDGE_PTR next_edge, avail_edge;
#define NYL -1

delete_all_edges() { next_edge = 0; avail_edge = NYL;}

EDGE_PTR alloc_edge()
{
    EDGE_PTR ans;

    if (avail_edge == NYL) ans = next_edge, next_edge += 4;
    else ans = avail_edge, avail_edge = onext(avail_edge);
    return(ans);
}

free_edge(e)
EDGE_PTR e;
{
    e ^= e & 3;
    onext(e) = avail_edge;
    avail_edge = e;
}

EDGE_PTR
consolidate_edges()
{
    EDGE_PTR e;
    int i,j;

    while (avail_edge != NYL)
    {
	printf("Doing something in consolidate\n");

	next_edge -= 4; e = avail_edge; avail_edge = onext(avail_edge);

	if (e==next_edge)
	    continue; /* the one deleted was the last one anyway */
	if ((One_bndry_edge&~3) == next_edge)
	    One_bndry_edge = e | (One_bndry_edge&3);
	for (i=0,j=3; i<4; i++,j=rot(j))
	{
	    onext(e+i) = onext(next_edge+i);
	    if (onext(rot(onext(e+i))) != next_edge+j)
		printf("Bug in consolidate_edges %d,%d,%d,%d\n",i,j,e,next_edge);
	    onext(rot(onext(e+i))) = e+j; /*rotinv(e+i)*/
	    /*really want	oprev(onext(e+i)) = e+i */
	}
	info(e) = info(next_edge); 
    }
    return next_edge;
}

/**************************** Face storage alloc ****************************/
TRI_PTR next_tri, avail_tri;

delete_all_faces() { next_tri = 0; avail_tri = NYL;}

TRI_PTR alloc_tri()
{
    TRI_PTR ans;

    if (avail_tri == NYL) ans = next_tri, next_tri++;
    else ans = avail_tri, avail_tri = tnext(avail_tri);
    return(ans);
}

free_tri(t)
TRI_PTR t;
{
    tnext(t) = avail_tri;
    avail_tri = t;
}

new_inf_corner(e)
EDGE_PTR e;
{
    TRI_PTR t;

    t = alloc_tri();
    right(e) = t;
}

new_corner(e)
EDGE_PTR e;
{
    EDGE_PTR nex;

    new_inf_corner(e);
    for_rring_o(e,nex)
	right(nex)=right(e);
    end_rring_o(e,nex)
}
