/*********************************************************************

Name:		Raytracer
Author:		Kamil Szatkowski "Netrix" (C)
Website:	http://www.netrix.org.pl/

*********************************************************************/
#include "CommandWalker.hpp"
#include "NLib/nBase.hpp"
#include <stdio.h>

namespace
{
	const NIne::NUint32 VECTOR_REALLOC = 4;

	// Looks for second string at the begining of first string
	inline bool stratb(const char* first, const char* second)
	{
		while(*first != 0 && *second != 0 && *first == *second)
		{
			++first;
			++second;
		}

		return *second == 0;
	}
}

CommandWalker::CommandWalker(int argc, const char* argv[])
	: m_arguments(argc, argv)
	, m_pDefaultAction(null)
{
	m_vCommands.Create(VECTOR_REALLOC, VECTOR_REALLOC);
}

CommandWalker::~CommandWalker()
{
	if(m_vCommands) { m_vCommands.Release(); }
}

void CommandWalker::AddCommand(const char* szCommand, const char* szHelp, CommandCallback pCallback)
{
	Command c =
	{
		szCommand,
		szHelp,
		pCallback
	};

	m_vCommands.PushElement(c);
}

void CommandWalker::AddDefault(CommandCallback pCallback)
{
	m_pDefaultAction = pCallback;
}

bool CommandWalker::ParseCommands()
{
	bool bValid = false;	// First time use indicates whether any command was parsed

	while(!bValid && m_arguments.IsValid())
	{
		const char* szArg = m_arguments.GetActualArgument();
		
		bool bFound = false;
		for(size_t i = 0; !bFound && !bValid && i < m_vCommands.GetSize(); ++i)
		{
			// Checking if string contains another string at the begin
			if(stratb(szArg, m_vCommands[i].szCommand))
			{
				bValid = m_vCommands[i].pCallback(m_arguments);
				i = m_vCommands.GetSize();
				bFound = true;
			}
		}

		// Default action
		if(!bFound && !bValid && m_pDefaultAction != null)
		{
			bValid = m_pDefaultAction(m_arguments);
		}

		m_arguments.NextArgument();
	}

	return bValid;
}

void CommandWalker::PrintCommands()
{
	printf("Command list:\n");
	for(size_t i = 0; i < m_vCommands.GetSize(); ++i)
	{
		printf("'%s'\t%s\n", m_vCommands[i].szCommand, m_vCommands[i].szHelp);
	}
	printf("\n");
}