/*
 * Caveworld
 *
 * Copyright (c) 2014 kegare
 * https://github.com/kegare
 *
 * This mod is distributed under the terms of the Minecraft Mod Public License 1.0, or MMPL.
 * Please check the contents of the license located in http://www.mod-buildcraft.com/MMPL-1.0.txt
 */

package com.kegare.caveworld.block;

import java.util.Random;

import mceconomy.api.MCEconomyAPI;
import net.minecraft.block.Block;
import net.minecraft.block.BlockPortal;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.passive.EntityBat;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.potion.Potion;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.Icon;
import net.minecraft.util.MathHelper;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.Teleporter;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;

import com.kegare.caveworld.core.Caveworld;
import com.kegare.caveworld.core.Config;
import com.kegare.caveworld.inventory.InventoryCaveworldPortal;
import com.kegare.caveworld.plugin.mceconomy.MCEconomyPlugin;
import com.kegare.caveworld.util.CaveUtils;
import com.kegare.caveworld.world.TeleporterCaveworld;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

public class BlockPortalCaveworld extends BlockPortal
{
	public final InventoryCaveworldPortal inventory = new InventoryCaveworldPortal();

	@SideOnly(Side.CLIENT)
	public Icon portalIcon;

	public BlockPortalCaveworld(int blockID, String name)
	{
		super(blockID);
		this.setUnlocalizedName(name);
		this.setTextureName("caveworld:caveworld_portal");
		this.setBlockUnbreakable();
		this.setLightOpacity(3);
		this.setLightValue(0.6F);
		this.setStepSound(soundGlassFootstep);
		this.disableStats();
		this.setCreativeTab(CreativeTabs.tabDecorations);
	}

	@Override
	@SideOnly(Side.CLIENT)
	public void registerIcons(IconRegister iconRegister)
	{
		blockIcon = iconRegister.registerIcon(getTextureName() + "_block");
		portalIcon = iconRegister.registerIcon(getTextureName());
	}

	@Override
	public int getRenderType()
	{
		return Config.RENDER_TYPE_PORTAL;
	}

