package electrosphere.entity.state.inventory;

import java.util.LinkedList;
import java.util.List;

import electrosphere.entity.Entity;
import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.equip.ServerEquipState;
import electrosphere.entity.state.equip.ServerToolbarState;
import electrosphere.game.data.creature.type.equip.EquipPoint;
import electrosphere.net.parser.net.message.InventoryMessage;
import electrosphere.server.datacell.utils.EntityLookupUtils;
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;

/**
 * Principally used to handle network messages related to inventory and thread synchronization
 */
public class ServerInventoryState implements BehaviorTree {

    /**
     * The queue of messages to handle
     */
    List<InventoryMessage> networkMessageQueue = new LinkedList<InventoryMessage>();

    /**
     * The parent of the state
     */
    Entity parent;

    /**
     * Constructor
     */
    ServerInventoryState() {}

    /**
     * Creates an inventory state
     * @param parent The parent entity
     * @return The inventory state
     */
    public static ServerInventoryState serverCreateInventoryState(Entity parent){
        ServerInventoryState rVal = new ServerInventoryState();
        rVal.parent = parent;
        ServerBehaviorTreeUtils.attachBTreeToEntity(parent, rVal);
        return rVal;
    }

    @Override
    public void simulate(float deltaTime) {
        for(InventoryMessage message : networkMessageQueue){
            networkMessageQueue.remove(message);
            switch(message.getMessageSubtype()){
                case ADDITEMTOINVENTORY: {
                    InventoryUtils.serverAttemptStoreItemTransform(parent, EntityLookupUtils.getEntityById(message.getentityId()));
                } break;
                case REMOVEITEMFROMINVENTORY: {
                    InventoryUtils.serverAttemptEjectItem(parent, EntityLookupUtils.getEntityById(message.getentityId()));
                } break;
                case CLIENTREQUESTEQUIPITEM: {
                    //item to equip
                    Entity target = EntityLookupUtils.getEntityById(message.getentityId());
                    //perform transform if it makes sense
                    if(InventoryUtils.hasEquipInventory(parent) && InventoryUtils.hasNaturalInventory(parent) && ServerEquipState.hasEquipState(parent)){
                        ServerEquipState equipState = ServerEquipState.getEquipState(parent);
                        EquipPoint point = equipState.getEquipPoint(message.getequipPointId());
                        equipState.commandAttemptEquip(target, point);
                    }
                }
                break;
                case CLIENTREQUESTUNEQUIPITEM: {
                    //make sure can unequip
                    if(InventoryUtils.hasEquipInventory(parent) && InventoryUtils.hasNaturalInventory(parent) && ServerEquipState.hasEquipState(parent)){
                        ServerEquipState equipState = ServerEquipState.getEquipState(parent);
                        // EquipPoint point = equipState.getEquipPoint(message.getequipPointId());
                        if(equipState.hasEquippedAtPoint(message.getequipPointId())){
                            equipState.commandAttemptUnequip(message.getequipPointId());
                            //tell player
                        }
                    }
                } break;
                case CLIENTREQUESTADDNATURAL: {
                    InventoryUtils.serverAddToNatural(parent, EntityLookupUtils.getEntityById(message.getentityId()));
                } break;
                case CLIENTREQUESTADDTOOLBAR: {
                    Entity itemEnt = EntityLookupUtils.getEntityById(message.getentityId());
                    ServerToolbarState serverToolbarState = ServerToolbarState.getServerToolbarState(parent);
                    serverToolbarState.attemptEquip(itemEnt, message.gettoolbarId());
                } break;
                case CLIENTUPDATETOOLBAR: {
                    ServerToolbarState serverToolbarState = ServerToolbarState.getServerToolbarState(parent);
                    serverToolbarState.attemptChangeSelection(message.gettoolbarId());
                } break;
                case CLIENTREQUESTCRAFT:
                case CLIENTREQUESTPERFORMITEMACTION:
                case SERVERCOMMANDUNEQUIPITEM:
                case SERVERCOMMANDEQUIPITEM:
                case SERVERCOMMANDMOVEITEMCONTAINER:
                break;
            }
        }
    }

    /**
     * Add a network message to be handled on the server
     * @param networkMessage The message
     */
    public void addNetworkMessage(InventoryMessage networkMessage) {
        networkMessageQueue.add(networkMessage);
    }
    
}
