#include <stdio.h>
#include <string.h>
#include <ctype.h>
#ifndef _DEBUG
#define ALLEGRO_STATICLINK
#endif
#include <allegro.h>
#include "voice_mgr.h"

#define DEFAULT_FREQ	22050

VOICE_MGR *voice_load(char *filename)
{
	FILE *fp;
	char str[81];
	char path[256]="";
	char sample_path[256];
	int ret=!EOF, index, delay_count=0, phon_count=0, freq;
	VOICE_MGR *voice_mgr;

	// Open file
	fp=fopen(filename, "rb");

	if(!fp)
		return NULL;

	// Allocate the voice manager
	voice_mgr=calloc(sizeof(VOICE_MGR), 1);

	// Scan and count all "delay" and "phon" to get allophone count
	while(ret!=EOF)
	{
		ret=fscanf(fp, "%s", str);
		if(!ret)
			ret=EOF;

		if(!strcmp(str, "delay")||!strcmp(str, "phon"))
			phon_count++;
	}

	// Get name
	fseek(fp, 0, SEEK_SET);
	fscanf(fp, "%s", str);
	if(!strcmp(str, "name"))
	{
		fscanf(fp, "%s", str);
		sprintf(path, "allophones/%s/", str);
	}

	// Get frequency of samples
	fscanf(fp, "%s", str);
	if(!strcmp(str, "freq"))
	{
		fscanf(fp, "%d", &freq);
	}
	else
		voice_mgr->freq=DEFAULT_FREQ;

	// Allocate sample list
	voice_mgr->phon_list=(PHON_DEF*)calloc(sizeof(PHON_DEF),
		phon_count);

	voice_mgr->phon_count=phon_count;
	voice_mgr->freq=freq;

	voice_mgr->voice=speechy_init(voice_mgr->phon_count, voice_mgr->freq);
	if(!voice_mgr->voice)
	{
		free(voice_mgr);
		fclose(fp);
		return NULL;
	}

	// Load/add delays or allophones
	index=0;
	fseek(fp, 0, SEEK_SET);
	ret=!EOF;

	while(ret!=EOF)
	{
		ret=fscanf(fp, "%s", str);
		if(!ret)
		{
			ret=EOF;
			continue;
		}

		if(!strcmp(str, "delay"))
		{
			unsigned int delay;

			fscanf(fp, "%s", str);
			strncpy(voice_mgr->phon_list[index].name, str, 4);
			voice_mgr->phon_list[index].name[4]=0;

			fscanf(fp, "%d", &delay);

			speechy_add_silence(voice_mgr->voice, delay);
			index++;
		}
		else if(!strcmp(str, "phon"))
		{
			fscanf(fp, "%s", str);
			strncpy(voice_mgr->phon_list[index].name, str, 4);
			voice_mgr->phon_list[index].name[4]=0;

			fscanf(fp, "%s", str);
			sprintf(sample_path, "%s%s", path, str);

			voice_mgr->phon_list[index].sample=load_sample(sample_path);
			if(!voice_mgr->phon_list[index].sample)
			{
				speechy_add(voice_mgr->voice, NULL, 0, FALSE);
//				ret=EOF;
//				break;
			}
			else
			{
				speechy_add(voice_mgr->voice, 
					voice_mgr->phon_list[index].sample->data, 
					voice_mgr->phon_list[index].sample->len, FALSE);
			}

			index++;
		}
		else
		{
			// Ignore it
		}
	}
	
	// Set up VOICE_MGR struct

	fclose(fp);

	return voice_mgr;
}


void voice_unload(VOICE_MGR *voice_mgr)
{
	unsigned int i;

	for(i=0; i<voice_mgr->phon_count; i++)
	{
		if(voice_mgr->phon_list[i].sample)
			destroy_sample(voice_mgr->phon_list[i].sample);
	}

	free(voice_mgr->phon_list);
	free(voice_mgr);
}


int voice_parse(VOICE_MGR *voice_mgr, char *str, short *buf, unsigned int size)
{
	char *ptr=str;
	unsigned int count=0, i, pos=0, quit=FALSE;

	while(*ptr&&isspace(*ptr))
		ptr++;

	while(*ptr)
	{
		char *end=ptr;

		while(*end&&!isspace(*end))
			end++;

		for(i=0; i<voice_mgr->phon_count; i++)
		{
			char token[9];
			int len;

			len=(end-ptr<=8?(end-ptr):8);
			
			strncpy(token, ptr, len);
			token[len]=0;
			if(!strcmp(token, voice_mgr->phon_list[i].name))
			{
				buf[pos]=i;
				pos++;
				break;
			}

		}

		// Out of buffer space
		if(pos>=size)
		{
			pos-=1;
			break;
		}

		// Didn't find it
		else if(i>=voice_mgr->phon_count)
		{
			buf[pos]=ERR_SEQ_FLAG;
			pos++;
//			break;
		}

		ptr=end;
	
		while(*ptr&&isspace(*ptr))
			ptr++;
	}

	buf[pos]=END_SEQ;

	return pos;
}


