#ifndef MATHUTILS_H
#define MATHUTILS_H

#include <stdint.h>

#include "sge.h"

#include "FixedInt.h"
#include "../graphics/AffineTransformationMatrix.h"

#include <vector>
#include <cmath>
#include <iostream>
#include <cstdlib>
using namespace std;

#define NUMBER_PI 3.14159265

#define RANDOMIZE_STYLE_NONE 0
#define RANDOMIZE_STYLE_LINEAR_ADD 1
#define RANDOMIZE_STYLE_PERCENTAGE 2

//stores table look ups for useful math functions. These store
static vector<FixedInt> sineAngles;
static vector<FixedInt> cosineAngles;
static vector<FixedInt> tangentAngles;

class AffineTransformationMatrix;

//Angle functions are based on 256 bit angles and the screen system. Compared to the Cartesian system this means the y axis is inverted.
//Cartesian: 0 = right, 64 = up, 128 = left, 192 = down
//Screen: 0 = right, 64 = down, 128 = left, 192 = up
//Now this means screen x = cosine(Angle) and screen y = sine(Angle)

bool initializeAngles ();
double byteDegreesToRadians (uint8_t);
uint8_t radiansToByteDegrees (double radians);
float byteDegreesToDegrees(uint8_t bt);
FixedInt sine (uint8_t);
FixedInt cosine (uint8_t);
FixedInt tangent (uint8_t);
uint8_t arctangent (int, int, uint8_t errorAngle=0);

//integer math
int intAbs (int a);
int intSqrt (int);

//collision math
bool pointRectangleCollision (int pointX, int pointY, int leftSide, int rightSide, int topSide, int bottomSide);
bool pointCircleCollision (int pointX, int pointY, int centerX, int centerY, int radius);
bool pointAnyRectangleCollision (int ax, int ay, int bx, int by, int cx, int cy, int radius);
bool pointAnyRectangleCollisionHelper1 (FixedInt & corigx, FixedInt & corigy, AffineTransformationMatrix & atm, int radius, int ax, int ay, int bx, int by, int abQuad);
void pointAnyRectangleCollisionHelper2 (int ax, int ay, int bx, int by, AffineTransformationMatrix & projectionMatrix, int & abQuad);

//randomization
void seedRandomization ();
int generateRandomNumber (int);
int generateRandomNumber (int, int);
#endif
