#include "allegro.h"
#include "tasmMath.h"

#include <stdio.h>

fixed calcAngle (const fixed & fromX, const fixed & fromY, const fixed & toX, const fixed & toY, const fixed & currAngle)
{
  //calculates angle between two points. This is relative to the screen's axis.
  //This is also relative to allegro's angles ie 0 = up, 64 = right, 128 = down, 192 = left
  // screen: positive y on bottom, positive x on right, angle forms from negative y axis and rotates to positive x axis
  //cartesian: positive y on top, positive x on right, angle forms from positive x axis and rotates to positive y axis
  //to translate: x -> y', y -> -x'

  fixed ans;

  fixed deltaY = toY - fromY;
  fixed deltaX = fromX - toX;

  if (deltaY == 0 && deltaX == 0)
    return currAngle;
  if (deltaY == 0 && deltaX < 0)
    return itofix (192);
  if (deltaY == 0 && deltaX > 0)
    return itofix (64);

  ans = fixatan (fixdiv (deltaX, deltaY));

  if (deltaY > 0)
    ans -= itofix (128);

  return ans;
}

fixed calcDist (const fixed & fromX, const fixed & fromY, const fixed & toX, const fixed & toY)
{
  //gets the total dist between two points.

  fixed deltaY = toY - fromY;
  fixed deltaX = toX - fromX;

  fixed gab = fixhypot (deltaX, deltaY);
  return gab;
}

fixed angleDist (const fixed & fromAngle, const fixed & toAngle)
{
  //calculates the closest angle distance between two angles. Answers range from -128 to 128.
  //takes into account loop around issues. Example: 2 vs 255 is 2 away, not 253 away.
  //in Allegro, angles are 256 'degrees' to a full circle. 0 is straight up, and 64 is a right angle.

  fixed angleFrom = fromAngle;
  fixed angleTo = toAngle;
  fixed distStraight = itofix (0), dS = itofix (0);
  fixed distPlus = itofix (0), dP = itofix (0);
  fixed distMinus = itofix (0), dM = itofix (0);
  int distAns = 0;

  //normalize both.
  while (angleFrom < itofix (0))
    angleFrom += itofix (256);
  while (angleFrom > itofix (256))
    angleFrom -= itofix (256);

  while (angleTo < itofix (0))
    angleTo += itofix (256);
  while (angleTo > itofix (256))
    angleTo -= itofix (256);

  //now get some answers. angleFrom must be compared to angleTo, angleTo + 256, and angleTo - 256 to prevent loopovers. Example: 0 vs 259 is 1 away, not 259.
  distStraight = angleFrom - angleTo;
  distPlus = angleFrom - angleTo + itofix (256);
  distMinus = angleFrom - angleTo - itofix (256);

  //return the minimum (closest to 0, not closest to -infinity)
  dS = distStraight;
  if (dS < 0)
    dS *= -1;

  dP = distPlus;
  if (dP < 0)
    dP *= -1;

  dM = distMinus;
  if (dM < 0)
    dM *= -1;

  if (dS <= dP && dS <= dM)
    distAns = 1;

  if (dP <= dS && dP <= dM)
    distAns = 2;

  if (dM <= dP && dM <= dS)
    distAns = 3;

  if (distAns == 1)
    return distStraight;
  else if (distAns == 2)
    return distPlus;
  else if (distAns == 3)
    return distMinus;
  else
    return (itofix (0));
}

fixed fixabs (const fixed & f)
{
  //returns the absolute value of a fixed number.
  if (f < 0)
    return (f * -1);
  return f;
}

fixed normalizeAngle (const fixed & f)
{
  fixed gub = f;

  while (gub < itofix (0))
    gub += itofix (256);

  while (gub > itofix (256))
    gub -= itofix (256);

  return gub;
}

void setUpDialog (DIALOG * d, int (*proc)(int, DIALOG *, int), int x, int y, int w, int h, int fg, int bg, int key, int flags, int d1, int d2, void *dp, void *dp2, void *dp3)
{
  //sets up the dialog because Allegro has no support for this...
  d -> proc = proc;
  d -> x = x;
  d -> y = y;
  d -> w = w;
  d -> h = h;
  d -> fg = fg;
  d -> bg = bg;
  d -> key = key;
  d -> flags = flags;
  d -> d1 = d1;
  d -> d2 = d2;
  d -> dp = dp;
  d -> dp2 = dp2;
  d -> dp3 = dp3;
}
