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

    FILE....: APIFUNC.CPP
    TYPE....: C++ Module
    AUTHOR..: David Rowe
    DATE....: 24/6/98

    Some selected helper functions used to implement the API, does
    not correpond one to one with apifunc.h.


         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., 59 Temple Place, Suite 330, Boston, MA  02111-1307
	 USA

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

#include <assert.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#ifdef WIN32
#include <conio.h>
#endif

#include "apifunc.h"
#include "wobbly.h"

static int ErrorMode = VPB_EXCEPTION;
static FILE *f = NULL;

int WINAPI vpb_seterrormode( int mode )
{ //{{{
	switch( mode )
	{
	    case 0: //XXX VPB_DEVELOPMENT:
	    case 1: //VPB_ERROR_CODE:
	    case VPB_EXCEPTION:
		ErrorMode = mode;
		return VPB_OK;

	    default:
		return RunTimeError( Wobbly(VPBAPI_SETERRORMODE_MODE_INVALID),
				     "vpb_seterrormode" );
	}
} //}}}


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

	FUNCTION.: RunTimeError()
	AUTHOR...: David Rowe
	DATE.....: 5/3/98

	Helper function that deals with run time errors generated in API
	function call.  There are three error handling modes:
	
	  1. Development: Used by VT engineers when developing.  This mode
	     prints the error message to the screen using mprintf and kills
	     the application.
	  2. Error code: Causes API function to return an error code which
	     application can then check and interpret.
	  3. Exception: causes API function to throw another exception that
	     must be handled by application.  This enables application to
	     write exception handler and handle run time errors more 
	     efficiently than checking error codes after every API function 
	     call.

    Wobbly   w                  exception object thrown by run time error
    char     api_function[]     api function where exception occured

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

int RunTimeError(const Wobbly &w, const char *api_function)
{ //{{{
	char s[MAX_STR];
	w.translate(s);

	switch( ErrorMode )
	{
	    case 0: //XXX VPB_DEVELOPMENT:
		printf("exception caught: %s, file: %s line:%d\n", s, w.file,
								      w.line);
	      #ifdef WIN32
		printf("Press any key to finish....\n");
		while(!kbhit());
	      #endif
		exit(0);

	    case 1: //VPB_ERROR_CODE:
		return -w.code;

	    case VPB_EXCEPTION:
		throw VpbException(s, api_function);
	}
	// should never get to here
	assert(0);
	//return -1;
} //}}}

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

	FUNCTION.: apifunc_trace()
	AUTHOR...: David Rowe
	DATE.....: 10/10/98

	Prints trace messages to a file.

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

void apifunc_trace(char s[])
{
	// first time around open trace file

	if (f == NULL) {
		f = fopen("trace.txt","wt");
		assert(f != NULL);
	}

	fprintf(f, "%s", s);
	fflush(f);
	printf("%s", s);
}

size_t get_total_port_count()
{ //{{{
	// This should never change while this library instance
	// remains active, so only compute it once.
	static size_t total;

	if( total == 0 ) {
		for( int i = 0, n = vpb_get_num_cards(); i < n; ++i )
			total += vpb_get_ports_per_card(i);
	}
	return total;
} //}}}

