#include "mplus_stroke_svg.h"
#include "mplus_stroke_line.h"

#include <string.h>

#define CUBIC_RESOLUTION 10

typedef struct pos2d {
	double x;
	double y;
} pos2d_t;

static MPLUS_GlyphsData_t g_tGlyphsData;
static MPLUS_Line_Glyph_t tGlyph;

static void cubic_bezier(pos2d_t* o_ptPos, const pos2d_t* i_ptFrom, const pos2d_t* i_ptControl1, const pos2d_t* i_ptControl2, const pos2d_t* i_ptTo, const double i_dRatio) {
	pos2d_t ltTemp1[3];
	pos2d_t ltTemp2[2];
	ltTemp1[0].x = i_ptFrom->x + (i_ptControl1->x - i_ptFrom->x) * i_dRatio;
	ltTemp1[0].y = i_ptFrom->y + (i_ptControl1->y - i_ptFrom->y) * i_dRatio;
	ltTemp1[1].x = i_ptControl1->x + (i_ptControl2->x - i_ptControl1->x) * i_dRatio;
	ltTemp1[1].y = i_ptControl1->y + (i_ptControl2->y - i_ptControl1->y) * i_dRatio;
	ltTemp1[2].x = i_ptControl2->x + (i_ptTo->x - i_ptControl2->x) * i_dRatio;
	ltTemp1[2].y = i_ptControl2->y + (i_ptTo->y - i_ptControl2->y) * i_dRatio;
	ltTemp2[0].x = ltTemp1[0].x + (ltTemp1[1].x - ltTemp1[0].x) * i_dRatio;
	ltTemp2[0].y = ltTemp1[0].y + (ltTemp1[1].y - ltTemp1[0].y) * i_dRatio;
	ltTemp2[1].x = ltTemp1[1].x + (ltTemp1[2].x - ltTemp1[1].x) * i_dRatio;
	ltTemp2[1].y = ltTemp1[1].y + (ltTemp1[2].y - ltTemp1[1].y) * i_dRatio;
	o_ptPos->x = ltTemp2[0].x + (ltTemp2[1].x - ltTemp2[0].x) * i_dRatio;
	o_ptPos->y = ltTemp2[0].y + (ltTemp2[1].y - ltTemp2[0].y) * i_dRatio;
}

void LoadMPLUSStroke_Line(MPLUS_Line_GlyphsData_t* o_ptGlyphsData) {
	int i, j, k;

	LoadMPLUSStroke(&g_tGlyphsData);

	o_ptGlyphsData->glyphscount = g_tGlyphsData.glyphscount;

	for(i = 0; i < g_tGlyphsData.glyphscount; i++) {
		memset(&tGlyph, 0, sizeof(MPLUS_Line_Glyph_t));
		o_ptGlyphsData->glyphs[i].code = g_tGlyphsData.glyphs[i].code;
		o_ptGlyphsData->glyphs[i].code8 = g_tGlyphsData.glyphs[i].code8;
		o_ptGlyphsData->glyphs[i].linescount = 0;

		for(j = 0; j < g_tGlyphsData.glyphs[i].itemscount; j++) {
			switch(g_tGlyphsData.glyphs[i].items[j].top.ItemType) {
			case MPLUS_ITEMTYPE_LINE:
				o_ptGlyphsData->glyphs[i].lines[o_ptGlyphsData->glyphs[i].linescount].pos1.x = g_tGlyphsData.glyphs[i].items[j].line.pos1.x;
				o_ptGlyphsData->glyphs[i].lines[o_ptGlyphsData->glyphs[i].linescount].pos1.y = g_tGlyphsData.glyphs[i].items[j].line.pos1.y;
				o_ptGlyphsData->glyphs[i].lines[o_ptGlyphsData->glyphs[i].linescount].pos2.x = g_tGlyphsData.glyphs[i].items[j].line.pos2.x;
				o_ptGlyphsData->glyphs[i].lines[o_ptGlyphsData->glyphs[i].linescount].pos2.y = g_tGlyphsData.glyphs[i].items[j].line.pos2.y;
				o_ptGlyphsData->glyphs[i].linescount++;
				break;
			case MPLUS_ITEMTYPE_CUBIC:
				{
					pos2d_t tPos, tPre;
					pos2d_t tFrom, tControl1, tControl2, tTo;

					tFrom.x     = g_tGlyphsData.glyphs[i].items[j].cubic.pos1.x;
					tFrom.y     = g_tGlyphsData.glyphs[i].items[j].cubic.pos1.y;
					tControl1.x = g_tGlyphsData.glyphs[i].items[j].cubic.pos2.x;
					tControl1.y = g_tGlyphsData.glyphs[i].items[j].cubic.pos2.y;
					tControl2.x = g_tGlyphsData.glyphs[i].items[j].cubic.pos3.x;
					tControl2.y = g_tGlyphsData.glyphs[i].items[j].cubic.pos3.y;
					tTo.x       = g_tGlyphsData.glyphs[i].items[j].cubic.pos4.x;
					tTo.y       = g_tGlyphsData.glyphs[i].items[j].cubic.pos4.y;

					tPre.x = tFrom.x;
					tPre.y = tFrom.y;
					for(k = 1; k <= CUBIC_RESOLUTION; k++) {
						cubic_bezier(&tPos, &tFrom, &tControl1, &tControl2, &tTo, (double)k / (double)CUBIC_RESOLUTION);
						o_ptGlyphsData->glyphs[i].lines[o_ptGlyphsData->glyphs[i].linescount].pos1.x = tPre.x;
						o_ptGlyphsData->glyphs[i].lines[o_ptGlyphsData->glyphs[i].linescount].pos1.y = tPre.y;
						o_ptGlyphsData->glyphs[i].lines[o_ptGlyphsData->glyphs[i].linescount].pos2.x = tPos.x;
						o_ptGlyphsData->glyphs[i].lines[o_ptGlyphsData->glyphs[i].linescount].pos2.y = tPos.y;
						o_ptGlyphsData->glyphs[i].linescount++;
						tPre.x = tPos.x;
						tPre.y = tPos.y;
					}
				}
				break;
			}
		}
	}
}
