#pragma once

#include "PathElement.h"
#include "Point.h"

#include <memory>
#include <vector>
#include <string>

class GeometryPath;
using PathElementPtr = std::unique_ptr<PathElement>;

class GeometryPathFeature;
using GeometryPathFeaturePtr = std::unique_ptr<GeometryPathFeature>;

class PathPostScriptConverter
{
public:
	void fromPostScript(GeometryPath* targetPath, const std::string& postScriptPath);

	std::string toPostScript(const GeometryPath* targetPath);

private:
	enum class LineState
	{
		START,
		IN_FIRST_POINT,
		IN_HORIZONTAL,
		IN_VERTICAL,
		IN_LINE,
		IN_CUBIC_BEZIER,
		IN_QUADRATIC_BEZIER,
		IN_ARC,
		IN_UNSUPPORTED
	};

	enum class PositionState
	{
		ABSOLUTE,
		RELATIVE
	};

	PositionState getPositionState(char c) const;

	void onNewElement(char c);
	void onNonNumeric();
	void onElementEnd();

	void onMoveTo();
	PathElementPtr onHorizontalLineTo();
	PathElementPtr onVerticalLineTo();
	PathElementPtr onLineTo();

	PathElementPtr onArc();
	PathElementPtr onQuadraticBezier();
	PathElementPtr onCubicBezier();

	LineState mLineState{ LineState::START };
	PositionState mPositionState{ PositionState::ABSOLUTE };
	std::string mBuffer;
	std::vector<double> mPointBuffer;

	GeometryPathFeaturePtr mWorkingFeature;
	Point mCurrentPoint;

	std::size_t mPrecision{ 3 };
};
