/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



#include "cmdline.hxx"

#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>


char C_sUseText[] = "Use: xml2cmp.exe \n"
					"        [-func funcFile] \n"
					"        [-html htmlFile] \n"
					"        [-types typeFile] \n"
					"        [-idlpath idlPath] \n"
					"        Xml_FileName\n"
					" or: xml2cmp.exe \n"
					"        -ix \n"
					"        sourceDirectory \n"
					"        outputDirectory \n"
					"        [-idlpath idlPath] \n"
					"        tagname [tagname ...]";


char C_sCmdFunc[] 		= "-func";
char C_sCmdHtml[]       = "-html";
char C_sCmdType[]       = "-types";
char C_sCmdIndex[]      = "-ix";
char C_sCmdIdlPath[]    = "-idlpath";



bool GetParameter( Simstr & o_rMemory, int & io_nCountArg, int argc, char * argv[] );


CommandLine::CommandLine( int			argc,
						  char *		argv[] )
	:	bIsOk(true)
{
	bool bDisplayUse = false;

	/* Check command line: */
	if ( argc < 2 )
		bDisplayUse = true;
	else if ( argc == 2 && ! isalnum(argv[1][0]) )
		bDisplayUse = true;
	else if ( strcmp( argv[1], C_sCmdIndex ) == 0 && argc < 5 )
		bDisplayUse = true;

	if (bDisplayUse)
	{
		std::cout << C_sUseText << std::endl;
		bIsOk = false;
		exit(0);
	}

	if ( strcmp( argv[1], C_sCmdIndex ) == 0 )
	{
		ParseIndexCommand(argc,argv);
	}
	else
	{
		ParseSingleFileCommand(argc,argv);
	}

	if ( sXmlSourceFile.l() == 0
		 && sXmlSourceDirectory.l() == 0 )
	{
		bIsOk = false;
	}
	else if ( sXmlSourceFile.l() > 0
			  && sXmlSourceDirectory.l() > 0 )
	{
		bIsOk = false;
	}
	else if ( sIndexFile.l() > 0
			  && ( sXmlSourceDirectory.l() == 0
				   || aTagsInIndex.size() == 0
				 )
			)
	{
		bIsOk = false;
	}

}

CommandLine::~CommandLine()
{
}


const char *
CommandLine::ErrorText() const
{
	static char cOut[] = "Error:  Command line was incorrect. Probably there was a flag without\n"
						 "        the corresponding parameter. Or there was no XML-sourcefile specified.\n";
	return cOut;
}

bool
GetParameter( Simstr &      o_pMemory,
			  int & 	    io_pCountArg,
			  int           argc,
			  char *        argv[] )
{
	io_pCountArg++;
	if( io_pCountArg < argc )
	{
		o_pMemory = argv[io_pCountArg];
		return true;
	}
	return false;
}


void
CommandLine::ParseIndexCommand( int					argc,
								char *				argv[] )
{
	int nCountArg = 1;
	bIsOk = GetParameter(
				sXmlSourceDirectory,
				nCountArg,
				argc,
				argv  );
	if (bIsOk)
		bIsOk = GetParameter(
					sOutputDirectory,
					nCountArg,
					argc,
					argv  );
	if (bIsOk && strcmp( argv[nCountArg+1], C_sCmdIdlPath ) == 0 )
		bIsOk = GetParameter(
					sIdlRootPath,
					++nCountArg,
					argc,
					argv  );

	sIndexFile = sOutputDirectory;
#if defined(WNT) || defined(OS2)
	sIndexFile+= "\\xmlindex.html";
#elif defined(UNX)
	sIndexFile+= "/xmlindex.html";
#endif

	for ( ++nCountArg; nCountArg < argc; ++nCountArg )
	{
		Simstr sElementName(argv[nCountArg]);
		aTagsInIndex.push_back( sElementName );
	}
}


void
CommandLine::ParseSingleFileCommand( int				argc,
									 char *				argv[] )
{
	for ( int nCountArg = 1; nCountArg < argc && bIsOk; ++nCountArg )
	{
		if ( strcmp( argv[nCountArg], C_sCmdFunc ) == 0 )
		{
			bIsOk = GetParameter(
								sFuncFile,
								nCountArg,
								argc,
								argv  );
		}
		else if ( strcmp( argv[nCountArg], C_sCmdHtml ) == 0 )
		{
			bIsOk = GetParameter(
								sHtmlFile,
								nCountArg,
								argc,
								argv  );
		}
		else if ( strcmp( argv[nCountArg], C_sCmdType ) == 0 )
		{
			bIsOk = GetParameter(
								sTypeInfoFile,
								nCountArg,
								argc,
								argv  );
		}
		else if ( strcmp( argv[nCountArg], C_sCmdIdlPath ) == 0 )
		{
			bIsOk = GetParameter(
								sIdlRootPath,
								nCountArg,
								argc,
								argv  );
		}
		else
		{
			sXmlSourceFile = argv[nCountArg];
		}
	}  	/* end for */
}
