#include <allegro.h>

#include <stdio.h> // sprintf

#include "main.h"

#include "line.h"

#include "flipper.h"


/* IN CASE YOU ARE LOOKING AT THIS CODE TO FIND A PHYSICAL MODEL TO USE IN A
   FLIPPER SIMULATION, I'M SORRY, THERE IS NONE IN HERE !
   
   I wrote this code without ever looking into a physics book or any other
   physics resources. From some glances into physics I had when working on
   other projects, though, I guess what I'm doing would be called Euler
   Integration (which is considered quite bad), combined with a just plain
   wrong (which is bad as well) physical model, losely based on Newtonian
   physics.
   
   I'd very like to have a more accurate, and especially better performing
   (this one needs a 1GHz machine to run) algorithm, so if you know one,
   please mail me :) (Not if we are far into the 21 century already, then I'm
   probably out of the game programming business for some time :| Actually,
   mail me anyway.. and I'll be really wondering how you got this source code)

*/

FlipperLeft *flipperleft1 = 0, *flipperleft2 = 0;

FlipperRight *flipperright1 = 0, *flipperright2 = 0;

FlipperLeft::FlipperLeft(float _xp, float _yp, float _R) : Part(_xp, _yp, 0, _R) {
	
	rc = FLIPPER_ANGEL_SPEED;
	
	sideup = new Line(xp, yp, 0, R);
	sidedown = new Line(xp, yp, 0, R);		
	
	sideup->sound = 1;
	sidedown->sound = 1;
	
	drx1 = -5;
	dry1 = -int(R);
	drx2 = int(R);
	dry2 = int(R);	
}

FlipperRight::FlipperRight(float _xp, float _yp, float _R) : Part(_xp, _yp, M_PI, _R) {
	
	rc = -FLIPPER_ANGEL_SPEED;
	
	sideup = new Line(xp, yp, M_PI, R);
	sidedown = new Line(xp, yp, M_PI, R);
	
	sideup->sound = 1;
	sidedown->sound = 1;
	
	drx1 = -int(R);
	dry1 = -int(R);
	drx2 = 5;
	dry2 = int(R + 1);				
}

void FlipperLeft::move(float d) {		
													
	rp += rc * d;												
													
	if(rp < -M_PI / 4.0) {rp = -M_PI / 4.0; rc = 0; }
	if(rp > M_PI / 4.0) {rp = M_PI / 4.0; rc = 0; }			
	
	sideup->xp = xp - sin(rp) * -5;
	sideup->yp = yp + cos(rp) * -5;
	sideup->rp = rp;
	
	sidedown->xp = xp + cos(rp) * R - sin(rp) * 5;
	sidedown->yp = yp + sin(rp) * R + cos(rp) * 5;
	sidedown->rp = M_PI + rp;
	
	if(rc) rest = redraw = true;
		
}

void FlipperRight::move(float d) {		
													
	rp += rc * d;												
													
	if(rp < 3.0 * M_PI / 4.0) {rp = 3.0 * M_PI / 4.0; rc = 0; }
	if(rp > 5.0 * M_PI / 4.0) {rp = 5.0 * M_PI / 4.0; rc = 0; }			
		
	sideup->xp = xp + cos(rp) * R - sin(rp) * 5;
	sideup->yp = yp + sin(rp) * R + cos(rp) * 5;
	sideup->rp = M_PI + rp;	
	
	sidedown->xp = xp - sin(rp) * -5;
	sidedown->yp = yp + cos(rp) * -5;
	sidedown->rp = rp;	
	
	if(rc) rest = redraw = true;
}

void FlipperLeft::load() {	
	for(int i = 0; i < 7; i++) {
		char str[256];
		sprintf(str, "dat.dat#flipper_left%d.bmp", 1 + i);
		bmp[i] = load_bitmap(str, NULL);	
		if(!bmp[i]) {
			allegro_message("Error loading bitmap.\n"); exit(-1);
		}
	}
}

void FlipperRight::load() {
	for(int i = 0; i < 7; i++) {
		char str[256];
		sprintf(str, "dat.dat#flipper_right%d.bmp", 1 + i);
		bmp[i] = load_bitmap(str, NULL);	
		if(!bmp[i]) {
			allegro_message("Error loading bitmap.\n"); exit(-1);
		}
	}
}

void FlipperLeft::draw() {
	
	if(redraw) {	
		redraw = false;
		old = true;
		xo = xp;
		yo = yp;
		ro = rp;
		
		int a = int(6.9 * (M_PI/4 - rp) / (M_PI / 2));
		if(a > 0) a = a % 7;
		if(a < 0) a = (8 + a) % 7;
		
		draw_sprite(page, bmp[a], int(xo - 10), int(yo - 75));
	}			
	
}

void FlipperRight::draw() {
	
	if(redraw) {	
		redraw = false;
		old = true;
		xo = xp;
		yo = yp;
		ro = rp;
		
		int a = int(6.9 * (rp - 3*M_PI/4) / (M_PI / 2));
		if(a > 0) a = a % 7;
		if(a < 0) a = (8 + a) % 7;
		
		draw_sprite(page, bmp[a], int(xo - 80), int(yo - 75));
	}
		
}




