// Copyright (c) 2023 Alex Diener. All rights reserved.

#include "gamemath/Scalar.h"
#include "PROJECT_NAME/RoomTransition.h"

#define stemobject_implementation RoomTransition

stemobject_vtable_begin();
stemobject_vtable_entry(dispose);
stemobject_vtable_end();

#define TRANSITION_DURATION 0.375

RoomTransition * RoomTransition_create(RoomVisual * oldRoomVisual, RoomVisual * newRoomVisual, Vector2f offsetFromOldToNew, Vector2f oldRoomCameraPosition, Vector2f newRoomCameraPosition, float interpolationStart) {
	stemobject_create_implementation(init, oldRoomVisual, newRoomVisual, offsetFromOldToNew, oldRoomCameraPosition, newRoomCameraPosition, interpolationStart)
}

bool RoomTransition_init(RoomTransition * self, RoomVisual * oldRoomVisual, RoomVisual * newRoomVisual, Vector2f offsetFromOldToNew, Vector2f oldRoomCameraPosition, Vector2f newRoomCameraPosition, float interpolationStart) {
	call_super(init, self);
	self->oldRoomVisual = oldRoomVisual;
	self->newRoomVisual = newRoomVisual;
	self->offsetFromOldToNew = offsetFromOldToNew;
	self->oldRoomCameraPosition = oldRoomCameraPosition;
	self->newRoomCameraPosition = newRoomCameraPosition;
	self->interpolation = interpolationContextInit(0.0f, 1.0f, TRANSITION_DURATION, false, InterpolationCurveFunc_easeInOutSin, NULL);
	interpolationSetProgress(&self->interpolation, interpolationStart);
	self->speedMultiplier = 1.0f;
	return true;
}

void RoomTransition_dispose(RoomTransition * self) {
	RoomVisual_dispose(self->oldRoomVisual);
	call_super_virtual(dispose, self);
}

Vector2f RoomTransition_getCameraOffset(RoomTransition * self) {
	Vector2f oldOffset = VECTOR2f(self->oldRoomCameraPosition.x, self->oldRoomCameraPosition.y);
	Vector2f newOffset = Vector2f_add(VECTOR2f(self->newRoomCameraPosition.x, self->newRoomCameraPosition.y), self->offsetFromOldToNew);
	Vector2f offset = Vector2f_interpolate(newOffset, oldOffset, self->interpolation.currentValue);
	offset.x -= self->oldRoomCameraPosition.x + self->newRoomCameraPosition.x;
	offset.y -= self->oldRoomCameraPosition.y + self->newRoomCameraPosition.y;
	return Vector2f_round(offset);
}

Vector2f RoomTransition_getInverseCameraOffset(RoomTransition * self) {
	return Vector2f_subtract(RoomTransition_getCameraOffset(self), self->offsetFromOldToNew);
}

void RoomTransition_advance(RoomTransition * self, double deltaTime) {
	interpolationAdvance(&self->interpolation, deltaTime * self->speedMultiplier);
}

void RoomTransition_draw(RoomTransition * self, Vector2f offset, VertexIO * vertexIO) {
	RoomVisual_draw(self->oldRoomVisual, Vector2f_subtract(offset, self->offsetFromOldToNew), vertexIO);
	RoomVisual_draw(self->newRoomVisual, offset, vertexIO);
}

bool RoomTransition_allowMovement(RoomTransition * self) {
	return self->interpolation.currentProgress >= 0.625f;
}

bool RoomTransition_isDone(RoomTransition * self) {
	return self->interpolation.currentProgress >= 1.0f;
}
