package ncrashed.warp;

import ic2.core.block.wiring.TileEntityElectricBlock;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;

import com.eloraam.redpower.control.TileIOExpander;
import com.eloraam.redpower.core.BluePowerConductor;
import com.eloraam.redpower.core.CoreLib;
import com.eloraam.redpower.core.IBluePowerConnectable;
import com.eloraam.redpower.lighting.TileShapedLamp;
import com.eloraam.redpower.logic.TileLogicStorage;
import com.eloraam.redpower.logic.TileLogicStorage$LogicStorageCounter;
import com.eloraam.redpower.logic.TileLogicStorage$LogicStorageModule;

/**
 * Здесь собраны методы для работы с другими модами, такими как RedPower2 и IndustrialCraft2
 * @author NCrashed
 *
 */
public class ModHelper 
{
	/**
	 * Информация о текущем состоянии элемента сети Bluetricity.
	 * @author NCrashed
	 *
	 */
	public static class BlueInfo
	{
		public double voltage;
		public double amperage;
		public double power;
		
		public BlueInfo(double voltage, double amperage)
		{
			this.voltage = voltage;
			this.amperage = amperage;
			this.power = voltage*amperage;
		}
	}
	
	/**
	 * Измерить текущие параметры bluetricity в блоке. Вернет null, если блок не проводит
	 * ток.
	 * @param world
	 * @param x
	 * @param y
	 * @param z
	 * @param side
	 * @return
	 */
    public static BlueInfo rp2MeasureBlue(World world, int x, int y, int z, int side)
    {
        IBluePowerConnectable powerConn = (IBluePowerConnectable)CoreLib.getTileEntity(world, x, y, z, IBluePowerConnectable.class);

        if (powerConn == null)
        {
            return null;
        }
        else
        {
            BluePowerConductor conductor = powerConn.getBlueConductor(side);
            return new BlueInfo(conductor.getVoltage(), conductor.Itot);
        }
    }
    
    /**
     * Если в указанной точке есть ic2 хранилище энергии, то пытается забрать из него amount энергии.
     * Вернет количество энергии, которое было забрано у ic2 хранилища, или 0, если там хранилища не оказалось.
     * @param world
     * @param x
     * @param y
     * @param z
     * @param amount
     * @return
     */
    public static int ic2SunkEnergy(World world, int x, int y, int z, int amount)
    {
    	TileEntity ent = world.getBlockTileEntity(x, y, z);
    	if(ent == null || !(ent instanceof TileEntityElectricBlock)) return 0;
    	TileEntityElectricBlock storage = (TileEntityElectricBlock)ent;
    	
    	int oldEnergy = storage.getStored();
    	if(oldEnergy >= amount) 
    	{
    		storage.setStored(oldEnergy-amount);
    		return amount;
    	} else
    	{
    		storage.setStored(0);
    		return oldEnergy;
    	}
    }
    
    /**
     * Если в указанной точке есть ic2 хранилище энергии, то вернет запасенную в нем энергию, иначе вернет 0.
     * @param world
     * @param x
     * @param y
     * @param z
     * @return
     */
    public static int ic2GetEnergy(World world, int x, int y, int z)
    {
    	TileEntity ent = world.getBlockTileEntity(x, y, z);
    	if(ent == null || !(ent instanceof TileEntityElectricBlock)) return 0;
    	TileEntityElectricBlock storage = (TileEntityElectricBlock)ent;
    	
    	return storage.getStored();
    }
    
    /**
     * Получить значение каунтера в заданной точке, если там нет каунтера вернет -1.
     * @param world
     * @param x
     * @param y
     * @param z
     * @return
     */
    public static int rp2GetCounterValue(World world, int x, int y, int z)
    {
    	return rp2GetCounterValue(world.getBlockTileEntity(x, y, z));
    }
    
    /**
     * Получить значение каунтера в заданной точке, если entity не является каунтером вернет -1.
     * @param world
     * @param x
     * @param y
     * @param z
     * @return
     */    
    public static int rp2GetCounterValue(TileEntity counterEntity)
    {
    	if(counterEntity == null || !(counterEntity instanceof TileLogicStorage)) return 0;
    	TileLogicStorage entity = (TileLogicStorage)counterEntity;
    	
    	TileLogicStorage$LogicStorageCounter storage = (TileLogicStorage$LogicStorageCounter)entity.getLogicStorage(TileLogicStorage$LogicStorageModule.class);
    	if(storage == null) return 0;
    	
    	return storage.Count;
    }
    
    /**
     * Установка значение IOExpander в value. Если энтити не является экспандером, ничего не делает.
     * @param expander
     * @param value
     */
    public static void rp2SetIOExpander(TileEntity expander, int value)
    {
    	if(expander == null || !(expander instanceof TileIOExpander)) return;
    	TileIOExpander tile = (TileIOExpander)expander;
    	
    	tile.WBuf = value;
    	tile.RBuf = value;
    	tile.onBlockNeighborChange(0);
    	tile.updateBlockChange();
    }
    
    /**
     * Чтение выходов IOExpander. Если энтити не является экспандером, вернет 0.
     * @param expander
     * @return
     */
    public static int rp2GetIOExpander(TileEntity expander)
    {
    	if(expander == null || !(expander instanceof TileIOExpander)) return 0;
    	TileIOExpander tile = (TileIOExpander)expander;
    	
    	return tile.WBuf;
    }
    
    /**
     * Если блок является лампой, то обновляет световую информацию.
     * @param entity
     */
    public static void rp2UpdateLighting(TileEntity entity)
    {
    	if(entity == null || !(entity instanceof TileShapedLamp)) return;
    	
    	TileShapedLamp lamp = (TileShapedLamp)entity;
    	
    	lamp.onBlockNeighborChange(0);
    }
}
