#include <stdlib.h>
#include <math.h>
#include "vector.h"
#include "draw.h"

void vid_mode(byte_t mode){
	/*
	union REGS regs;
	regs.h.ah = 0;
	regs.h.al = mode;
	int86(0x10,&regs,&regs);
	*/
}

void swap(int &a, int &b){
	int t;
	t=a;
	a=b;
	b=t;
}

void blit0(byte_t* what){
	//dosmemput(what,XMAX*YMAX,0xA0000);
}

void pixel(int x, int y, byte_t color, byte_t* where){
	where[(y+YMAX)%YMAX*XMAX+(x+XMAX)%XMAX]=color;
}

void hline(int x1, int x2, int y, byte_t color, byte_t* where){
	if(x1>x2) swap(x1,x2);
	for(;x1 <=x2; x1++)
		pixel(x1,y,color,where);
}

void vline(int x,int y1,int y2,byte_t color,byte_t* where){
	if(y1>y2) swap(y1,y2);
	for(;y1 <= y2;y1++)
		pixel(x,y1,color,where);
}

void line(Vector a, Vector b,byte_t color,byte_t* where){
	if ((a.x-b.x<1)&&(b.x-a.x<1)) vline(int(a.x),int(a.y),int(b.y),color,where);
	if (a.x>b.x) {
		swap(a,b);
		}
	double y;
	double ylast=-1;
	for (double i=a.x; i<=b.x; i+=.2){
		y=(((double(b.y-a.y)/double(b.x-a.x))*(i-a.x))+a.y);
		if (ylast>=0){
		if(y>ylast) vline(int(i),int(ylast),int(y),color,where);
		else vline(int(i),int(y),int(ylast),color,where);
		}
		ylast=y;
	}
}


Line::Line(const Vector &a, const Vector &b){
	p1=a;
	p2=b;
}

Line::Line(const Line &copy){
	p1=copy.p1;
	p2=copy.p2;
}

Line::~Line(){
}

void Line::set(const Vector &a, const Vector &b){
	p1=a;
	p2=b;
}

void Line::draw(byte_t color, byte_t* where){
	line((p1),(p2),color,where);
}

double mag(const Line &l){
	return(mag(l.p1-l.p2));
}

double slope(const Line &l){
	return( ((l.p2).y-(l.p1).y)/((l.p2).x-(l.p1).x) );
}


void Circle::size(unsigned r){
	radius=5.0*r;
}

double Circle::getsize(){
	return radius;
}

Vector Circle::getcenter(){
	return center;
}

void Circle::speed(const Vector &v){
	velocity=v;
}

Circle::Circle(const Vector &c, const Vector &v, double r){
	center=c;
	velocity=v;
	radius=r;
	enemyType=int(0.5+((rand()*1.0)/RAND_MAX));
	clock=-1;
	toShip=Vector(0,0);
}

Circle::Circle(const Circle &copy){
	center=copy.center;
	velocity=copy.velocity;
	radius=copy.radius;
	enemyType=copy.enemyType;
	clock=copy.clock;
	toShip=copy.toShip;
}

Circle::~Circle(){

}

void Circle::set(const Vector &c, const Vector &v, double r){
	center=c;
	velocity=v;
	radius=r;
}

bool Circle::on(const Vector &p){
	double x=p.x-center.x;
	double y=p.y-center.y;
	return ((x*x+y*y)<=(radius*radius));
}

void draw(const Circle &cir, byte_t color, byte_t *where){
	switch (cir.enemyType){
		case 1:
			do{
				double alpha=Pi/2.0,
			       		beta=7*Pi/6.0,
			       		gamma=11*Pi/6.0;
				Vector a(cir.radius*cos(alpha)+cir.center.x,cir.radius*sin(alpha)+cir.center.y),
			       		b(cir.radius*cos(beta)+cir.center.x,cir.radius*sin(beta)+cir.center.y),
			       		c(cir.radius*cos(gamma)+cir.center.x,cir.radius*sin(gamma)+cir.center.y);
				line(a,b,color,where);
				line(b,c,color,where);
				line(c,a,color,where);
			} while (false);
			break;
		case 0:
		default:
			for(double i=0; i<2*Pi; i+=1.0/cir.radius)
				pixel(	int(cir.radius*cos(i)+cir.center.x),
					int(cir.radius*sin(i)+cir.center.y),
					color,where);
			break;
	}
}

void Circle::fly(int ticks, const Vector &ship){
	clock-=ticks;
	if(enemyType==1){
		if(clock>=0){
			velocity=velocity-(toShip/(3*mag(toShip)));
		}
		else {
			velocity=Vector(0,0);
		}
		toShip=ship-center;
		velocity=velocity+(toShip/(3*mag(toShip)));
	}
	if(clock<0){
		clock=rand()%1200;
		velocity=velocity+Vrand()/2;
	}
	
	center=center+ticks*velocity/5.0;
	while (center.x<0)
		center.x+=XMAX;
	while (center.x>=XMAX)
		center.x-=XMAX;
	while(center.y<0)
		center.y+=YMAX;
	while(center.y>=YMAX)
		center.y-=YMAX;
}

