/*
    ANTLand simulation
    (C) 2004 justin_sane

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    Contact: justinsanemsu@msu.edu

    FILE: collide.cpp
    Authors: justin_sane
*/

#include <math.h>

#pragma hdrstop

#include "world.h"
#include "utility.h"
#include "collide.h"
#include "ant.h"

#pragma package(smart_init)




/* returns true if the grid area at p had on obstructuon */
bool __fastcall grid_area_blocked(point p, vector<obstacle_class> &obstacles, vector<ant_class *> &ants )
{
    // check against all of the obstacles
    for (unsigned int i = 0; i < obstacles.size(); i++)
        if (obstacles[i].point_inside(p)) return(1);

    // check againnt the sim area boundrys
    if (p.x < 0 || p.x >= sim_x_size || p.y < 0 || p.y >= sim_y_size) return(1);

    // check against other ants
    for (unsigned int i = 0; i < ants.size(); i++)
        if (ants[i]->point_inside(p)) return(true);

    return(0); // position not blocked
}
/* end of grid_area_blocked */


/* returns if a a test point is "below" a line defined from pa to pb */
bool inline line_inside(point pa, point pb, float x, float y)
{
    point d = pa - pb;  // calculate the delta

    // x delta too small, revert to vertical line test
    if (fabs(d.x) < 0.00001)
    {
         if (d.y >= 0 && x > pa.x) return(false);
         if (d.y <  0 && x < pa.x) return(false);
    }
    else
    {
        float m = d.y / d.x;           // find slope
        float b = pa.y - m * pa.x;     // find intercept

        float test_y = m*x + b;

        if ((d.x >= 0 && y < test_y) ||
            (d.x <  0 && y > test_y)) return(false);
    }

    return(true);
}
/* End of line inside */


/* returns true of the passes grid cords are inside of the ant */
bool __fastcall point_in_box(point a, point b, point c, point d, float x, float y)
{
    return(line_inside(a, b, x, y) && line_inside(b, c, x, y) &&
           line_inside(c, d, x, y) && line_inside(d, a, x, y));
}
/* point_in_box */


/* returns true if we can set an ant here */
bool __fastcall okay_to_land(point pos, float dir,  vector<obstacle_class> &obstacles )
{
    // create a temporary bounding box
    point tmp_fr = forward_vector(pos, 2.5, dir - 25);
    point tmp_fl = forward_vector(pos, 2.5, dir + 25);
    point tmp_rr = forward_vector(pos, -2.5, dir + 25);
    point tmp_rl = forward_vector(pos, -2.5, dir - 25);

    // all of the bounding box points against the sim area boundries

    if ((tmp_fr.x < 0 || tmp_fr.x >= sim_x_size) ||
        (tmp_fr.y < 0 || tmp_fr.y >= sim_y_size) ||

        (tmp_fl.x < 0 || tmp_fl.x >= sim_x_size) ||
        (tmp_fl.y < 0 || tmp_fl.y >= sim_y_size) ||

        (tmp_rr.x < 0 || tmp_rr.x >= sim_x_size) ||
        (tmp_rr.y < 0 || tmp_rr.y >= sim_y_size) ||

        (tmp_rl.x < 0 || tmp_rl.x >= sim_x_size) ||
        (tmp_rl.y < 0 || tmp_rl.y >= sim_y_size)) return(false);

    if (obstacles.size() == 0) return (true); // empty simarea, okay to land


    // create a point to the first obstacle
    obstacle_class *t = &obstacles[0];

    // cross check colisions will all of the obstacles
    for (unsigned int i = 0; i < obstacles.size(); i++)
    {
        // check to see it any of the obstacle points are IN the ant
        if (point_in_box(tmp_rl, tmp_fl, tmp_fr, tmp_rr, t->get_upper_left().x, t->get_upper_left().y) ||
            point_in_box(tmp_rl, tmp_fl, tmp_fr, tmp_rr, t->get_upper_right().x, t->get_upper_right().y) ||
            point_in_box(tmp_rl, tmp_fl, tmp_fr, tmp_rr, t->get_lower_left().x, t->get_lower_left().y) ||
            point_in_box(tmp_rl, tmp_fl, tmp_fr, tmp_rr, t->get_lower_right().x, t->get_lower_right().y)) return (false);

        // check to see it any of the ant points are IN the obstacle
        if (t->point_inside(get_point(pos.x, pos.y)) ||
            t->point_inside(tmp_fl) || t->point_inside(tmp_fr) ||
            t->point_inside(tmp_rl) || t->point_inside(tmp_rr)) return(false);

       t++; // go to the next obstacle
    }

    return(true);
}
/* end of okay to land */








