/*
   client/galaxymapwidget.cc
   This file is part of the Osirion project and is distributed under
   the terms of the GNU General Public License version 2
*/

#include "client/galaxymapwidget.h"
#include "core/application.h"
#include "ui/paint.h"
#include "render/render.h"
#include "render/gl.h"
#include "ui/ui.h"

namespace client {

GalaxyMapWidget::GalaxyMapWidget(ui::Widget *parent) : ui::Widget(parent)
{
	set_label("galaxymapwidget");
	galaxymapwidget_zone = 0;
	galaxymapwidget_hover_id = 0;
	galaxymapwidget_zoom = 1.0f;
}

GalaxyMapWidget::~GalaxyMapWidget()
{
	
}

void GalaxyMapWidget::set_zoom(const float zoom)
{
	galaxymapwidget_zoom = zoom;
}

void GalaxyMapWidget::set_zone(core::Zone *zone)
{
	galaxymapwidget_zone = zone;
}

bool GalaxyMapWidget::on_keypress(const int key, const unsigned int modifier)
{
	if (key == 512 + SDL_BUTTON_LEFT) {
		if (has_mouse_focus() && hover()) {
			if (zone() && (zone()->id() == hover())) {
				emit(ui::Widget::EventDoubleClicked);
			} else {
				set_zone(core::Zone::find(hover()));
				emit(ui::Widget::EventClicked);
			}
		}
		return true;

	}
	return false;
}

void GalaxyMapWidget::draw()
{
	// size and global location of the map
	const float map_size = math::min(width(), height());
	math::Vector2f map_location(global_location());
	
	if (map_size < width()) {
		map_location[0] += (width() - map_size) * 0.5f;
	}
	if (map_size < height()) {
		map_location[1] += (height() - map_size) * 0.5f;
	}

	// draw widget background
	math::Vector2f background_size(map_size, map_size);	
	ui::Paint::draw_bitmap(map_location, background_size, math::Color(), "bitmaps/ui/map_background");
	
	// number of squares in one grid segment
	const float grid_size = 16.0f;
	
	// draw the grid itself
	gl::color(0, 0, 0.25f);
	gl::begin(gl::Lines);
	
	for (float i = 0; i <= grid_size; i += 1.0f) {
		gl::vertex(map_location.x(), map_location.y() + map_size / grid_size * i);
		gl::vertex(map_location.x() + map_size, map_location.y() + map_size / grid_size * i);

		gl::vertex(map_location.x() + map_size / grid_size * i, map_location.y());
		gl::vertex(map_location.x() + map_size / grid_size * i, map_location.y() + map_size);
	}
	gl::end();

	// request required textures
	const size_t texture_zone = render::Textures::load("bitmaps/icons/entity_default");
	render::Textures::bind(texture_zone);

	// global mouse cursor location
	const math::Vector2f cursor(ui::root()->global_mouse_coords());
	galaxymapwidget_hover_id = 0;
	
	// map center
	//math::Vector2f map_center(map_location[0] + map_size / 2.0f,  map_location[1] + map_size / 2.0f);
	math::Vector2f icon_location;
	const float r = 12.0f; 		// radius of map icons	
	float scale = 1024.0f; 		// galaxy size (in zone location units)
	math::Color color(1.0f, 1.0f, 1.0f, 1.0f);
	const core::Zone *zone = 0;

	// draw map icons
	/*
	 * Note: the galactic coordinate system differs from the zone coordinate system:
	 * positive X-axis runs left-to-right on the screen and the positive U-axis runs bottom-to-top on the screen.
	 * 
	 * This is because I'm lazy and I just copy the coordinates from the SVG starsystem roadmap as shown in Inkscape.
	 */
	gl::enable(GL_TEXTURE_2D);
	gl::begin(gl::Quads);


	for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) {
		zone = (*it).second;
		
		if (zone->has_flag(core::Zone::Hidden)) {
			continue;
		}
	
		bool draw_icon = true;
		
		icon_location.assign(map_location);
		icon_location[0] += map_size / scale * zone->location().x();		
		icon_location[1] += map_size - map_size / scale * zone->location().y(); // flip vertically
		
		if (math::distancesquared(cursor, icon_location) < (r*r)) {
			galaxymapwidget_hover_id = zone->id();
		}
		
		if (zone == galaxymapwidget_zone) {
			if (core::application()->time() - floorf(core::application()->time()) < 0.5f) {
				draw_icon = false;
			}
		}
		
		// TODO draw a ship icon for current location
		if (draw_icon) {
			color.assign(zone->color());
			
			gl::color(color);
			glTexCoord2f(0.0f, 0.0f);
			gl::vertex(icon_location.x() - r, icon_location.y() - r);

			glTexCoord2f(1.0f, 0.0f);
			gl::vertex(icon_location.x() + r, icon_location.y() - r);

			glTexCoord2f(1.0f, 1.0f);
			gl::vertex(icon_location.x() + r, icon_location.y() + r);

			glTexCoord2f(0.0f, 1.0f);
			gl::vertex(icon_location.x() - r, icon_location.y() + r);
		}

	}
	
	gl::end();
	gl::disable(GL_TEXTURE_2D);
	
	if (has_mouse_focus()) {
		if (galaxymapwidget_hover_id)
			ui::root()->set_pointer("target", ui::Palette::Active, true);
	}
}

} // namespace client