/* Listing 6*/
/*----------------- PINLIST.H--------------------*/
#include "pinnacle.h"
#include "list.h"

#define PINNACLE_LIST_CLASS       LIST_CLASS \
/* Pinnacle Database Object */        DB db; \
/*Pinnacle Database Table */	DBTAB table; \
/* Boolean flags*/     unsigned is_at_top, is_at_bottom;

typedef struct pinnacle_list {
    PINNACLE_LIST_CLASS
} PINNACLE_LIST;

PINNACLE_LIST *new_pinnacle_list(char *database,
char *table);

/*------------------- PINLIST.C ------------------*/
#include "pinlist.h"

static long total_members(PINNACLE_LIST *this) {
    return((long) DB_CountRows(this->table));
}

static unsigned at_top(PINNACLE_LIST *this) {
    return(this->is_at_top);
}

static unsigned at_end(PINNACLE_LIST *this) {
    return(this->is_at_bottom);
}

static void prev(PINNACLE_LIST *this) {
    if (DB_NextRow(this->table, DBPREVIOUS))
        this->is_at_top = FALSE;
    else
        this->is_at_top = TRUE;
    if (this->total_members(this) > 1)
        this->is_at_bottom = FALSE;
}

static void next(PINNACLE_LIST *this) {
    if (DB_NextRow(this->table, DBNEXT))
       this->is_at_bottom = FALSE;
    else
       this->is_at_bottom = TRUE;
    if (this->total_members(this) > 1)
        this->is_at_top = FALSE;
}


static void top(PINNACLE_LIST *this) {
    DB_FirstRow(this->table);
    DB_NextRow(this->table,DBNEXT);
    this->is_at_top = TRUE;
    if (this->total_members(this) > 1)
        this->is_at_bottom = FALSE;
}

static void end(PINNACLE_LIST *this) {
    DB_ForAllRows(this->table);
    this->is_at_bottom = TRUE;
    if (this->total_members(this) > 1)
	this->is_at_top = FALSE;
}

static long tell(PINNACLE_LIST *this) {
    DBROWID thisrow, checkrow;
    long position = 0L;

    thisrow = DB_CurrentRow(this->table);
    this->top(this);
    checkrow = DB_CurrentRow(this->table);
    while(checkrow != thisrow) {
        ++position;
        DB_NextRow(this->table,DBNEXT);
        checkrow = DB_CurrentRow(this->table);
    }
    return(position);
}

PINNACLE_LIST *new_pinnacle_list(char *datab,char *table) {
PINNACLE_LIST *this;
LIST *l;

l = new_list();
if (l == NULL)
   return(NULL);

this = calloc(1,sizeof(PINNACLE_LIST));
if (this == NULL) {
    destroy_list(l);  return(NULL);
}
memmove(this,l,sizeof(LIST)); free(l);

this->db = DB_Open(datab,"rw",0);
this->table = DB_Table(this->db,table);
this->total_members = total_members;
this->at_top = at_top; this->at_end = at_end;
this->prev = prev; this->next = next;
this->top = top; this->end = end; this->tell = tell;

return(this);
}

destroy_pinnacle_list(PINNACLE_LIST *this) {
DB_Close(this->db); destroy_list(this);
}
