#include <iostream>
#include <cmath>
#include <array>

#include <raylib.h>
#include <raymath.h>

int screenWidth = 600;
int screenHeight = 800;

int pos = 0;
Vector2 mouseStart;
float len;
float ofset;
bool validHit = false;

float rotation = 0.0f;
Rectangle destB;
Rectangle destA;

std::array<RenderTexture2D, 2> canvasTexure = {0};

void init()
{
  for (size_t i = 0; i < canvasTexure.size(); i++)
  {
    canvasTexure[i] = LoadRenderTexture(screenWidth, screenWidth);
  }

  BeginTextureMode(canvasTexure[0]);
  ClearBackground(WHITE);
  EndTextureMode();

  BeginTextureMode(canvasTexure[1]);
  ClearBackground(BLUE);
  EndTextureMode();

  float posY = (screenHeight - screenWidth) / 2.0f;
  destA = {0, posY, (float)screenWidth, (float)screenWidth};
  destB = destA;
}

Vector2 CalculateVector(float rotation, float offSet, float len)
{
  float angle = ((rotation)*PI) / 180.0f;
  angle += offSet;
  return {
      .x = len * std::sin(angle),
      .y = len * std::cos(angle)};
}

void update()
{
  if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
  {
    mouseStart = GetMousePosition();
    validHit = CheckCollisionPointRec(mouseStart, destA);
    len = Vector2Distance(mouseStart, {destB.x, destB.y});
    ofset = std::atan2(destB.x - mouseStart.x, destB.y - mouseStart.y);
  }

  if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) && validHit)
  {
    Vector2 mousePosition = GetMousePosition();
    float dist = mousePosition.x - mouseStart.x;
    float l = dist / screenWidth;
    rotation = Lerp(45.0f, -45.0f, (l + 1) / 2);
    Vector2 newCenter = CalculateVector(rotation, ofset, len);
    destA.x = newCenter.x + mousePosition.x;
    destA.y = newCenter.y + mousePosition.y;
  }

  if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT) && validHit)
  {
    pos = 1 - pos;
    rotation = 0.0f;
    destA = destB;
  }
}

void drawTexureWithRotation(RenderTexture2D &target, Rectangle &dest, float rotation)
{
  Rectangle source = {0, 0, (float)target.texture.width, (float)-target.texture.height};
  Vector2 origin = {0.0f, 0.0f};
  rotation = 360 - rotation;
  DrawTexturePro(target.texture, source, dest, origin, rotation, WHITE);
}

void draw()
{
  ClearBackground(RED);
  drawTexureWithRotation(canvasTexure[pos], destB, 0.0f);
  drawTexureWithRotation(canvasTexure[1 - pos], destA, rotation);
}

int main(int argc, char const *argv[])
{
  char name[] = "treender";
  int screenWidth = 600;
  int screenHeight = 800;
  InitWindow(screenWidth, screenHeight, name);
  SetTargetFPS(60);
  init();
  while (!WindowShouldClose())
  {
    update();
    BeginDrawing();
    draw();
    EndDrawing();
  }

  CloseWindow();
  return 0;
}