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

#include "intro/intro.h"
#include "core/core.h"
#include "core/parser.h"
#include "filesystem/filesystem.h"
#include "filesystem/inifile.h"
#include "math/color.h"
#include "sys/sys.h"

namespace intro {

core::Module *factory()
{
	return new Intro();
}

Intro::Intro() : core::Module("Project::OSiRiON", false)
{
	if (!load_world()) {
		abort();
		return;
	}

	core::Func *func = 0;

	func = core::Func::add("intro", Intro::func_intro);
	func->set_info("[int] view specified introduction");
}

bool Intro::load_world()
{
	std::string filename("intro");

	filesystem::IniFile ini;
	ini.open(filename);

	if (!ini.is_open()) {
		con_error << "Could not open " << ini.name() << std::endl;
		return false;
	}

	core::Zone *zone = 0;
	Convoy *convoy = 0;

	std::string strval;
	core::EntityGlobe *globe = 0;
	math::Color color;
	math::Vector3f v;
	float f;
	bool b;
	
	while (ini.getline()) {

		if (ini.got_section()) {
			if (ini.got_section("intro")) {

				zone = new core::Zone("intro");
				zone->set_name("Introduction");
				zone->set_sky("sky");
				core::Zone::add(zone);
	
			} else if (ini.got_section("convoy")) {
				if (zone) {
					convoy = new Convoy(zone);
				}
	
			} else if (ini.got_section("globe")) {
				if (zone) {
					globe = new core::EntityGlobe();
					globe->set_zone(zone);
				}
	
			} else {
				ini.unknown_section();
			}
		} else if (zone && ini.got_key()) {

			if (ini.in_section("intro")) {

				if (ini.got_key_string("label", strval)) {
					zone->set_label(strval);
	
				} else  if (ini.got_key_string("sky", strval)) {
					zone->set_sky(strval);

				} else if (ini.got_key()) {
					ini.unkown_key();
				}

			} else if (ini.in_section("convoy")) {

				if (ini.got_key_string("label", strval)) {
					convoy->set_label(strval);

				} else if (ini.got_key_color("color", color)) {
					convoy->set_color(color);

				} else if (ini.got_key_color("colorsecond", color)) {
					convoy->set_color_second(color);

				} else if (ini.got_key_vector3f("location", v)) {
					convoy->entity_location.assign(v);

				} else if (ini.got_key_float("direction", f)) {
					convoy->axis().change_direction(f);

				} else if (ini.got_key_float("speed", f)) {
					convoy->entity_speed = f;

				} else if (ini.got_key_string("ship", strval)) {
					convoy->add(strval);

				} else if (ini.got_key()) {
					ini.unkown_key();
				}

			} else if (ini.in_section("globe")) {

				if (core::Parser::got_entity_key(ini, globe)) {
					continue;
				} else if (ini.got_key_string("texture", globe->entity_texture)) {
					continue;
				} else if (ini.got_key_float("rotationspeed", globe->entity_rotationspeed)) {
					continue;
				} else if (ini.got_key_bool("bright", b)) {
					if (b) { globe->set_flag(core::Entity::Bright); }
				} else if (ini.got_key()) {
					ini.unkown_key();
				}
			}
		}
	}

	return true;
}

void Intro::player_connect(core::Player *player)
{
	core::Zone::Registry::iterator it = core::Zone::registry().begin();
	if (it != core::Zone::registry().end()) {
		size_t m = math::randomi(core::Zone::registry().size());
		for (size_t i = 0; i < m; i++) {
			it++;
		}
		player->set_zone((*it).second);
	}
}

void Intro::player_disconnect(core::Player *player)
{

}

void Intro::frame(float seconds)
{

}

Intro::~Intro()
{
	core::Func::remove("intro");
}

void Intro::func_intro(core::Player *player, std::string const &args)
{
	std::stringstream str(args);
	size_t id;
	if (str >> id) {
		core::Zone *zone = core::Zone::find(id);
		if (zone) {
			player->set_zone(zone);
		} else {
			core::Zone::list();
		}
	} else {
		core::Zone::list();
	}
}

}