package ncrashed.warp.api;

import java.util.List;

import ncrashed.warp.api.volume.IVolume;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.world.World;

public interface IWarpCore 
{
	public static final int CONSTRUCTED_EVENT = 1;
	
	/**
	 * Габариты настроены правильно - true.
	 * @return
	 */
	boolean isVolumed();
	
	/**
	 * Вернет true, если ядро собрано. После сборки ядра маркеры не привязываются.
	 * @return
	 */
	boolean isConstructed();
	
	/**
	 * Вернет true, если ядро собрано и готово к прыжку.
	 * @return
	 */
	boolean isReady();
	
	/**
	 * Получает количество тиков до окончания кулдауна.
	 * @return
	 */
	int getCooldownTicks();
	
	/**
	 * Получает количество секунд до окончания кулдауна.
	 * @return
	 */
	int getCooldownSecs();
	
	/**
	 * Добавить к счетчику кулдауна ticks тиков. 
	 * @param ticks
	 * @return
	 */
	void addCooldownTicks(int ticks);
	
	/**
	 * Структура ядра, определяет пространственное положение его частей и условий собранности.
	 * @return
	 */
	ICoreStructure getCoreStructure();
	
	/**
	 * Получает описание габаритов, привязанных к ядру.
	 * @return
	 */
	IVolume getCoreVolume();
	
	/**
	 * Мир, в котором находится ядро.
	 * @return
	 */
	World getCoreWorld();
	
	/**
	 * Активация ядра, считывание значений каунтеров и выполнение соответствующего действия.
	 * Вернет true при успешном варпе, вернет false при фейле (не хватило энергии, не та фаза
	 * луны и т.п.)
	 * @return
	 */
	boolean activate();
	
	/**
	 * Регистрация реакции ядра на определенные значения каунтеров.
	 * @param action
	 */
	void registerAction(ICoreAction action);
	
	/**
	 * Получение положения ядра
	 * @return
	 */
	int getCoreX();
	
	/**
	 * Получение положения ядра
	 * @return
	 */
	int getCoreY();
	
	/**
	 * Получение положения ядра
	 * @return
	 */
	int getCoreZ();
	
	/**
	 * Получение id ядра.
	 * @return
	 */
	int getCoreID();
	
	/**
	 * Установка id ядра.
	 * @param id
	 */
	void setCoreID(int id);
	
	/**
	 * Принудительное обновление структуры ядра.
	 */
	void checkConstruction();
	
	
	/**
	 * Аналогично EntityTile.isInvalid()
	 * @return
	 */
	boolean isInvalid();
	
	/**
	 * Добавление игрока в команду корабля. Члены экипажа могут
	 * быть телепортированы на корабль ядром (если ядро поддерживает эту функцию)
	 * и не считаются вражескими единицами системой защиты. 
	 * @param player
	 * @return true если привязка произошла успешно.
	 */
	boolean addPlayerCrew(EntityPlayerMP player);
	
	/**
	 * Проверка, принадлежит ли игрок коменде корабля.
	 * @param player
	 * @return 
	 */
	boolean isPlayerCrew(EntityPlayerMP player);
	
	/**
	 * Отчисляет игрока из команды корабля. 
	 * @param player
	 * @return true при успешной отвязке.
	 */
	boolean exludePlayerCrew(EntityPlayerMP player);
	
	/**
	 * Количество урона, наносящегося игроку при успешной привязке.
	 * @return
	 */
	int getDamageOnCrewSuccess();
	
	/**
	 * Количество урона, наносящегося игроку при неуспешной привязке.
	 * @return
	 */
	int getDamageOnCrewFail();
	
	/**
	 * Получение списка имен экипажа.
	 * @return
	 */
	List<String> getCrew();
	
	/**
	 * Получение экипажа, который сейчас присутствует в игре.
	 * @return
	 */
	List<EntityPlayerMP> getCrewInGame();
	
	/**
	 * Получение экипажа на борту.
	 * @return
	 */
	List<EntityPlayerMP> getCrewOnBoard();
	
	/**
	 * Получение экипажа вне борта и сейчас присутствующих в игре.
	 * @return
	 */
	List<EntityPlayerMP> getCrewNotOnBoard();
	
	/**
	 * Некоторые команды используют экспандеры для вывода информации, 
	 * а они еще использются ядром для вывода сигналов о готовности, состоянии сборки.
	 * Этот метод обнуляет счетчики для проверки всех этих сигналов, давая время для 
	 * считывания данных.
	 */
	void restartCheckingTickers();
	
	/**
	 * Определяет, было ли неудачно исполнено предыдущее действие ядра.
	 * @return
	 */
	boolean isLastActionFailed();
	
	/**
	 * Возвращает id (внутренний) экспандера, на который выводятся ошибки.
	 * @return
	 */
	int getErrorExpanderID();
	
	/**
	 * Возвращает номер бита, куда выводится сигнал о нехватке энергии.
	 * @return
	 */
	int getNotEnoughEnergyBitError();
	
	/**
	 * Возвращает номер бита, куда выводится сигнал о результате последнего действия.
	 * @return
	 */
	int getResultBit();
}
