#include "P_LineSegment.h"
#include "PixelCallback.h"
#include <math.h>
#include <stdlib.h>
#include <string.h>

void rotatePoint(i32* x, i32* y, double angle) {
	i32 xR = *x * cos(angle) + *y * sin(angle);
	i32 yR = - *x * sin(angle) + *y * cos(angle);
	*x = xR;
	*y = yR;
}

void LineSegment_callback(LineSegment* self, struct PixelContext* fc) {
	/* IDK if this is the most efficient, online results seem
	 * to do more complicated calculations.
	 * Center coordianates around aX,aY
	 * Then unrotate bX,bY and x,y relative to 0,0 (aX,aY),
	 * so that bX,bY lies on the horizontal axis.
	 * Now the line is flat from 0,0 to the "right" (increasing x).
	 */
	i32 x = fc->x - self->aX, y = fc->y - self->aY;
	i32 bX = self->bX - self->aX, bY = self->bY - self->aY;

	double phi = atan2(bY, bX);
	rotatePoint(&y, &x, -phi);
	rotatePoint(&bY, &bX, -phi);

	i32 halfWidth = self->width / 2;
	if (0 <= x && x <= bX && -halfWidth <= y && y <= halfWidth)
	{
		ARGB_merge(&fc->pixel, self->color);
	}
}

PixelCallback* LineSegment_setup(LineSegment obj) {
	PixelCallback* pca = malloc(sizeof(struct PixelCallback));

	pca->callback = (PixelCallback_callback)LineSegment_callback;
	pca->callback_self = malloc(sizeof(obj));
	memcpy(pca->callback_self, &obj, sizeof(obj));

	return pca;
}
