package electrosphere.entity.state.inventory;

import java.util.concurrent.CopyOnWriteArrayList;

import electrosphere.entity.Entity;
import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.equip.ServerEquipState;
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 {

    CopyOnWriteArrayList<InventoryMessage> networkMessageQueue = new CopyOnWriteArrayList<InventoryMessage>();

    Entity parent;

    ServerInventoryState() {

    }

    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.serverAttemptStoreItem(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 SERVERCOMMANDUNEQUIPITEM:
                case SERVERCOMMANDEQUIPITEM:
                case SERVERCOMMANDMOVEITEMCONTAINER:
                break;
            }
        }
    }

    public void addNetworkMessage(InventoryMessage networkMessage) {
        networkMessageQueue.add(networkMessage);
    }
    
}
