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

    FILE....: prilog.cpp
    TYPE....: C++ Console program
    AUTHOR..: Ben Kramer
    DATE....: 20/07/05


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

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

         Voicetronix Voice Processing Board (VPB) Software

         Copyright (C) 1999-2005 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#include "vpbapi.h"
#include "verbose.h"
#include "../kbhit.h"
#include "../threads.h"

void *port_thread(void *pv);

int             threads_active; // the number of active threads.
pthread_mutex_t mutex;          // mutex to protect shared data
int             finito;         // flag to signal the program is finished.
float           gain;           // option software record gain
int		LV=0;

static int arg_exists(int argc, char *argv[], const char *arg)
{ //{{{
	for(int i = 0; i < argc; ++i)
		if(strcmp(argv[i],arg) == 0) return i;

	return 0;
} //}}}

int main(int argc, char * argv[])
{
	int		*h;
	int		x,j,i,y,k;
	VPB_RECORD	record;
	pthread_t       *aport_thread;

	verbose(1);
	record.term_digits = "";
	record.time_out = 0;
	pthread_mutex_init(&mutex,NULL);
	finito = 0;

	// count the cards and ports
	int num_cards = vpb_get_num_cards();
	int num_ch = 0;

	int ports_per_card[num_cards];

	for (int i = 0; i < num_cards; ++i)
		num_ch += (ports_per_card[i] = vpb_get_ports_per_card(i));

	printf("Found [%d] channels...\n",num_ch);

	h = new int[num_ch];
	aport_thread = new pthread_t[num_ch];

	// now init each port and start one thread per port
	x=0;
	for(i=0; i<num_cards; i++) {
		for(j=0;j<ports_per_card[i];j++){
			h[x] = vpb_open(i,j);
			vpb_sethook_sync(h[x],VPB_ONHOOK);
			vpb_record_set(h[x], &record);
			y=arg_exists(argc, argv, "--hookthreshold");
			if((y != 0) && ((y+1) <argc))
			{
				k = atoi(argv[y+1]);
				if((k>2) && (k<128))
				{
					vpb_loopvolt_set_threshold(h[x], k);
					LV=1;
				}
				else
					printf("Range error for hook threshold (%d)\n",k);
			}
			y=arg_exists(argc, argv, "--hookwindow");
			if((y != 0) && ((y+1) <argc))
			{
				k = atoi(argv[y+1]);
				LV=1;
				vpb_loop_set_onhookwindow(h[x], k);
				vpb_loop_set_offhookwindow(h[x], k);
			}
			pthread_create(&aport_thread[x], NULL, port_thread, (void*)&h[x]);
			x++;
		}
	}
	printf("%d ports opened!\n", num_ch);

	// do nothing in main loop until return pressed
	while(!kbhit()){
		vpb_sleep(500);
	}
	finito = 1;

	printf("shutting down....\n");
	while(threads_active) {
		vpb_sleep(100);
		printf("threads active: %d\r", threads_active);
	}

	for(i=0; i<num_ch; i++) {
		vpb_close(h[i]);
	}
	delete h;

	return 0;
}

void *port_thread(void *pv)
{
	int       h = *(int*)pv;
	char      file_name[VPB_MAX_STR];
	int	ret;
	VPB_EVENT e;
	char      s[VPB_MAX_STR];
	int	state=0;

	pthread_mutex_lock(&mutex);
	threads_active++;
	pthread_mutex_unlock(&mutex);
	sprintf(file_name,"linear%02d.wav",h);
	while(!finito) {

		ret = vpb_get_event_ch_sync(h, &e,6000);
		if (ret == VPB_OK){
			vpb_translate_event(&e, s);
			printf("%s",s);
			if ((e.type == VPB_ISDN_ANS) && (state ==0)){
				vpb_record_file_async(h, file_name, VPB_LINEAR);
				printf(")*( Started Recording!\n");
				state=1;
			} else if ((e.type == VPB_DROP)&&(state ==1)){
				vpb_record_terminate(h);
				printf("(*) Stoped Recording!\n");
				state=0;
			}
		}
	}

	pthread_mutex_lock(&mutex);
	threads_active--;
	pthread_mutex_unlock(&mutex);

	return NULL;
}

