/*---------------------------------------------------------------------------*\

    FILE....: OBJTRACK.CPP
    TYPE....: C++ Module
    AUTHOR..: David Rowe
    DATE....: 25/3/98

    This module maintains a database of the VPB configuration manager
    objects.  This database is used to determine a device handle 
    (channel) from an object and board, or vice versa.


         Voicetronix Voice Processing Board (VPB) Software
         Copyright (C) 1999-2007 Voicetronix www.voicetronix.com.au

         This library is free software; you can redistribute it and/or
         modify it under the terms of the GNU Lesser General Public
         License as published by the Free Software Foundation; either
         version 2.1 of the License, or (at your option) any later version.

         This library is distributed in the hope that it will be useful,
         but WITHOUT ANY WARRANTY; without even the implied warranty of
         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
         Lesser General Public License for more details.

         You should have received a copy of the GNU Lesser General Public
         License along with this library; if not, write to the Free Software
         Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
         MA  02110-1301  USA

\*---------------------------------------------------------------------------*/

#include <assert.h>

#include "objtrack.h"
#include "apifunc.h"
#include "mapdev.h"
#include "mess.h"


typedef struct OBJS {
	unsigned short	cls;		// class of object
	unsigned short	id;		// id of object on this board
	unsigned short	handle;		// handle of channel
	unsigned short	b;		// board number
	struct	OBJS *next;	// next object in linked list	
} OBJ;


static OBJ *start;		// first object in linked list
static OBJ *end;		// last object in linked list
static int opened=0;


void objtrack_open() {
	if (!opened){
		start = NULL;
		end = NULL;
		opened = 1;
	}
}

void objtrack_close() {
	OBJ	*po = start;
	OBJ	*d;

	// delete all objects in linked list

	while(po != NULL) {
		d = po;
		po = po->next;
		delete d;
	}
	opened = 0;
}

void objtrack_add_object(unsigned short cls, int id, int handle, unsigned short b)
{
	OBJ	*po;

	po = new OBJ;
	po->cls = cls;
	po->handle = handle;
	po->b = b;
	po->id = id;
	po->next = NULL;

	// attach new object to end of list

	if (start == NULL) {
		start = end = po;
	}
	else {
		end->next = po;
		end = po;
	}
//	mprintf("ObjTrack: added cls(%d) id(%d) b(%d) h(%d)\n",cls,id,b,handle);
}

int objtrack_id_to_handle(unsigned short cls, int id, unsigned short b)
{ //{{{
	OBJ	*po = start;

	switch( vpb_c->vpbreg(b)->model )
	{
	    case VPB_OPCI:
	    case VPB_OSW:
	    case VPB_PRI:
		return mapdevtohndle(b,id);

	    case VPB_V4PCI:
	    case VPB_V4LOG: break;

	    case VPB_MODEL_UNKNOWN:
		throw VpbException("objtrack_id_to_handle: unknown model type");
	}
	while(po != NULL) {
		if( po->cls == cls && po->id == id &&  po->b == b )
			return po->handle;
		po = po->next;
	}

	mprintf("ObjTrack: Cant find cls(%d) id(%d) b(%d)\n",cls,id,b);
	assert(0);
	return 0;
} //}}}

int objtrack_handle_to_id(unsigned short cls, int handle)
{
	OBJ	       *po = start;
	unsigned short	bd,ch;
	maphndletodev(handle,&bd,&ch);

//	mprintf("objtrack_handle_to_id: h[%d] => ch[%d] bd[%d]\n",handle,ch,bd);

	switch( vpb_c->vpbreg(bd)->model )
	{
	    case VPB_OPCI:
	    case VPB_OSW:
	    case VPB_PRI:
		return ch;

	    case VPB_V4PCI:
	    case VPB_V4LOG: break;

	    case VPB_MODEL_UNKNOWN:
		throw VpbException("objtrack_id_to_handle: unknown model type");
	}

	while(po != NULL) {
		if( po->cls == cls && po->handle == handle )
			return po->id;
		po = po->next;
	}
	assert(0);
	return 0;
}

