////////////////////////////////////////////////////////////////////////////////
//    Scorched3D (c) 2000-2011, 2024, 2026
//
//    This file is part of Scorched3D.
//
//    Scorched3D is free software; you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation; either version 2 of the License, or
//    (at your option) any later version.
//
//    Scorched3D is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License along
//    with this program; if not, write to the Free Software Foundation, Inc.,
//    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
////////////////////////////////////////////////////////////////////////////////

#ifndef __INCLUDE_ARGParser_hpp_INCLUDE__
#define __INCLUDE_ARGParser_hpp_INCLUDE__

// ARGParser.hpp: interface for the ARGParser class.
//
//////////////////////////////////////////////////////////////////////

#include <list>
#include <map>
#include <string>

class ARGParserBoolI
{
public:
	virtual bool setBoolArgument( bool value ) = 0;
};

class ARGParserIntI
{
public:
	virtual bool setIntArgument( int value ) = 0;
};

class ARGParserStringI
{
public:
	virtual bool setStringArgument( const char* value ) = 0;
};

class ARGParser
{
public:
	ARGParser();

	bool parse( const char* lpCmdLine );
	bool parse( int argc, char* argv[] );
	void addEntry( char* cmd, char** destStr, const char* help = "" );
	void addEntry( char* cmd, int* destI, const char* help = "" );
	void addEntry( char* cmd, bool* destB, const char* help = "" );

	void addEntry( char* cmd, ARGParserBoolI* destBool, const char* help = "" );
	void addEntry( char* cmd, ARGParserIntI* destInt, const char* help = "" );
	void addEntry( char* cmd, ARGParserStringI* destString, const char* help = "" );

	void addNonParamEntry( char* cmd, ARGParserStringI* destString, const char* help = "" );

	void showArgs( const char* topString = nullptr );

protected:
	struct Entry
	{
		Entry(
			ARGParserBoolI*   destBoolArg   = nullptr,
			ARGParserIntI*    destIntArg    = nullptr,
			ARGParserStringI* destStringArg = nullptr,
			char**            destCArg      = nullptr,
			int*              destIArg      = nullptr,
			bool*             destBArg      = nullptr,
			const char*       helpArg       = ""
		);

		ARGParserBoolI*   destBool;
		ARGParserIntI*    destInt;
		ARGParserStringI* destString;
		char**            destC;
		int*              destI;
		bool*             destB;
		std::string       help;
	};

	std::map< std::string, Entry > argMap_;
	std::map< std::string, Entry > nonParamMap_;
	void                           addNewEntry( const char* cmd, ARGParser::Entry& entry );
	bool                           parseLineIntoStrings( const char* line, std::list< std::string >& cmdLine );
	bool                           parseArg( ARGParser::Entry& newEntry, std::list< std::string >& cmdLine );
};

#endif  // __INCLUDE_ARGParser_hpp_INCLUDE__
