/*
 * This file is part of the Simutrans project under the Artistic License.
 * (see LICENSE.txt)
 */

/*
 * Convoi info stats, like loading status bar
 */

#include "gui_convoiinfo.h"
#include "../../world/simworld.h"
#include "../../vehicle/rail_vehicle.h"
#include "../../simconvoi.h"
#include "../../simcolor.h"
#include "../../simhalt.h"
#include "../../display/simgraph.h"
#include "../../display/viewport.h"
#include "../../tool/simmenu.h"
#include "../../player/simplay.h"
#include "../../simline.h"

#include "../../dataobj/translator.h"
#include "../../dataobj/schedule.h"

#include "../../utils/simstring.h"

class gui_convoi_images_t : public gui_component_t
{
	convoihandle_t cnv;
public:
	gui_convoi_images_t(convoihandle_t cnv) { this->cnv = cnv; }

	scr_size get_min_size() const OVERRIDE
	{
		return draw_vehicles( scr_coord(0,0), false);
	}

	scr_size draw_vehicles(scr_coord offset, bool display_images) const
	{
		scr_coord p = offset + get_pos();
		p.y += get_size().h/2;
		// we will use their images offsets and width to shift them to their correct position
		// this should work with any vehicle size ...
		scr_size s(0,0);
		unsigned count = cnv.is_bound() ? cnv->get_vehicle_count() : 0;
		for(unsigned i=0; i<count; i++) {
			const image_id image = cnv->get_vehicle(i)->get_loaded_image();
			scr_rect r = gfx->get_base_image_offset(image);
			if (display_images) {
				gfx->draw_base_img(image, p.x + s.w - r.x, p.y - r.y - r.h/2, cnv->get_owner()->get_player_nr(), false, true CLIP_NUM_DEFAULT);
			}
			s.w += (r.w*2)/3;
			s.h = max(s.h, r.h);
		}
		return s;
	}

	scr_size get_max_size() const OVERRIDE { return get_min_size(); }

	void draw( scr_coord offset ) OVERRIDE
	{
		draw_vehicles( offset, true);
	}
};


gui_convoiinfo_t::gui_convoiinfo_t(convoihandle_t cnv)
{
	this->cnv = cnv;
	old_income = 0xFFFFFFFFFFFFFFFFull;

	set_table_layout(3,0);
	set_alignment(ALIGN_LEFT | ALIGN_BOTTOM);

	// first row
	new_component<gui_empty_t>(); // could become posbutton to jump to convoi
	add_component(&label_name);
	new_component<gui_convoi_images_t>(cnv);

	// second row
	new_component<gui_empty_t>();
	add_component(&label_profit);
	filled_bar.add_color_value(&cnv->get_loading_limit(), gfx->palette_lookup(COL_YELLOW));
	filled_bar.add_color_value(&cnv->get_loading_level(), gfx->palette_lookup(COL_GREEN));
	add_component(&filled_bar);

	// third row
	pos_next_halt.init( button_t::posbutton_automatic, "" );
	add_component( &pos_next_halt );

	add_component( &label_next_halt );

	route_bar.init(&cnv_route_index, 0);
	if (cnv->get_vehicle_count() > 0 && dynamic_cast<rail_vehicle_t*>(cnv->front())) {
		// only for trains etc.
		route_bar.set_reservation(&next_reservation_index);
	}
	add_component(&route_bar);

	new_component<gui_empty_t>();
	add_component(&label_line,2);

	update_label();
}


bool gui_convoiinfo_t::infowin_event(const event_t *ev)
{
	if(cnv.is_bound()) {

		// check whether some child must handle this!
		if (gui_aligned_container_t::infowin_event(ev)) {
			return true;
		}

		if (IS_LEFTRELEASE(ev)) {
			if ((event_get_last_control_shift() ^ tool_t::control_invert) == 2) {
				world()->get_viewport()->change_world_position(cnv->get_pos());
			}
			else {
				cnv->open_info_window();
			}
			return true;
		}
		else if(IS_RIGHTRELEASE(ev)) {
			world()->get_viewport()->change_world_position(cnv->get_pos());
			return true;
		}
	}
	return false;
}


