#include <shinobi.h>
#include <kamui2.h>
#include <kmutil.h>
#include <string.h>
#include "dispstrex.h"
#include "command.h"

COMMANDCONTROL Command;

static char *argv[16];

void InitializeCommand()
{
	int i;
	Command.RegistTop 			= NULL;
	Command.nRegistratedCommand = 0;
	for(i = 0; i < 16; i++)
	{
		argv[i] = (char *)syMalloc(256);
	}
}

int RegisterCommand(		PCOMMANDFUNC pFunc, 
							PKMCALLBACKFUNC pPreprocess, 
							PKMVOID pData, 
							PKMCALLBACKFUNC pDrawFunc, 
							char* pszName)
{
	PCOMMANDSTRUCT pNewCommand, pCurrent;
	pNewCommand = (PCOMMANDSTRUCT)syMalloc(sizeof(COMMANDSTRUCT));
	if(pNewCommand == NULL ) return -1;

	pNewCommand->pCommand 		= pFunc;
	pNewCommand->pDrawFunc 		= pDrawFunc;
	pNewCommand->pPreprocess 	= pPreprocess;
	pNewCommand->pData			= pData;
	pNewCommand->Attrib			= CONSOLECOMMAND_ACTIVE;
	strcpy(pNewCommand->CommandName, pszName);

	if(Command.nRegistratedCommand == 0)
	{
		pNewCommand->pPrev = NULL;
		pNewCommand->pNext = NULL;
		Command.RegistTop = pNewCommand;
	}
	else
	{
		pCurrent = Command.RegistTop;
		while(pCurrent->pNext) pCurrent = (PCOMMANDSTRUCT)pCurrent->pNext;
		pCurrent->pNext 	= (PKMVOID)pNewCommand;
		pNewCommand->pPrev 	= (PKMVOID)pCurrent;
		pNewCommand->pNext	= NULL;
	}

	Command.nRegistratedCommand++;
	return Command.nRegistratedCommand;
}

int ExecuteCommand(char *pszCommandLine)
{
	PCOMMANDSTRUCT pCommand;
	int argc = 0;
	char *pCurrent;
	if (*pszCommandLine == '\0') return -1;	/* NULL COMMAND */

	pCurrent = strtok(pszCommandLine," ");
	strcpy(argv[argc], pCurrent);				/* argv[0] is command name */
	argc++;
	while((pCurrent = strtok(NULL," ")) != NULL)
	{
		strcpy(argv[argc], pCurrent);
		argc++;
		if(argc > 15) break;
	}

	pCommand = Command.RegistTop;
	do
	{
		if(strcmp(pCommand->CommandName, argv[0]) == 0)
		{
			(pCommand->pCommand)(argc, &argv[0]);
			return argc;
		}
	}while((pCommand = (PCOMMANDSTRUCT)pCommand->pNext) != NULL);

	PRINTOUT(("Command is not found\n"));
	return -2;
}

int ExecutePreprocess(void)
{
	PCOMMANDSTRUCT pCommand;

	pCommand = Command.RegistTop;
	do
	{
		if(	pCommand->pPreprocess && pCommand->Attrib == CONSOLECOMMAND_ACTIVE)
			(pCommand->pPreprocess)(pCommand->pData);

	}while((pCommand = (PCOMMANDSTRUCT)pCommand->pNext) != NULL);
	return 0;
}

int ExecuteDrawCommand(PKMVERTEXBUFFDESC pBuffDesc)
{
	PCOMMANDSTRUCT pCommand;

	pCommand = Command.RegistTop;
	do
	{
		if(pCommand->pDrawFunc && pCommand->Attrib == CONSOLECOMMAND_ACTIVE)
			(pCommand->pDrawFunc)(pBuffDesc);

	}while((pCommand = (PCOMMANDSTRUCT)pCommand->pNext) != NULL);
	return 0;
}

