


#include <allegro_flare/grid2d.h>

#include <algorithm>






grid2d::grid2d()
	: horizontal_guide()
	, vertical_guide()
{}



void grid2d::add_horizontal_guide(float x)
{
	horizontal_guide.push_back(x);
}



void grid2d::add_vertical_guide(float y)
{
	vertical_guide.push_back(y);
}



float grid2d::get_max_horizontal_guide()
{
	std::vector<float>::iterator it = std::max_element(horizontal_guide.begin(), horizontal_guide.end());
	return (it==horizontal_guide.end()) ? 0 : *it;
}


float grid2d::get_max_vertical_guide()
{
	std::vector<float>::iterator it = std::max_element(vertical_guide.begin(), vertical_guide.end());
	return (it==vertical_guide.end()) ? 0 : *it;
}



float grid2d::get_min_horizontal_guide()
{
	std::vector<float>::iterator it = std::min_element(horizontal_guide.begin(), horizontal_guide.end());
	return (it==horizontal_guide.end()) ? 0 : *it;
}


float grid2d::get_min_vertical_guide()
{
	std::vector<float>::iterator it = std::min_element(vertical_guide.begin(), vertical_guide.end());
	return (it==vertical_guide.end()) ? 0 : *it;
}



int grid2d::get_closest_horizontal_guide_index(float x, float threshold)
{
	int index = 0;
	float dist = abs(x - horizontal_guide[index]);

	for (int i=0; i<(int)horizontal_guide.size(); i++)
	{
		float this_distance = abs(x - horizontal_guide[i]);
		if (this_distance < dist)
		{
			dist = this_distance;
			index = i;
		}
	}
	return index;
}



int grid2d::get_closest_vertical_guide_index(float y, float threshold)
{
	int index = 0;
	float dist = abs(y - vertical_guide[index]);

	for (int i=0; i<(int)vertical_guide.size(); i++)
	{
		float this_distance = abs(y - vertical_guide[i]);
		if (this_distance < dist)
		{
			dist = this_distance;
			index = i;
		}
	}
	return index;
}



vec2d grid2d::get_closest_coordinates(float x, float y, float threshold)
{
	int hgi = get_closest_horizontal_guide_index(x);
	int vgi = get_closest_vertical_guide_index(y);
	return vec2d(get_horizontal_guide_pos(hgi), get_vertical_guide_pos(vgi));
}



void grid2d::draw_guides(ALLEGRO_COLOR color)
{
	float left = get_min_horizontal_guide();
	float top = get_min_vertical_guide();
	float width = get_max_horizontal_guide();
	float height = get_max_vertical_guide();

	// draw horizontals
	for (unsigned i=0; i<horizontal_guide.size(); i++)
	{
		al_draw_line(horizontal_guide[i], top, horizontal_guide[i], height, color, 1.0);
	}

	// draw verticals
	for (unsigned i=0; i<vertical_guide.size(); i++)
	{
		al_draw_line(left, vertical_guide[i], width, vertical_guide[i], color, 1.0);
	}

	//al_draw_rectangle(0, 0, width, height, color::black, 2.0);
}



void grid2d::draw_guide_numbers(ALLEGRO_FONT *font, float padding, ALLEGRO_COLOR color)
{
	float left = get_min_horizontal_guide();
	float top = get_min_vertical_guide();
	float width = get_max_horizontal_guide();
	float height = get_max_vertical_guide();

	char str[32];

	// draw horizontals
	for (unsigned i=0; i<horizontal_guide.size(); i++)
	{
		sprintf(str, "%d", i);
		//al_draw_line(horizontal_guide[i], top, horizontal_guide[i], height, color::black, 1.0);
		al_draw_text(font, color, horizontal_guide[i], top - padding - al_get_font_ascent(font), ALLEGRO_ALIGN_CENTER, str);
	}

	// draw verticals
	for (unsigned i=0; i<vertical_guide.size(); i++)
	{
		sprintf(str, "%d", i);
		//al_draw_line(left, vertical_guide[i], width, vertical_guide[i], color::black, 1.0);
		al_draw_text(font, color, left - padding, vertical_guide[i] - al_get_font_ascent(font)/2, ALLEGRO_ALIGN_RIGHT, str);
	}

	//al_draw_rectangle(0, 0, width, height, color::black, 2.0);
}



float grid2d::get_horizontal_guide_pos(int index)
{
	if (index < 0) return 0;
	if (index >= horizontal_guide.size()) return 0;
	return horizontal_guide[index];
}



float grid2d::get_vertical_guide_pos(int index)
{
	if (index < 0) return 0;
	if (index >= vertical_guide.size()) return 0;
	return vertical_guide[index];
}



