<?php

include_once("internal/tracker.php");
include_once("internal/log.php");

// --------------------------------------------

abstract class MapRotator extends Tracker {
	protected $metagame = NULL;
	protected $stages_completed = array();
	protected $current_stage_index = 0;

	// --------------------------------------------
	function __construct($metagame) {
		$this->metagame = $metagame;
	}

	// --------------------------------------------
	function init() {
	}

	// --------------------------------------------
	function start($begin_only = false) {
		// pick first map, and change to it
		$index = $this->get_next_stage_index();

		global $SKIP_START;
		if ($SKIP_START) {
			$begin_only = true;
		} 

		// normal
		$this->start_map($index, $begin_only);
	}

	// --------------------------------------------
	abstract protected function get_stage_count();
	abstract protected function get_map_name($index);
	abstract protected function get_change_map_command($index);
	abstract protected function get_start_game_command($index);
	abstract protected function get_next_stage_index();

	// --------------------------------------------
	// match status events
	// --------------------------------------------
	protected function handle_match_end($doc) {
		// always advance to next map

		// not real data to add about it, is there a "set" in php?
		$this->stages_completed[$this->current_stage_index] = true;

		// if all maps have been completed, start over
		if (count($this->stages_completed) == $this->get_stage_count()) {
			_log("all maps completed, resetting");
			$this->stages_completed = array();
		}

		// share some information with the server (and thus clients)
		$index = $this->get_next_stage_index();
		$map_name = $this->get_map_name($index);

		// map change needed
		_log("next map: index " . $index . ", " . $map_name);
		$this->metagame->comms->send("say next map " . $map_name);

		// wait a while, and let server announce a few things
		$this->metagame->task_sequencer->add(new TimeAnnouncerTask($this->metagame, 30, true));

		$this->metagame->task_sequencer->add(new GenericCallTask($this, "start_map", array($index))); // --> translates to $this->start_map($index) as delayed call
	}

	// --------------------------------------------
	function has_ended() {
		// always on
		return false;
	}

	// --------------------------------------------
	function has_started() {
		// always on
		return true;
	}

	public function save(&$doc, &$root) {
	}

	public function load(&$doc, &$root) {
	}

	// --------------------------------------------
	// --------------------------------------------
	// --------------------------------------------
	// --------------------------------------------
	public function start_map($index, $begin_only = false) {
		$this->current_stage_index = $index;

		$this->metagame->pre_begin_match();

		if (!$begin_only) {
			// change map 
			$change_map_command = $this->get_change_map_command($index);
			$this->metagame->comms->send($change_map_command);

			// start game 
			$start_game_command = $this->get_start_game_command($index);
			$this->metagame->comms->send($start_game_command);
		}

		// TODO: would be actually better to call match begin once the map has actually loaded and game started
		// but it doesn't matter really
		$this->metagame->post_begin_match();
	}

	protected function restart_map() {
		$index = $this->current_stage_index;

		$this->metagame->pre_begin_match();

		// restart same map
		$start_game_command = $this->get_start_game_command($index);
		$this->metagame->comms->send($start_game_command);

		$this->metagame->post_begin_match();

	}

}

?>