package projectzombie.menu;

import gl_engine.matrix.Matrix4;
import gl_engine.vec.Vec2d;
import gl_engine.vec.Vec3d;
import projectzombie.Main;
import projectzombie.init.Models;
import projectzombie.input.CursorPosCallback;
import projectzombie.input.types.InputGUI;
import projectzombie.inventory.Inventory;
import projectzombie.inventory.InventoryArmor;
import projectzombie.inventory.InventoryClothing;
import projectzombie.items.ItemArmor;
import projectzombie.items.ItemClothing;
import projectzombie.menu.gui.GUI;
import projectzombie.menu.gui.GUIBackToMenu;
import projectzombie.menu.gui.GUIItemHolder;
import projectzombie.menu.gui.GUIItemSlot;
import projectzombie.menu.gui.GUIItemSlotGetter;
import projectzombie.menu.gui.GUIItemSlotGetterStorage;
import projectzombie.model.Model;
import projectzombie.model.ModelGui;
import projectzombie.util.ItemStack;

public abstract class MenuInventory extends Menu
{
	protected Menu parent;
	protected GUIItemHolder itemHolder;
	protected GUI gui;
	private GUI top_gui;
	
	protected GUIItemSlot[] item_slots;
	protected GUIItemSlot[] armor_slots;
	
	public MenuInventory(Menu parent)
	{
		this.parent = parent;
		
		doGameloop = parent.doGameloop;
		doGameRender = parent.doGameRender;
		showIngameGUI = parent.showIngameGUI;
		
		keepMouse = false;
		
		top_gui = new GUIBackToMenu(parent);
		input = new InputGUI(top_gui);
		gui = new GUI();
		
		Inventory inventory = Main.player.getInventory();
		
		itemHolder = new GUIItemHolder(top_gui);
		item_slots = new GUIItemSlot[42];
		armor_slots = new GUIItemSlot[6];
		
		{
			double offset = Models.UI_ITEM_SLOTS.getWidth() / 10;
			
			double inv_w = Models.UI_INVENTORY.getWidth();
			double inv_h = Models.UI_INVENTORY.getHeight();
			
			for(int i=0;i<10;i++)
			{
				GUIItemSlot slot = new GUIItemSlot(1, false, new GUIItemSlotGetterStorage(inventory, i));
				
				slot.setPos(new Vec2d((i - 5) * offset + 0.325, 0.65 / 2 - 9.5));
				
				gui.add(slot);
				item_slots[i] = slot;
			}
			
			for(int i=10;i<42;i++)
			{
				int row = (i - 10) / 4;
				int col = (i - 10) % 4;
				
				GUIItemSlot slot = new GUIItemSlot(1.5, true, new GUIItemSlotGetterStorage(inventory, i));
				
				slot.setPos(new Vec2d(col * offset - inv_w + 0.325, -row * offset + inv_h / 2 - 1.175));
				
				gui.add(slot);
				item_slots[i] = slot;
			}
			
			InventoryArmor armor = Main.player.getInventoryArmor();
			InventoryClothing clothing = Main.player.getInventoryClothing();
			
			double[] positions = new double[] {
					156, 76,
					156, 42,
					156, 8,
					196, 76,
					196, 42,
					196, 8,
			};
			
			ItemStack[] armor_item_slots = new ItemStack[] {
					armor.getHelmet(), armor.getChest(), armor.getLeggings(),
					clothing.getShirt(), clothing.getPants(), clothing.getBoots(),
			};
			
			for(int i=0;i<6;i++)
			{
				int[] id = {i};
				
				GUIItemSlot slot = new GUIItemSlot(1.5, true, new GUIItemSlotGetter() {
					
					@Override
					public void setItemStack(ItemStack stack) {
						armor_item_slots[id[0]] = stack;
					}
					
					@Override
					public boolean isAllowed(ItemStack stack)
					{
						if(id[0] < 3)
						{
							if(stack.item instanceof ItemArmor)
							{
								ItemArmor ia = (ItemArmor) stack.item;
								
								switch(id[0])
								{
								case 0: return ia.isHelmet(stack);
								case 1: return ia.isChestplate(stack);
								case 2: return ia.isLeggings(stack);
								}
							}
						}
						
						else
						{
							if(stack.item instanceof ItemClothing)
							{
								ItemClothing ic = (ItemClothing) stack.item;
								
								switch(id[0])
								{
								case 3: return ic.isShirt(stack);
								case 4: return ic.isPants(stack);
								case 5: return ic.isBoots(stack);
								}
							}
						}
						
						return false;
					}
					
					@Override
					public ItemStack getItemStack() {
						return armor_item_slots[id[0]];
					}
				});
				
				switch(i)
				{
				case 0:
					slot.setModelEmpty(Models.UI_SLOT_ARMOR_HELMET);
					break;
				case 1:
					slot.setModelEmpty(Models.UI_SLOT_ARMOR_CHEST);
					break;
				case 2:
					slot.setModelEmpty(Models.UI_SLOT_ARMOR_LEGS);
					break;
				case 3:
					slot.setModelEmpty(Models.UI_SLOT_CLOTHING_SHIRT);
					break;
				case 4:
					slot.setModelEmpty(Models.UI_SLOT_CLOTHING_PANTS);
					break;
				case 5:
					slot.setModelEmpty(Models.UI_SLOT_CLOTHING_BOOTS);
					break;
				}
				
				slot.setPos(new Vec2d(
						inv_w * (positions[i*2] / 256) - inv_w + 0.325,
						inv_h * (positions[i*2+1] / 256) - inv_h / 2 + 0.325));
				
				//slot.setItemStack(new ItemStack(Items.ACORN, 3, (short)0));
				
				armor_slots[i] = slot;
				gui.add(slot);
			}
		}
		
		top_gui.add(gui);
		top_gui.add(itemHolder);
	}

