package zmaster587.advancedRocketry.tile.infrastructure;
import java.util.LinkedList;
import java.util.List;
import io.netty.buffer.ByteBuf;
import cpw.mods.fml.relauncher.Side;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ChatComponentText;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import zmaster587.advancedRocketry.api.Configuration;
import zmaster587.advancedRocketry.api.EntityRocketBase;
import zmaster587.advancedRocketry.api.IInfrastructure;
import zmaster587.advancedRocketry.api.satellite.SatelliteBase;
import zmaster587.advancedRocketry.dimension.DimensionManager;
import zmaster587.advancedRocketry.entity.EntityRocket;
import zmaster587.advancedRocketry.inventory.TextureResources;
import zmaster587.advancedRocketry.api.IMission;
import zmaster587.libVulpes.client.util.IndicatorBarImage;
import zmaster587.libVulpes.client.util.ProgressBarImage;
import zmaster587.libVulpes.interfaces.ILinkableTile;
import zmaster587.libVulpes.inventory.modules.IButtonInventory;
import zmaster587.libVulpes.inventory.modules.IModularInventory;
import zmaster587.libVulpes.inventory.modules.IProgressBar;
import zmaster587.libVulpes.inventory.modules.ModuleBase;
import zmaster587.libVulpes.inventory.modules.ModuleButton;
import zmaster587.libVulpes.inventory.modules.ModuleProgress;
import zmaster587.libVulpes.inventory.modules.ModuleRedstoneOutputButton;
import zmaster587.libVulpes.inventory.modules.ModuleText;
import zmaster587.libVulpes.items.ItemLinker;
import zmaster587.libVulpes.network.PacketEntity;
import zmaster587.libVulpes.network.PacketHandler;
import zmaster587.libVulpes.network.PacketMachine;
import zmaster587.libVulpes.util.IAdjBlockUpdate;
import zmaster587.libVulpes.util.INetworkMachine;
import zmaster587.libVulpes.util.ZUtils.RedstoneState;
public class TileEntityMoniteringStation extends TileEntity implements IModularInventory, IAdjBlockUpdate, IInfrastructure, ILinkableTile, INetworkMachine, IButtonInventory, IProgressBar {
EntityRocketBase linkedRocket;
IMission mission;
ModuleText missionText;
RedstoneState state;
ModuleRedstoneOutputButton redstoneControl;
int rocketHeight;
int velocity;
int fuelLevel, maxFuelLevel;
public TileEntityMoniteringStation() {
mission = null;
missionText = new ModuleText(20, 90, "Mission Progress: N/A", 0x2b2b2b);
redstoneControl = new ModuleRedstoneOutputButton(174, 4, -1, "", this);
state = RedstoneState.ON;
}
@Override
public void invalidate() {
super.invalidate();
if(linkedRocket != null) {
linkedRocket.unlinkInfrastructure(this);
unlinkRocket();
}
if(mission != null) {
mission.unlinkInfrastructure(this);
unlinkMission();
}
}
public boolean getEquivilentPower() {
if(state == RedstoneState.OFF)
return false;
boolean state2 = worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord);
if(state == RedstoneState.INVERTED)
state2 = !state2;
return state2;
}
@Override
public void onAdjacentBlockUpdated() {
if(!worldObj.isRemote && getEquivilentPower() && linkedRocket != null) {
linkedRocket.prepareLaunch();
}
}
@Override
public int getMaxLinkDistance() {
return 300000;
}
@Override
public boolean onLinkStart(ItemStack item, TileEntity entity,
EntityPlayer player, World world) {
ItemLinker.setMasterCoords(item, this.xCoord, this.yCoord, this.zCoord);
if(player.worldObj.isRemote)
Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage((new ChatComponentText("You program the linker with the monitoring station at: " + this.xCoord + " " + this.yCoord + " " + this.zCoord)));
return true;
}
@Override
public boolean onLinkComplete(ItemStack item, TileEntity entity,
EntityPlayer player, World world) {
if(player.worldObj.isRemote)
Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage((new ChatComponentText("This must be the first machine to link!")));
return false;
}
@Override
public void unlinkRocket() {
linkedRocket = null;
}
@Override
public boolean disconnectOnLiftOff() {
return false;
}
@Override
public boolean linkRocket(EntityRocketBase rocket) {
this.linkedRocket = rocket;
return true;
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
state = RedstoneState.values()[nbt.getByte("redstoneState")];
redstoneControl.setRedstoneState(state);
if(nbt.hasKey("missionID")) {
long id = nbt.getLong("missionID");
int dimid = nbt.getInteger("missionDimId");
SatelliteBase sat = DimensionManager.getInstance().getSatellite(id);
if(sat instanceof IMission)
mission = (IMission)sat;
}
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
nbt.setByte("redstoneState", (byte) state.ordinal());
if(mission != null) {
nbt.setLong("missionID", mission.getMissionId());
nbt.setInteger("missionDimId", mission.getOriginatingDimention());
}
}
@Override
public void writeDataToNetwork(ByteBuf out, byte id) {
if(id == 1)
out.writeLong(mission == null ? -1 : mission.getMissionId());
else if(id == 2)
out.writeByte(state.ordinal());
}
@Override
public void readDataFromNetwork(ByteBuf in, byte packetId,
NBTTagCompound nbt) {
if(packetId == 1) {
nbt.setLong("id", in.readLong());
}
else if(packetId == 2) {
nbt.setByte("state", in.readByte());
}
}
@Override
public void useNetworkData(EntityPlayer player, Side side, byte id,
NBTTagCompound nbt) {
if(id == 1) {
long idNum = nbt.getLong("id");
if(idNum == -1) {
mission = null;
setMissionText();
}
else {
SatelliteBase base = DimensionManager.getInstance().getSatellite(idNum);
if(base instanceof IMission) {
mission = (IMission)base;
setMissionText();
}
}
}
else if(id == 2) {
state = RedstoneState.values()[nbt.getByte("state")];
}
if(id == 100) {
if(linkedRocket != null)
linkedRocket.prepareLaunch();
}
}
@Override
public Packet getDescriptionPacket() {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setByte("state", (byte)state.ordinal());
return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 0, nbt);
}
@Override
public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) {
state = RedstoneState.values()[pkt.func_148857_g().getByte("state")];
redstoneControl.setRedstoneState(state);
super.onDataPacket(net, pkt);
}
@Override
public List<ModuleBase> getModules(int ID, EntityPlayer player) {
LinkedList<ModuleBase> modules = new LinkedList<ModuleBase>();
modules.add(new ModuleButton(20, 40, 0, "Launch!", this, zmaster587.libVulpes.inventory.TextureResources.buttonBuild));
modules.add(new ModuleProgress(98, 4, 0, new IndicatorBarImage(2, 7, 12, 81, 17, 0, 6, 6, 1, 0, ForgeDirection.UP, TextureResources.rocketHud), this));
modules.add(new ModuleProgress(120, 14, 1, new IndicatorBarImage(2, 95, 12, 71, 17, 0, 6, 6, 1, 0, ForgeDirection.UP, TextureResources.rocketHud), this));
modules.add(new ModuleProgress(142, 14, 2, new ProgressBarImage(2, 173, 12, 71, 17, 6, 3, 69, 1, 1, ForgeDirection.UP, TextureResources.rocketHud), this));
modules.add(redstoneControl);
setMissionText();
modules.add(missionText);
modules.add(new ModuleProgress(30, 110, 3, TextureResources.progressToMission, this));
modules.add(new ModuleProgress(30, 120, 4, TextureResources.workMission, this));
modules.add(new ModuleProgress(30, 130, 5, TextureResources.progressFromMission, this));
if(!worldObj.isRemote) {
PacketHandler.sendToPlayer(new PacketMachine(this, (byte)1), player);
}
return modules;
}
private void setMissionText() {
if(mission != null) {
int time = mission.getTimeRemainingInSeconds();
int seconds = time % 60;
int minutes = (time/60) % 60;
int hours = time/3600;
missionText.setText(((SatelliteBase)mission).getName() + " Progress: " + String.format("\n%02dhr:%02dm:%02ds", hours, minutes, seconds));
}
else
missionText.setText("Mission Progess: N/A");
}
@Override
public void onInventoryButtonPressed(int buttonId) {
if(buttonId != -1)
PacketHandler.sendToServer(new PacketMachine(this, (byte) (buttonId + 100)) );
else {
state = redstoneControl.getState();
PacketHandler.sendToServer(new PacketMachine(this, (byte)2));
}
}
@Override
public String getModularInventoryName() {
return "container.monitoringstation";
}
@Override
public float getNormallizedProgress(int id) {
if(id == 1) {
return Math.max(Math.min(0.5f + (getProgress(id)/(float)getTotalProgress(id)), 1), 0f);
}
else if(id == 3) {
if(mission == null)
return 0f;
return (float) Math.min(3f*mission.getProgress(this.worldObj), 1f);
}
else if(id == 4) {
if(mission == null)
return 0f;
return (float) Math.min(Math.max( 3f*(mission.getProgress(this.worldObj) - 0.333f), 0f), 1f);
}
else if(id == 5) {
if(mission == null)
return 0f;
return (float) Math.min(Math.max( 3f*(mission.getProgress(this.worldObj) - 0.666f), 0f), 1f);
}
//keep text updated
if(worldObj.isRemote && mission != null)
setMissionText();
return getProgress(id)/(float)getTotalProgress(id);
}
@Override
public void setProgress(int id, int progress) {
if(id == 0)
rocketHeight = progress;
else if(id == 1)
velocity = progress;
else if(id == 2)
fuelLevel = progress;
}
@Override
public int getProgress(int id) {
//Try to keep client synced with server, this also allows us to put the monitor on a different world altogether
if(worldObj.isRemote)
if(mission != null && id == 0)
return getTotalProgress(id);
else if(id == 0)
return rocketHeight;
else if(id == 1)
return velocity;
else if(id == 2)
return fuelLevel;
if(linkedRocket == null)
return 0;
if(id == 0)
return (int)linkedRocket.posY;
else if(id == 1)
return (int)(linkedRocket.motionY*100);
else if (id == 2)
return (int)(linkedRocket.getFuelAmount());
return 0;
}
@Override
public int getTotalProgress(int id) {
if(id == 0)
return Configuration.orbit;
else if(id == 1)
return 200;
else if(id == 2)
if(worldObj.isRemote)
return maxFuelLevel;
else
if(linkedRocket == null)
return 0;
else
return linkedRocket.getFuelCapacity();
return 1;
}
@Override
public void setTotalProgress(int id, int progress) {
//Should only become an issue if configs are desynced or fuel
if(id == 2)
maxFuelLevel = progress;
}
@Override
public boolean canInteractWithContainer(EntityPlayer entity) {
return true;
}
@Override
public boolean linkMission(IMission misson) {
this.mission = misson;
PacketHandler.sendToNearby(new PacketMachine(this, (byte)1), worldObj.provider.dimensionId, xCoord, yCoord, zCoord, 16);
return true;
}
@Override
public void unlinkMission() {
mission = null;
setMissionText();
PacketHandler.sendToNearby(new PacketMachine(this, (byte)1), worldObj.provider.dimensionId, xCoord, yCoord, zCoord, 16);
}
@Override
public boolean canRenderConnection() {
return false;
}
}