#ifndef GST_IntersectionTemplateParser_hpp__
#define GST_IntersectionTemplateParser_hpp__

#include "buildspec.h"

#include "transport/IntersectionOutputConfig.hpp"

#include <boost/unordered_map.hpp>

#include <iosfwd>
#include <string>

namespace GST
{
namespace Utils
{

struct GST_API_EXPORT ImageDimension
{
	double width;
	double height;
	ImageDimension();
	ImageDimension(double width, double height);
};

class GST_API_EXPORT IntersectionTemplateParser
{
public:
	// Tries to parse the template svg given by input stream.
	//
	// throws GSTRuntimeException if there was an error while parsing the
	// template file or while retrieving the data from the parsed result
	IntersectionTemplateParser(std::istream &input,
							   bool isecInfoOptional = false,
							   bool legendInfoOptional = true);
	~IntersectionTemplateParser();

	// Fills in the template values with the given parameters and writes the
	// resulting svg to output
	//
	// if there are template values present, for which no fill in was given,
	// auto replacement will be either "n/a" or "", whichever is appropriate.
	void fillInTemplate(std::string &output,
						const std::string &isecImage,
						const std::string &legendImage,
						const std::string &overviewImage,
						const std::string &scalebarImage,
						const std::string &title,
						long xScale,
						long yScale,
						const boost::unordered_map<std::string, std::string>
							&placeholderValues);

	void fillInTemplate(std::string &output,
						const std::string &isecImage,
						const std::string &legendImage,
						const std::string &overviewImage,
						const std::string &scalebarImage,
						const std::string &title,
						long xScale,
						long yScale,
						double isecOutWidth,
						double isecOutLength,
						const boost::unordered_map<std::string, std::string>
							&placeholderValues);

	// Returns the ImageDimension of the svg document
	ImageDimension getDocDimension() const;

	// Returns the ImageDimension of the isecImg
	ImageDimension getIsecDimension() const;

	// Returns the ImageDimension of the legendImg encoded in the template file
	//
	// This info is optional in the template, so this function returns a
	// default constructed ImageDimension, if no legendImgInfo was provided
	// within the template.
	// See hasOverviewDimension().
	ImageDimension getLegendDimension() const;

	// Returns the ImageDimension of the overviewImg encoded in the template
	// file
	//
	// This info is optional in the template, so this function returns a
	// default constructed ImageDimension, if no overviewImgInfo was provided
	// within the template.
	// See hasOverviewDimension().
	ImageDimension getOverviewDimension() const;

	// Returns the ImageDimension of the scalebarImg encoded in the template
	// file
	//
	// This info is optional in the template, so this function returns a
	// default constructed ImageDimension, if no scalebarImgInfo was provided
	// within the template.
	// See hasScalebarDimension().
	ImageDimension getScalebarDimension() const;

	// Returns the params string in json format encoded in the template file
	//
	// This info is optional in the template, so this function returns a
	// default constructed string, if it was not provided within the template.
	// See hasParamsJson().
	std::string getParamsJson() const;

	// Tells if there is legendImgInfo present in the template file.
	//
	// if this is true, getLegendDimension() will return the acutal legend image
	// dimension out of the template files.
	// Else getLegendDimension() returns a default constructed ImageDimension
	// (all values are -1).
	bool hasLegendDimension() const;

	// Tells if there is overviewInfo present in the template file.
	//
	// if this is true, getOverviewDimension() will return the acutal overview
	// image dimension out of the template files.
	// Else getOverviewDimension() returns a default constructed ImageDimension
	// (all values are -1).
	bool hasOverviewDimension() const;

	// Tells if there is scalebarInfo present in the template file.
	//
	// if this is true, getScalebarDimension() will return the acutal scalebar
	// image dimension out of the template files.
	// Else getScalebarDimension() returns a default constructed ImageDimension
	// (all values are -1).
	bool hasScalebarDimension() const;

	// Tells if the params json string is in the template file.
	//
	// if this is true, getParamsJson() will return it
	// Else getParamsJson() returns a default constructed string (i.e. empty)
	bool hasParamsJson() const;

	// Sets the growMode from the json parameter
	//
	// Note: GrowMode::none will result in default grow direction (i.e. ul)
	// Note: this sets align to the opposite of growDirection (center for none)
	void setGrowMode(IntersectionOutputConfig::GrowMode::Type growMode);
	// Sets the image alignment in the isec box from the json parameter
	void setIsecAlign(IntersectionOutputConfig::ImageAlighnment::Type align);

private:
	class IntersectionTemplateParserImpl;
	IntersectionTemplateParserImpl *m_impl;

	// non-copyable
	IntersectionTemplateParser(const IntersectionTemplateParser &);
	IntersectionTemplateParser &operator=(const IntersectionTemplateParser &);
};

GST_API_EXPORT extern const double pxToMm90dpi;
GST_API_EXPORT extern const double mmToPx90dpi;
GST_API_EXPORT extern const double pxToMm72dpi;
GST_API_EXPORT extern const double mmToPx72dpi;
} // namespace Utils
} // namespace GST

#endif // GST_IntersectionTemplateParser_hpp__
