#ifndef CONFIGURATIONPARSER_H_
#define CONFIGURATIONPARSER_H_

#include <sstream>
#include <fstream>

#include "../config.h"
#include "../typedefs.h"
#include "../SimulatorException.h"

/**
 * Class for parsing the configuration files
 */
class ConfigurationParser
{
public:
	ConfigurationParser(): _iss(), _file(), _line(0), _carTypes() {}; 
	virtual ~ConfigurationParser() {};
	
	/**
	 * Parses the simulation setup file with basic constants (gravity, ERP, CFM, etc.)
	 */
	void parseSimSetup(const char* filename);
	/**
	 * Parses the objects file and instantiates simulation objects according to it
	 */
	void parseObjectsSetup(const char* filename);
	/**
	 * Parses the topography file and instantiates sectors according to it
	 */
	void parseTopographySetup(const char* filename);
	
private:
	std::istringstream _iss;
	std::ifstream _file;
	int _line;
	CarTypeMap _carTypes;
	
	/** Parses a single polygon */
	void parsePolygon();
	/** Parses a viewpoint */
	void parseViewpoint();
	/** Parses a car source object */
	void parseCarSource();
	/** Parses a car sink object */
	void parseCarSink();
	/** Parses a single car */
	void parseCar();
	/** Parses a single building */
	void parseBuilding();
	/** Parses a single signing */
	void parseSigning();
	
	/**
	 * Reads a line from the input file and strips comments
	 * @return false if reached end of file
	 */
	bool getLine();
	/**
	 * Parses the currently read line
	 * It accepts arbitrary amount of parameters which it fills with value found on the line.
	 * The configuration of passed parameters is specified in the first parameter.
	 * Currently supported types are:
	 * i - int
	 * d - double
	 * f - float
	 * s - string
	 * R - dReal
	 * @param types a concatenated list of variable types
	 */
	void parseLine(const char* types, ...);
	/**
	 * Searches for a sector in simulator, returns its pointer if found or creates new if not found
	 * @param id Sector's ID
	 */
	Sector* lookupSector(int id);
};

class ConfigurationException: public SimulatorException {
public:
	ConfigurationException(const std::string msg): SimulatorException(msg) {};
	ConfigurationException(const char* msg): SimulatorException(msg) {};
	~ConfigurationException() {};
};
#endif /*CONFIGURATIONPARSER_H_*/