	@Override
	public void render()
	{
		parent.render();
		
		double width = Models.UI_INVENTORY.getWidth();
		double height = Models.UI_INVENTORY.getHeight();
		
		Matrix4 matrix = Matrix4.translate(-width, -height / 2, 0);
		
		// Render the inventory gui
		Models.UI_INVENTORY.setModel(matrix);
		Models.UI_INVENTORY.render();
		
		{
			// Render the player in the gui
			Model player_model = Main.player.MODEL.model_gui;
			
			double px = width * (160 / 256.0);
			double py = height * (128 / 256.0);
			
			Matrix4 player_matrix = Matrix4.multiply(matrix, Matrix4.translate(px, py, 0));
			
			player_matrix = Matrix4.multiply(Matrix4.scale(new Vec3d(3, 3, 3)), player_matrix);
			
			player_model.setModel(player_matrix);
			player_model.render();
		}
		
		/*// Get the angles between the player character and the mouse
		double ax = Math.toDegrees(MathHelpers.atan2(-CursorPosCallback.mx - px / 20, 3.2));
		double ay = Math.toDegrees(MathHelpers.atan2(-CursorPosCallback.my - py / 20, 3.2));
		
		player_matrix = Matrix4.multiply(Matrix4.scale(new Vec3d(6, 6, 6)), player_matrix);
		player_matrix = Matrix4.multiply(Matrix4.projection(1, 90, 1, 50), player_matrix);
		player_matrix = Matrix4.multiply(Matrix4.translate(0, 0, -2), player_matrix);
		player_matrix = Matrix4.multiply(Matrix4.rotate(ax, 0, 1, 0), player_matrix);
		player_matrix = Matrix4.multiply(Matrix4.rotate(ay, 1, 0, 0), player_matrix);
		player_matrix = Matrix4.multiply(Matrix4.translate(-width * (10.8 / 256.0), -height * (10.8 / 256.0), 0), player_matrix);*/
		
		top_gui.render();
	}
	
	@Override
	public void update() {
		super.update();
		
		top_gui.update(CursorPosCallback.getCursorPos());
	}

}
