/* 
    Robot Simulator

    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.

    (C) 2006 Jason Hunt
    nulluser@gmail.gom 
*/


#ifndef WORLD_H
#define WORLD_H

#include <windows.h>
#include "utility.h"
#include "map.h"

// Resolution of gradient display grid
#define NUM_Y_GRAD 75
#define NUM_X_GRAD 75



// Linked list type for impacts
typedef struct impact_type
{
    double x, y;
    impact_type *next;
};


// Linked list type for markers
typedef struct marker_type
{
    double x, y;
    marker_type *next;
};


// Linked list type for walls
typedef struct wall_type
{
    double x, y;
    double x_size, y_size;
    wall_type *next;
};


// Linked list type for waypoints
typedef struct waypoint_type
{
    double x, y;
    double dir;
    
    int num;                // Number of waypoint
                            // Goal waypoint is zero
    
    waypoint_type *next;
};


// World structure
typedef struct world_type
{
    // Brushes for drawing
    HBRUSH white_brush;
    HBRUSH black_brush;
    HBRUSH green_brush;
    HBRUSH blue_brush;
    HBRUSH red_brush;
    HBRUSH color1_brush;

    // Pens for drawing    
    HPEN white_pen;
    HPEN black_pen;
    HPEN green_pen;
    HPEN blue_pen;
    HPEN color1_pen;

    // Size of world
    double x_size, y_size;           
    
    // Wall data    
    wall_type *walls;
    unsigned int num_walls;

    // Waypoint data    
    waypoint_type *waypoints;    
    unsigned int num_waypoints;
        
    // the waypoint we are tracking toward
    int cur_waypoint;
        
        
    // Marker data
    marker_type *markers;

    // Impact data
    impact_type *impacts;    
    unsigned int num_impact;
    

    // True to display walls
    bool show_walls;
    
    // Coords of goal
    double target_x, target_y;
    
    // True of target is to be followed
    bool target_enabled;
    
    // True if we are going to display the gradient grid    
    bool draw_grad;
    
    
    // Tweakable values
    double scale1;
    double scale2;
    double scale3;
    
    // Stored map grid
    int map_grid[MAP_GRID_X][MAP_GRID_Y];
};

extern world_type world;


void world_setup( void );               // Init world
void world_destroy( void );             // UnInit world
void world_draw( HDC dc );              // Display world
void world_update( void );              // Update world

int get_screen_x( double x );           // Convert world to screen pos
int get_screen_y( double y );

double get_world_x( unsigned int x);    // Convert Screen to world pos
double get_world_y( unsigned int y);

int get_map_x(double x);                // Convert world to map pos
int get_map_y(double y);


// Determine bounding rectangle for world scace coords
void get_bounding_rect(double x, double y, double x_size, double y_size, RECT &r);


// Wall functions
void world_add_wall(double x, double y, double y_size, double x_size);
void world_free_walls( void );
void world_draw_walls( HDC dc );
bool world_check_wall_point( double x, double y );

// Set target position
void world_set_target(double x, double y);

// Marker functions
void world_draw_markers( HDC dc );
void world_free_markers( void );
void world_add_marker(double x, double y);

// Impact functions
void world_draw_impacts( HDC dc );
void world_free_impacts( void );
void world_add_impact(double x, double y);

// Waypoint functions
void world_free_waypoints( void);
void world_draw_waypoints(HDC dc);
void world_add_waypoint(double x, double y, double dir);

// Gradient functions
void world_draw_grad(HDC dc);
void compute_grad_point(double x, double y, double &dir, double &mag);


void world_save( void );
void world_load( void );

#endif





