package net.minecraft.command;

import java.util.List;

import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.structure.StructureBoundingBox;

/**
 * + This portion of EaglercraftX contains deobfuscated Minecraft 1.8 source
 * code.
 *
 * Minecraft 1.8.8 bytecode is (c) 2015 Mojang AB. "Do not distribute!" Mod
 * Coder Pack v9.18 deobfuscation configs are (c) Copyright by the MCP Team
 *
 * EaglercraftX 1.8 patch files (c) 2022-2025 lax1dude, ayunami2000. All Rights
 * Reserved.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */
public class CommandCompare extends CommandBase {

	/**
	 * + Return a list of options when the user types TAB
	 */
	@Override
	public List<String> addTabCompletionOptions(ICommandSender var1, String[] astring, BlockPos blockpos) {
		return astring.length > 0 && astring.length <= 3 ? func_175771_a(astring, 0, blockpos)
				: (astring.length > 3 && astring.length <= 6 ? func_175771_a(astring, 3, blockpos)
						: (astring.length > 6 && astring.length <= 9 ? func_175771_a(astring, 6, blockpos)
								: (astring.length == 10
										? getListOfStringsMatchingLastWord(astring, new String[] { "masked", "all" })
										: null)));
	}

	/**
	 * + Gets the name of the command
	 */
	@Override
	public String getCommandName() {
		return "testforblocks";
	}

	/**
	 * + Gets the usage string for the command.
	 */
	@Override
	public String getCommandUsage(ICommandSender var1) {
		return "commands.compare.usage";
	}

	/**
	 * + Return the required permission level for this command.
	 */
	@Override
	public int getRequiredPermissionLevel() {
		return 2;
	}

	/**
	 * + Callback when the command is invoked
	 */
	@Override
	public void processCommand(ICommandSender parICommandSender, String[] parArrayOfString) throws CommandException {
		if (parArrayOfString.length < 9) {
			throw new WrongUsageException("commands.compare.usage", new Object[0]);
		} else {
			parICommandSender.setCommandStat(CommandResultStats.Type.AFFECTED_BLOCKS, 0);
			BlockPos blockpos = parseBlockPos(parICommandSender, parArrayOfString, 0, false);
			BlockPos blockpos1 = parseBlockPos(parICommandSender, parArrayOfString, 3, false);
			BlockPos blockpos2 = parseBlockPos(parICommandSender, parArrayOfString, 6, false);
			StructureBoundingBox structureboundingbox = new StructureBoundingBox(blockpos, blockpos1);
			StructureBoundingBox structureboundingbox1 = new StructureBoundingBox(blockpos2,
					blockpos2.add(structureboundingbox.func_175896_b()));
			int i = structureboundingbox.getXSize() * structureboundingbox.getYSize() * structureboundingbox.getZSize();
			if (i > 524288) {
				throw new CommandException("commands.compare.tooManyBlocks",
						new Object[] { Integer.valueOf(i), Integer.valueOf(524288) });
			} else if (structureboundingbox.minY >= 0 && structureboundingbox.maxY < 256
					&& structureboundingbox1.minY >= 0 && structureboundingbox1.maxY < 256) {
				World world = parICommandSender.getEntityWorld();
				if (world.isAreaLoaded(structureboundingbox) && world.isAreaLoaded(structureboundingbox1)) {
					boolean flag = false;
					if (parArrayOfString.length > 9 && parArrayOfString[9].equals("masked")) {
						flag = true;
					}

					i = 0;
					BlockPos blockpos3 = new BlockPos(structureboundingbox1.minX - structureboundingbox.minX,
							structureboundingbox1.minY - structureboundingbox.minY,
							structureboundingbox1.minZ - structureboundingbox.minZ);
					BlockPos blockpos$mutableblockpos = new BlockPos();
					BlockPos blockpos$mutableblockpos1 = new BlockPos();

					for (int j = structureboundingbox.minZ; j <= structureboundingbox.maxZ; ++j) {
						for (int k = structureboundingbox.minY; k <= structureboundingbox.maxY; ++k) {
							for (int l = structureboundingbox.minX; l <= structureboundingbox.maxX; ++l) {
								blockpos$mutableblockpos.func_181079_c(l, k, j);
								blockpos$mutableblockpos1.func_181079_c(l + blockpos3.getX(), k + blockpos3.getY(),
										j + blockpos3.getZ());
								boolean flag1 = false;
								IBlockState iblockstate = world.getBlockState(blockpos$mutableblockpos);
								if (!flag || iblockstate.getBlock() != Blocks.air) {
									if (iblockstate == world.getBlockState(blockpos$mutableblockpos1)) {
										TileEntity tileentity = world.getTileEntity(blockpos$mutableblockpos);
										TileEntity tileentity1 = world.getTileEntity(blockpos$mutableblockpos1);
										if (tileentity != null && tileentity1 != null) {
											NBTTagCompound nbttagcompound = new NBTTagCompound();
											tileentity.writeToNBT(nbttagcompound);
											nbttagcompound.removeTag("x");
											nbttagcompound.removeTag("y");
											nbttagcompound.removeTag("z");
											NBTTagCompound nbttagcompound1 = new NBTTagCompound();
											tileentity1.writeToNBT(nbttagcompound1);
											nbttagcompound1.removeTag("x");
											nbttagcompound1.removeTag("y");
											nbttagcompound1.removeTag("z");
											if (!nbttagcompound.equals(nbttagcompound1)) {
												flag1 = true;
											}
										} else if (tileentity != null) {
											flag1 = true;
										}
									} else {
										flag1 = true;
									}

									++i;
									if (flag1) {
										throw new CommandException("commands.compare.failed", new Object[0]);
									}
								}
							}
						}
					}

					parICommandSender.setCommandStat(CommandResultStats.Type.AFFECTED_BLOCKS, i);
					notifyOperators(parICommandSender, this, "commands.compare.success",
							new Object[] { Integer.valueOf(i) });
				} else {
					throw new CommandException("commands.compare.outOfWorld", new Object[0]);
				}
			} else {
				throw new CommandException("commands.compare.outOfWorld", new Object[0]);
			}
		}
	}
}
