#include <math.h>
#include "main.h"
#include "sprite.h"
#include "sprhelp.h"



void extrapolate_sprite_no_th(SPRITE *sprite) {

 float d = sprite->xv*sprite->xv +
           sprite->yv*sprite->yv +
           sprite->zv*sprite->zv;

 float r = 0.9 * sprite->r;

 if (d > r*r) {
  d = r / sqrt(d);
  sprite->x += sprite->xv * d;
  sprite->y += sprite->yv * d;
  sprite->z += sprite->zv * d;
 } else {
  sprite->x += sprite->xv;
  sprite->y += sprite->yv;
  sprite->z += sprite->zv;
 }
}



/* Adds the sprite velocity to the position, ensuring that the sprite is not
   moving too fast, and checking that the angle is within the primary range
   (0 - 2*M_PI).
*/
void extrapolate_sprite(SPRITE *sprite) {

 extrapolate_sprite_no_th(sprite);

 sprite->thv = MID(-M_PI/4.0, sprite->thv, M_PI/4.0);

 sprite->th += sprite->thv;

 while (sprite->th >= 2*M_PI) sprite->th -= 2*M_PI;
 while (sprite->th < 0) sprite->th += 2*M_PI;
}



int sprite_direction(float sth, float cth) {
 return (int)floor((sth - cth) * (4.0 / M_PI) + 0.5) & 7;
}


/* draw_generic_sprite(): 'bmp' is the bitmap on to which the sprite should
   be drawn. 'sprite' is the SPRITE struct (see sprite.h); it will be used
   for its 'xview', 'yview', 'xrad' and 'yrad' fields. 'spritebmp' is the
   image you want to use, and must have dimensions equal to powers of 2 (32,
   64, 128, etc.).

   This function won an award for most confusing parameter list, second only
   to the ENVELOPE statement on the BBC Microcomputer.
*/
void draw_generic_sprite(BITMAP *bmp, SPRITE *sprite, BITMAP *spritebmp,
                                                      int polytype) {

 float xl = sprite->xview - sprite->xrad;
 float xh = sprite->xview + sprite->xrad;
 float yl = sprite->yview - sprite->yrad;
 float yh = sprite->yview + sprite->yrad;

 float texw;
 float texh;

#ifndef ZIG_GL

 if (!spritebmp) {
		ellipsefill(bmp, (int)floor(sprite->xview), (int)floor(sprite->yview),
                   (int)sprite->xrad, (int)sprite->yrad, makecol(192,192,192));
		return;
 }

 
 texw = (float)spritebmp->w - 0.01;
 texh = (float)spritebmp->h - 0.01;

 {
 V3D_f vtx[] = {{xl, yl, 0, 0.01, 0.01, 0},
                {xl, yh, 0, 0.01, texh, 0},
                {xh, yh, 0, texw, texh, 0},
                {xh, yl, 0, texw, 0.01, 0}};

 quad3d_f(bmp, polytype, spritebmp, &vtx[0], &vtx[1], &vtx[2], &vtx[3]);
 }

#else
#endif
}


/* stc_stop(): callback function for use with sprite_tilemap_collision() in
   collide.h. This causes the sprite to stop dead on collision.
*/
void stc_stop(TILEMAP *map,
              SPRITE *sprite,
              float xi, float yi, float zi,
              float iv,
              int xt, int yt,
              TILE *tile, TILE_SURFACES *hit) {

 (void)map; (void)sprite; (void)xi; (void)yi; (void)zi; (void)iv; (void)xt;
 (void)yt; (void)tile; (void)hit;

 sprite->xv = 0;
 sprite->yv = 0;
 sprite->zv = 0;
 sprite->thv = 0;
}
