/** SGX

The   sss    gggg x   x   
     s      g      x x    Engine
      sss   g  gg   x
         s  g   g  x x          Copyright 1995-2009.
     ssss    gggg x   x         Steven Goodwin. All Rights Reserved.
    
This version has been released under the GNU Public License v2.0.

Please see the license files for details.

File: sgx/src/sgx/core/sgxlib/commandline.cpp

*/

#include "sgx/core/types/types.hpp"
#include "sgx/core/stl/stl.hpp"
#include "sgx/core/helpers/trace.hpp"
#include "sgx/core/sgxlib/commandline.hpp"

CCommandLine::CCommandLine(const int argc, char *argv[])
{
	m_Executable = argv[0];
	// We will assume that any option is application-specific
	// therefore querying for -d will return whatever was after -d
	// even if it is unreleated.

	// So, for every argument, add it to:
	// 1. The argument list
	// 2. The appropriate option list (if the preceeding arg was an opt)
	tBOOL bWasOption = FALSE;
	char last_option;
	for(int i=1;i<argc;++i) {

		// Is this an option?
		if (argv[i][0] == '-') {
			last_option = argv[i][1];
			bWasOption = TRUE;
			continue;
		}
		
		// process
		if (bWasOption) {
			m_Options.insert(sgxMap<char, sgxString>::value_type(last_option, argv[i]));
			bWasOption = FALSE;
		} else {
			m_Arguments.push_back(argv[i]);
			if (m_ArgumentString != "") {
				m_ArgumentString += " ";
			}
			m_ArgumentString += argv[i];
		}

	}
}

/**
Retrieve the specified switch option @opt into @result. The method returns
TRUE if this exists. An option switch is one that is written "-s result"
*/
tBOOL	
CCommandLine::getOption(sgxString &result, const char opt) const
{
	// Find.
	sgxMap<char, sgxString>::const_iterator cit = m_Options.find(opt);
	if (cit == m_Options.end()) {
		return FALSE;
	} else {
		result = (*cit).second;
	}

	return TRUE;
}

/**
Retrieve the @idx'th argument in the command line, into @result. The arguments
generally appear after the options, and often consist of filenames.
*/
tBOOL	
CCommandLine::getArgument(sgxString &result, const tUINT32 idx) const
{
	if (idx >= m_Arguments.size()) {
		return FALSE;
	}

	result = m_Arguments[idx];
	return TRUE;
}

/**
Retrieve all arguments into @result.
*/
void	
CCommandLine::getArgumentString(sgxString &result) const
{
	result = m_ArgumentString;
}

/**
Retrieve all arguments, from the @from_idx'th into @result. These are
separated by spaces, as they would have been entered on the command line.
*/
tBOOL	
CCommandLine::getArgumentString(sgxString &result, const tUINT32 from_idx) const
{
	if (from_idx >= m_Arguments.size()) {
		return FALSE;
	}

	result = "";
	sgxVector<sgxString>::const_iterator cit = m_Arguments.begin();
	while(cit!=m_Arguments.end()) {
		result += (*cit);
		
		if (++cit != m_Arguments.end()) {
			result += " ";
		}
	}

	return TRUE;
}

/**
Retrieve all arguments, from the @from_idx'th to the @to_idx'th into @result. 
These are separated by spaces, as they would have been entered on the command line.
*/
tBOOL	
CCommandLine::getArgumentString(sgxString &result, const tUINT32 from_idx, const tUINT32 to_idx) const
{
	if (from_idx >= m_Arguments.size() || to_idx >= m_Arguments.size()) {
		return FALSE;
	}

	result = "";
	for(tUINT32 i=from_idx;i!=to_idx;++i) {
		result += m_Arguments[i];
		
		if (++i != to_idx) {
			result += " ";
		}
	}

	return TRUE;
}

void
CCommandLine::debug() {
	sgxTrace("CommandLine input:");

	sgxMap<char, sgxString>::const_iterator citOpts = m_Options.begin();
	for(;citOpts!=m_Options.end();++citOpts) {
		sgxTrace("Opt %c = %s", (*citOpts).first, (*citOpts).second.c_str());
	}

	sgxVector<sgxString>::const_iterator citArgs = m_Arguments.begin();
	int idx = 0;
	for(;citArgs!=m_Arguments.end();++citArgs) {
		sgxTrace("Arg #%d %s", idx, (*citArgs).c_str());
		++idx;
	}

}