	@Override
	public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z)
	{
		if (world.getBlockId(x - 1, y, z) != blockID && world.getBlockId(x + 1, y, z) != blockID)
		{
			setBlockBounds(0.35F, 0.0F, 0.0F, 0.65F, 1.0F, 1.0F);
		}
		else
		{
			setBlockBounds(0.0F, 0.0F, 0.35F, 1.0F, 1.0F, 0.65F);
		}
	}

	@Override
	public boolean tryToCreatePortal(World world, int x, int y, int z)
	{
		if (world.getBlockId(x - 1, y, z) == blockID || world.getBlockId(x + 1, y, z) == blockID || world.getBlockId(x, y, z - 1) == blockID || world.getBlockId(x, y, z + 1) == blockID)
		{
			return false;
		}

		byte var1 = 0;
		byte var2 = 1;

		if (world.getBlockId(x - 1, y, z) == Block.cobblestoneMossy.blockID || world.getBlockId(x + 1, y, z) == Block.cobblestoneMossy.blockID)
		{
			var1 = 1;
			var2 = 0;
		}

		if (world.isAirBlock(x - var1, y, z - var2))
		{
			x -= var1;
			z -= var2;
		}

		byte var3;
		byte var4;

		for (var3 = -1; var3 <= 2; ++var3)
		{
			for (var4 = -1; var4 <= 3; ++var4)
			{
				if (var3 != -1 && var3 != 2 || var4 != -1 && var4 != 3)
				{
					if (var3 == -1 || var3 == 2 || var4 == -1 || var4 == 3)
					{
						if (world.getBlockId(x + var1 * var3, y + var4, z + var2 * var3) != Block.cobblestoneMossy.blockID)
						{
							return false;
						}
					}
				}
			}
		}

		for (var3 = 0; var3 < 2; ++var3)
		{
			for (var4 = 0; var4 < 3; ++var4)
			{
				if (!world.isAirBlock(x + var1 * var3, y + var4, z + var2 * var3))
				{
					return false;
				}
			}
		}

		for (var3 = 0; var3 < 2; ++var3)
		{
			for (var4 = 0; var4 < 3; ++var4)
			{
				world.setBlock(x + var1 * var3, y + var4, z + var2 * var3, blockID, 0, 2);
			}
		}

		if (world.provider.dimensionId == 1)
		{
			world.newExplosion(null, x, y, z, 4.5F, true, true);
		}

		return true;
	}

	@Override
	public void onNeighborBlockChange(World world, int x, int y, int z, int blockId)
	{
		byte var1 = 0;
		byte var2 = 1;

		if (world.getBlockId(x - 1, y, z) == blockID || world.getBlockId(x + 1, y, z) == blockID)
		{
			var1 = 1;
			var2 = 0;
		}

		int var3 = y;

		while (world.getBlockId(x, var3 - 1, z) == blockID)
		{
			--var3;
		}

		if (world.getBlockId(x, var3 - 1, z) != Block.cobblestoneMossy.blockID)
		{
			world.setBlockToAir(x, y, z);
		}
		else
		{
			int var4 = 1;

			while (var4 < 4 && world.getBlockId(x, var3 + var4, z) == blockID)
			{
				++var4;
			}

			if (var4 == 3 && world.getBlockId(x, var3 + var4, z) == Block.cobblestoneMossy.blockID)
			{
				if ((world.getBlockId(x - 1, y, z) == blockID || world.getBlockId(x + 1, y, z) == blockID) && (world.getBlockId(x, y, z - 1) == blockID || world.getBlockId(x, y, z + 1) == blockID))
				{
					world.setBlockToAir(x, y, z);
				}
				else
				{
					if ((world.getBlockId(x + var1, y, z + var2) != Block.cobblestoneMossy.blockID || world.getBlockId(x - var1, y, z - var2) != blockID) && (world.getBlockId(x - var1, y, z - var2) != Block.cobblestoneMossy.blockID || world.getBlockId(x + var1, y, z + var2) != blockID))
					{
						world.setBlockToAir(x, y, z);
					}
				}
			}
			else
			{
				world.setBlockToAir(x, y, z);
			}
		}
	}

	@Override
	public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ)
	{
		if (!world.isRemote && side >= 2)
		{
			world.playSoundAtEntity(player, "random.click", 0.8F, 1.5F);

			if (MCEconomyPlugin.MCECONOMY && MCEconomyPlugin.MINERS_SHOP >= 0 && player.dimension == Config.dimensionCaveworld)
			{
				if (CaveUtils.isItemPickaxe(player.getCurrentEquippedItem()))
				{
					MCEconomyAPI.openShopGui(MCEconomyPlugin.MINERS_SHOP, player, world, x, y, z);

					return true;
				}
			}

			player.displayGUIChest(inventory.setPortalPosition(player, x, y, z));
		}

		return true;
	}

	@Override
	public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity)
	{
		if (!world.isRemote && entity.isEntityAlive() && (entity.dimension != Config.dimensionCaveworld || !Config.hardcoreEnabled))
		{
			if (entity.timeUntilPortal <= 0)
			{
				MinecraftServer server = Caveworld.proxy.getServer();
				int dimOld = entity.dimension;
				int dimNew = dimOld == Config.dimensionCaveworld ? entity.getEntityData().getInteger("Caveworld:LastDim") : Config.dimensionCaveworld;
				WorldServer worldOld = server.worldServerForDimension(dimOld);
				WorldServer worldNew = server.worldServerForDimension(dimNew);
				Teleporter teleporter = new TeleporterCaveworld(worldNew);

				entity.worldObj.removeEntity(entity);
				entity.isDead = false;
				entity.timeUntilPortal = entity.getPortalCooldown();

				if (entity instanceof EntityPlayerMP)
				{
					EntityPlayerMP player = (EntityPlayerMP)entity;

					if (!player.isSneaking() && !player.isPotionActive(Potion.confusion))
					{
						worldOld.playSoundToNearExcept(player, "caveworld:caveworld_portal", 0.5F, 1.0F);

						server.getConfigurationManager().transferPlayerToDimension(player, dimNew, teleporter);

						worldNew.playSoundAtEntity(player, "caveworld:caveworld_portal", 0.75F, 1.0F);

						player.getEntityData().setInteger("Caveworld:LastDim", dimOld);
					}
				}
				else
				{
					entity.dimension = dimNew;

					server.getConfigurationManager().transferEntityToWorld(entity, dimOld, worldOld, worldNew, teleporter);

					Entity target = EntityList.createEntityByName(EntityList.getEntityString(entity), worldNew);

					if (target != null)
					{
						worldOld.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "caveworld:caveworld_portal", 0.25F, 1.15F);

						target.copyDataFrom(entity, true);
						target.forceSpawn = true;

						worldNew.spawnEntityInWorld(target);
						worldNew.playSoundAtEntity(target, "caveworld:caveworld_portal", 0.5F, 1.15F);

						target.forceSpawn = false;
						target.getEntityData().setInteger("Caveworld:LastDim", dimOld);
					}

					entity.setDead();

					worldOld.resetUpdateEntityTick();
					worldNew.resetUpdateEntityTick();
				}
			}
			else
			{
				entity.timeUntilPortal = entity.getPortalCooldown();
			}
		}
	}

	@Override
	public void updateTick(World world, int x, int y, int z, Random random)
	{
		if (!world.isRemote && world.provider.isSurfaceWorld())
		{
			if (world.isDaytime() || !world.getGameRules().getGameRuleBooleanValue("doMobSpawning"))
			{
				return;
			}
			else if (!world.isBlockNormalCube(x, y + 1, z) && random.nextInt(300) < world.difficultySetting)
			{
				EntityLiving entity = CaveUtils.createEntity(EntityBat.class, world);

				if (entity != null)
				{
					entity.setLocationAndAngles(x + 0.5D, y + 0.75D, z + 0.5D, MathHelper.wrapAngleTo180_float(world.rand.nextFloat() * 360.0F), 0.0F);
					entity.rotationYawHead = entity.renderYawOffset = entity.rotationYaw;
					entity.timeUntilPortal = entity.getPortalCooldown();
					entity.onSpawnWithEgg(null);

					if (world.spawnEntityInWorld(entity))
					{
						entity.playLivingSound();
						entity.getEntityData().setBoolean("Caveworld:CaveBat", true);
					}
				}
			}
		}
	}

	@Override
	@SideOnly(Side.CLIENT)
	public void randomDisplayTick(World world, int x, int y, int z, Random random)
	{
		if (random.nextInt(200) == 0)
		{
			world.playSound(x + 0.5D, y + 0.5D, z + 0.5D, "ambient.cave.cave", 0.25F, random.nextFloat() * 0.4F + 0.8F, false);
		}

		if (random.nextInt(3) == 0)
		{
			double ptX = x + random.nextFloat();
			double ptY = y + 0.5D;
			double ptZ = z + random.nextFloat();

			world.spawnParticle("reddust", ptX, ptY, ptZ, 0.5D, 1.0D, 1.0D);
		}
	}

	@Override
	@SideOnly(Side.CLIENT)
	public int idPicked(World world, int x, int y, int z)
	{
		return blockID;
	}
}