/*
 * Copyright (c) 2015 Tricoire Sebastien 3dsman@free.fr
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not
 * claim that you wrote the original software. If you use this software
 * in a product, an acknowledgment in the product documentation would be
 * appreciated but is not required.
 * 2. Altered source versions must be plainly marked as such, and must not be
 * misrepresented as being the original software.
 * 3. This notice may not be removed or altered from any source distribution.
 *
 */

#pragma once

#include "xml/tinyxml.h"

#include "OE_utils.h"
#include "OE_document.h"

class OE_svgParser
{
	public:
		/** Parse a svg file */
		static OE_document * fromFile(const std::string filename, const char* units, float dpi);

	private:
		/** Default constructor */
		OE_svgParser();

		char id[64];                // Optional 'id' attr of the curve or its group
		float opacity;              // Opacity of the curve.
		float strokeWidth;          // Stroke width (scaled).
		char strokeLineJoin;        // Stroke join type.
		char strokeLineCap;         // Stroke cap type.
		float bounds[4];            // Tight bounding box of the curve [minx,miny,maxx,maxy].

		OE_document* document;

		static float sqr(float x);
		static float vmag(float x, float y);
		static float vecrat(float ux, float uy, float vx, float vy);
		static float vecang(float ux, float uy, float vx, float vy);
		static void xformPoint(float* dx, float* dy, float x, float y, float* t);
		static void xformVec(float* dx, float* dy, float x, float y, float* t);

		int isspace(char c);
		int isdigit(char c);
		int isnum(char c);
		const char* parseNumber(const char* s, char* it, const int size);
		const char* getNextPathItem(const char* s, char* it);

		/**return the number of arguments for a specified command**/
		int getArgsPerElement(char cmd);
		void pathMoveTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel);
		void pathLineTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel);
		void pathHLineTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel);
		void pathVLineTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel);
		void pathCubicBezTo(OE_pointcurve* curve, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel);
		void pathCubicBezShortTo(OE_pointcurve* curve, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel);
		void pathQuadBezTo(OE_pointcurve* curve, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel);
		void pathQuadBezShortTo(OE_pointcurve* curve, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel);
		void pathArcTo(OE_pointcurve* curve, float* cpx, float* cpy, float* args, int rel);

		/** Draw the paths */
		bool parsePath(TiXmlElement* input);
		bool parseSvg(TiXmlElement* input);

		bool pushCurve(OE_pointcurve* curve);

		OE_Matrix matrix;
};

