package com.rs.game.player.actions;

import com.rs.Settings;
import com.rs.cache.loaders.ItemDefinitions;
import com.rs.game.Animation;
import com.rs.game.item.Item;
import com.rs.game.player.Player;
import com.rs.game.player.Skills;
import com.rs.game.player.actions.Fletching.Fletch;
import com.rs.game.player.actions.Fletching2.FletchData;

public class Fletching2 extends Action {

	private static final int LEVEL_OPCODE = 2645, BASE_OPCODE = 2655,
			PERMENANT_SECONDARY_OPCODE = 2650, REMOVEABLE_SECONDARY_OPCODE = 2656, EXPERIENCE_OPCODE = 2697,
			CREATION_COUNT_OPCODE = 2653;

	private static final int[] PRODUCTS = { 33665, 33667, 33668, 33669, 29611, 29614, 29736, 29734, 31868, 28645, 21640, 21823, 9179, 25478, 25917, 52, 50, 48, 9440, 841, 839, 54, 56, 9442, 843, 845, 60, 58, 9444, 849, 847, 64, 62, 9448, 853, 851, 68, 66, 9452, 857, 855, 72, 70, 861 ,859, 9454, 9457, 9456, 9459, 9461, 6493, 9465, 9174, 9177, 9465, 9176, 9181, 9183, 9185, 53, 882, 884, 886, 888, 890, 982, 11212, 877, 9140, 9141, 9142, 9143, 9144, 879, 9139, 9335, 880, 9145, 9336, 881, 9337, 9335, 9339, 9340, 9341, 9342, 806, 807, 808, 809, 810, 811, 11230, 772, 21353, 21364, 21365, 17747, 16427, 16432, 16437, 16442, 16447, 16452, 16457, 16462, 16467, 16472, 14867, 14869, 16871, 16873, 16875, 16877, 16879, 16881, 16883, 16885, 16317, 16319, 16321, 16323, 16327, 16329, 16331, 16333, 16335, 17702, 17722, 17742, 16977, 17756, 17704, 17724, 17742, 16979, 17758, 17706, 17726, 17742, 16981, 17760, 17708, 17728, 17742, 16983, 17762, 17710, 17730, 17742, 16985, 17764, 17712, 17732, 17742, 16987, 17766, 17714, 17734, 17742, 16989, 17768, 17716, 17736, 17742, 16991, 17770, 17718, 17738, 17742, 16993, 17772, 17720, 17740, 17742, 16995, 17774, 13280, 4160  };

	private final FletchData data;
	private int product, cycles, incrementPerCycle, level;
	private double experience;

	public Fletching2(FletchData data, int product, int cycles) {
		this.data = data;
		this.product = product;
		this.cycles = cycles;
		ItemDefinitions defs = ItemDefinitions.getItemDefinitions(product);
		this.incrementPerCycle = defs.getCSOpcode(CREATION_COUNT_OPCODE);
		this.level = defs.getCSOpcode(LEVEL_OPCODE);
		this.experience = defs.getCSOpcode(EXPERIENCE_OPCODE) / 10.0;
	}

	public boolean checkAll(Player player) {
		if (player.getSkills().getLevel(Skills.FLETCHING) < level)
			return false;
		else if (!player.getSlayerManager().hasLearnedBroad()) {
			if (product == 4160 || product == 13280) {
				player.getPackets().sendGameMessage("You lack the knowledge to create a broad accessory, perhaps a Slayer Master could assist you.");
				return false;
			}
		}
		return continueNextCycle(player);
	}

	@Override
	public boolean start(Player player) {
		if (!checkAll(player))
			return false;
		return true;
	}

	@Override
	public boolean process(Player player) {
		return continueNextCycle(player) && cycles > 0;
	}

	private boolean continueNextCycle(Player player) {
		return player.getInventory().containsItemToolBelt(data.getSecondary()) && player.getInventory().containsItem(data.getNode(), 1);
	}

	@Override
	public int processWithDelay(Player player) {
		cycles--;
		boolean isShaft = product == 52;
		if (incrementPerCycle > 0) {
			if (data.canDeleteSecondary()) {
				int nodeCount = player.getInventory().getAmountOf(data.getNode());
				int secondaryCount = player.getInventory().getAmountOf(data.getSecondary());
				if (!isShaft) {
					if (nodeCount < incrementPerCycle)
						incrementPerCycle = nodeCount;
					if (secondaryCount < incrementPerCycle)
						incrementPerCycle = secondaryCount;
				}
			}
		} else
			incrementPerCycle = 1;
		if (data.canDeleteSecondary())
			player.getInventory().deleteItem(data.getSecondary(), incrementPerCycle);
		player.getInventory().deleteItem(data.getNode(), isShaft ? 1 : incrementPerCycle);
		player.getSkills().addXp(Skills.FLETCHING, experience * incrementPerCycle);
		player.getInventory().addItem(product, incrementPerCycle * (incrementPerCycle != 1 ? Settings.getCraftRate() : incrementPerCycle));
		return 4;
	}

	@Override
	public void stop(Player player) {
		setActionDelay(player, 3);
	}

	public static FletchData isFletching(int material) {
		for (int product : PRODUCTS) {
			ItemDefinitions defs = ItemDefinitions.getItemDefinitions(product);
			int secondary = defs.getCSOpcode(PERMENANT_SECONDARY_OPCODE);
			if (secondary == 0)
				continue;
			int nodeId = defs.getCSOpcode(BASE_OPCODE);
			if (nodeId == material)
				return new FletchData(product, nodeId, secondary, secondary == 0);
		}
		return null;
	}

	public static FletchData isFletchingCombination(Item node, Item secondary) {
		for (int product : PRODUCTS) {
			ItemDefinitions defs = ItemDefinitions.getItemDefinitions(product);
			int nodeId = defs.getCSOpcode(BASE_OPCODE);
			int fixedSecondaryId = defs.getCSOpcode(PERMENANT_SECONDARY_OPCODE);
			int removeableSecondaryId = defs.getCSOpcode(REMOVEABLE_SECONDARY_OPCODE);
			if (fixedSecondaryId == 0 && removeableSecondaryId == 0)
				removeableSecondaryId = 314;//Feather isn't in cache idk why
			if (node.getId() == nodeId && (secondary.getId() == fixedSecondaryId || secondary.getId() == removeableSecondaryId))
				return new FletchData(product, nodeId, secondary.getId(), fixedSecondaryId == 0);
			else if ((node.getId() == fixedSecondaryId || node.getId() == removeableSecondaryId) && secondary.getId() == nodeId)
				return new FletchData(product, secondary.getId(), nodeId, fixedSecondaryId == 0);
		}
		return null;
	}

	public static class FletchData {
		private int product;
		private final int node;
		private final int secondary;
		private final boolean deleteSecondary;

		public FletchData(int product, int node, int secondary, boolean deleteSecondary) {
			System.out.println(product);
			this.product = product;
			this.node = node;
			this.secondary = secondary;
			this.deleteSecondary = deleteSecondary;
		}

		public int getProduct() {
			return product;
		}

		public int getNode() {
			return node;
		}

		public int getSecondary() {
			return secondary;
		}

		public boolean canDeleteSecondary() {
			return deleteSecondary;
		}
	}
}
