/* vim: set syntax=objc ts=4 sw=4 expandtab : */

/* C Includes */
#include <stdio.h>
#include <stdlib.h>

#import <objc/Object.h>
#import "CBuffer.h"

@implementation CBuffer : Object
+ new
{
    return [self new: 64];
}

+ new: ( int ) space
{
    CBuffer *cbuffer = (CBuffer *) [[self alloc] init];
    cbuffer->size = space;
    cbuffer->head = 0;
    cbuffer->tail = 0;
    cbuffer->data = (id *) malloc( sizeof( id ) * cbuffer->size );

    if ( cbuffer->data == NULL ) { return NULL; }

    return cbuffer;
}

- (id) free
{
    free( data );
    return [super free];
}

- ( int ) put: value
{
    if ( ( ( head + 1 ) % size ) == tail )
    {
        /* full buffer */
        return FALSE;
    }

    data[head++] = value;
    head = head % size;

    return TRUE;
}

- ( id ) get
{
    id temp;
    if ( head == tail )
    {
        /* empty buffer, nothing to return */
        return nil;
    }

    temp = data[tail];
    data[tail] = nil;
    tail = ++tail % size;

    return temp;
}

- ( int ) available
{
    if ( head == tail ) return size - 1;
    return ((head > tail) ? size - ( head - tail ) : tail - head) - 1;
/*
    return (head == tail ? size 
                         : head > tail ? size - (head - tail) 
                                       : tail - head
           ) - 1;
*/
}

- (void) dump
{
    int i;

    fprintf( stdout, "size = %d\nhead = %d\ntail = %d\n", size, head, tail);

    for ( i = 0; i < size; i++ )
    {
        fprintf( stdout, "(%d) = %p\n", i, data[i] );
    }
}

@end
