/* xyz */

/*
 * Copyright (c) 1997 by Wayne C. Gramlich.
 * All rights reserved.
 *
 * Permission to use, copy, modify, distribute, and sell this software
 * for any purpose is hereby granted without fee provided that the above
 * copyright notice and this permission are retained.  The author makes
 * no representations about the suitability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 */

/*
 * This file provide a bunch of interface routines for dealing xlib
 * {XPoints} objects.
 */

#ifndef XLIB_H
#include "xlib.h"
#endif

/* The initial object: */
Xlib_points_struct xlib_points___initial_object = {
    0,					/* Limit */
    0,					/* Size */
    (XPoint *)0				/* XPoints vector */
};
Xlib_points xlib_points___initial = &xlib_points___initial_object;

/*
 * xlib_points__address_get(points)
 *	This routine will return the address of {points}.
 */
unsigned
xlib_points__address_get(
    Xlib_points points)
{
    return (unsigned)points;
}
    
/*
 * xlib_points__append(points, x, y)
 *	This procedure will append ({x}, {y}) to {points}.
 */
void
xlib_points__append(
    Xlib_points points,
    int x,
    int y)
{
    unsigned limit;
    unsigned size;
    XPoint *xpoints;
    extern void *realloc(void *, size_t);

    limit = points->limit;
    size = points->size;
    xpoints = points->xpoints;

    if (size == limit) {
	if (limit == 0) {
	    limit = 1;
	    xpoints = (XPoint *)malloc(sizeof(XPoint));
	    points->xpoints = xpoints;
	} else {
	    limit = limit << 1;
	    xpoints =
	      (XPoint *)realloc((void *)xpoints, limit * sizeof(XPoint));
	}
	points->limit = limit;
    }

    /* Do the actual append: */
    xpoints[size].x = x;
    xpoints[size].y = y;
    size += 1;
    points->size = size;
}


/*
 * xlib_points__create()
 *	This procedure will allocate and return an {xlib_points} object.
 */
Xlib_points
xlib_points__create(void)
{
    Xlib_points points;

    points  = (Xlib_points)malloc(sizeof(*points));
    points->limit = 0;
    points->size = 0;
    points->xpoints = (XPoint *)0;
    return points;
}

/*
 * xlib_points__external__initialize()
 *	This routine will initialize the {Xlib_points} object:
 */
void
xlib_points__external__initialize(void)
{
    assert(xlib_points___initial == &xlib_points___initial_object);
}

/*
 * xlib_points__size_get(points)
 *	This procedure will return the number of points in {points}.
 */
unsigned
xlib_points__size_get(
    Xlib_points points)
{
    return points->size;
}

/*
 * xlib_points__trim(points, new_size)
 *	This procedure will trim the number of points in {points} to
 *	{new_size}.
 */
void
xlib_points__trim(
    Xlib_points points,
    unsigned new_size)
{
    assert(new_size <= points->size);
    points->size = new_size;
}

/*
 * xlib_points__x_fetch(points, index)
 *	This procedure will return the {index}'th x value from {points}.
 */
int
xlib_points__x_fetch(
    Xlib_points points,
    unsigned index)
{
    assert(index < points->size);
    return points->xpoints[index].x;
}

/*
 * xlib_points__x_store(points, index, x)
 *	This procedure will store {x} as the {index}'th x value
 *	in {points}.
 */
void
xlib_points__x_store(
    Xlib_points points,
    unsigned index,
    int x)
{
    assert(index < points->size);
    points->xpoints[index].x = x;
}

/*
 * xlib_points__y_fetch(points, index)
 *	This procedure will return the {index}'th y value from {points}.
 */
int
xlib_points__y_fetch(
    Xlib_points points,
    unsigned index)
{
    assert(index < points->size);
    return points->xpoints[index].y;
}

/*
 * xlib_points__y_store(points, index, y)
 *	This procedure will store {y} as the {index}'th y value
 *	in {points}.
 */
void
xlib_points__y_store(
    Xlib_points points,
    unsigned index,
    int y)
{
    assert(index < points->size);
    points->xpoints[index].y = y;
}