const char* gui_convoiinfo_t::get_text() const
{
	return cnv->get_name();
}


void gui_convoiinfo_t::update_label()
{
	bool size_change = old_income != cnv->get_jahresgewinn();
	old_income = cnv->get_jahresgewinn();

	label_profit.buf().append(translator::translate("Gewinn"));
	label_profit.buf().append_money(cnv->get_jahresgewinn() / 100.0);
	label_profit.update();

	label_line.buf().clear();
	if (cnv->in_depot()) {
		if (label_line.is_visible()) {
			label_line.buf();
			label_line.set_visible(false);
			size_change = true;
		}
		pos_next_halt.set_targetpos3d(cnv->get_home_depot());
		label_next_halt.set_text("(in depot)");
	}
	else {
		if( cnv->get_line().is_bound() ) {
			if (!label_line.is_visible()) {
				label_line.set_visible(true);
				size_change = true;
			}
			label_line.buf().printf( "%s: %s", translator::translate( "Line" ), cnv->get_line()->get_name() );
		}
		else {
			if (label_line.is_visible()) {
				label_line.buf();
				label_line.set_visible(false);
				size_change = true;
			}
		}
		label_line.update();

		switch (cnv->get_state()) {
		case convoi_t::WAITING_FOR_CLEARANCE:
		case convoi_t::CAN_START:
		case convoi_t::DRIVING:
			route_bar.set_state(0);
			break;
		case convoi_t::NO_ROUTE:
			route_bar.set_state(3);
			break;
		case convoi_t::WAITING_FOR_CLEARANCE_ONE_MONTH:
		case convoi_t::CAN_START_ONE_MONTH:
		case convoi_t::WAITING_FOR_CLEARANCE_TWO_MONTHS:
		case convoi_t::CAN_START_TWO_MONTHS:
			route_bar.set_state(2);
			break;
		default:
			route_bar.set_state(1);
			break;
		}
		if (!cnv->get_route()->empty()) {
			route_bar.set_base(cnv->get_route()->get_count() - 1);
			cnv_route_index = cnv->front()->get_route_index() - 1;
			next_reservation_index = cnv->get_next_reservation_index();

			halthandle_t h;
			const koord3d end = cnv->get_route()->back();

			if(  grund_t *gr = world()->lookup( end )  ) {
				h = gr->get_halt();
				// oil riggs and fish swarms can load anywhere in ther coverage area
				if(  !h.is_bound()  &&  gr->is_water()  &&  cnv->get_schedule()  &&  cnv->get_schedule()->get_waytype()==water_wt   ) {
					planquadrat_t *pl = world()->access( end.get_2d() );
					if(  pl->get_haltlist_count() > 0  ) {
						h = pl->get_haltlist()[0];
					}
				}
			}
			pos_next_halt.set_targetpos3d( end );
			scr_size old_min = label_next_halt.get_max_size();
			new_halt_name = (h.is_bound() ? h->get_name() : translator::translate("Wegpunkt"));
			label_next_halt.set_text(new_halt_name.c_str());
			if(old_min != label_next_halt.get_max_size()) {
				size_change = true;
			}
		}
		else {
			route_bar.set_base(1);
			cnv_route_index = 0;
			next_reservation_index = 0;
		}
	}

	label_name.set_text_pointer(cnv->get_name());
	label_name.set_color(cnv->get_status_color());

	if (size_change) {
		set_size(scr_size(get_size().w, get_min_size().h));
	}
}

/**
 * Draw the component
 */
void gui_convoiinfo_t::draw(scr_coord offset)
{
	if (cnv.is_bound()) {
		update_label();
	}
	gui_aligned_container_t::draw(offset);
}
