//
// map.hpp
//
// Header file for the programming contest on cartographic label placement.
//
// Copyright (c) 2000 by Dave Sullivan
// Written for Computer Science S-111 at Harvard University
//

#ifndef MAP_HPP
#define MAP_HPP

#include <fstream.h>

// Constants
#define X_MIN           36
#define Y_MIN           36
#define LABEL_WIDTH     60
#define LABEL_HEIGHT    12
#define MAP_WIDTH       (540 - (2 * LABEL_WIDTH)) 
#define MAP_HEIGHT      (720 - (2 * LABEL_HEIGHT))
#define NUM_LABEL_POSNS 4
#define NUM_ROWS        (MAP_HEIGHT/LABEL_HEIGHT + 1)
#define NUM_COLS        (MAP_WIDTH/LABEL_WIDTH + 1)

// The name of the file containing the Postscript code that
// must be included at the top of each map file.
#define HEADER_FILE     "map_header"


// The possible label positions
enum label_posn { UR, LR, UL, LL, NONE };

// advance declaration
struct overlap;

//
// A point feature on a map
//
class point {
    friend class map;	

private:
    map *my_map;            // the map that I belong to
    int x, y;               // x and y coordinates
    int row, col;           // the row and column of cell in which it falls
    label_posn lposn;       // the position of its label
    int num_overlaps;       // number of current pairwise overlaps 
                            // involving this point

    // lists of possible overlaps with this point, one for each label posn.
    overlap *poss_overlaps[NUM_LABEL_POSNS];  
    point *next;            // next point in the list of points for our cell

    void determine_possible_overlaps();

public:
    point(int x, int y, map *my_map);
    ~point();
    bool would_overlap(label_posn my_posn, point *other,
		       label_posn other_posn);
    int set_label_posn(label_posn posn);
    int change_in_score(label_posn posn);
    label_posn get_label_posn() { return lposn; }
    int get_num_overlaps() { return num_overlaps; }
};


//
// A struct used to store information about possible overlaps.
//
// Each point maintains four lists of these, one for each label_posn.
// For example, my_pt->poss_overlaps[UL] is a list of all overlaps that
// can occur when my_pt's label in in the upper-left corner.
//
// Each struct includes the point whose label might be overlapped (pt),
// and a one-byte bitmap (overlap_positions) that stores the set of
// positions for its label that would lead to overlap.
//
struct overlap {
	point *pt;
	char overlap_positions;
	overlap *next;
};

//
// A map
//
// For the sake of easy access to points in a given region of the map,
// a rectangular grid is superimposed on the map, and points are
// associated with the cell in which they fall.  Each cell is the size
// of a label.
// For example, points[r][c] is a linked list of the points that fall in
// the rectangular cell located at row r and column c in the grid.
// The upper left-hand corner of the map is row 0, column 0.
//
class map {
    friend class point;
    
private:
    point* points[NUM_ROWS][NUM_COLS]; 
    int num_points[NUM_ROWS][NUM_COLS];
    int total_points;
    bool existing_point(int x, int y);	
    void draw_labels(ofstream &file);
    void draw_points(ofstream &file);	  

public:
    map();
    ~map();
    void add_point(int x, int y);
    point* first_point();
    point* next_point(point *pt);
    point* first_point_in_cell(int row, int col);
    int num_points_in_cell(int row, int col);
    void determine_possible_overlaps();
    int score();
    int get_total_points() { return total_points; }
    void generate_points(int num_pts);
    int read_points(char *filename);
    void write_points(char *filename);
    void remove_labels();	
    void clear();
    bool generate_postscript(char *filename);
};

#endif
