package electrosphere.entity.state;

import electrosphere.entity.state.movement.GroundMovementTree;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.AttackTree.AttackTreeState;
import electrosphere.entity.state.movement.GroundMovementTree.MovementTreeState;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.Actor;
import electrosphere.renderer.anim.Animation;
import java.util.concurrent.CopyOnWriteArrayList;
import org.joml.Vector3f;

public class IdleTree {
    
    public static enum IdleTreeState {
        IDLE,
        NOT_IDLE,
    }
    
    IdleTreeState state;
    
    Entity parent;
    
    CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList();
    
    int frameCurrent;
    
    int maxFrame = 60;
    
    public IdleTree(Entity e){
        state = IdleTreeState.IDLE;
        parent = e;
    }
    
    public IdleTreeState getState(){
        return state;
    }
    
    public void start(){
        //TODO: check if can start moving
        state = IdleTreeState.IDLE;
        frameCurrent = 0;
    }
    
    public void interrupt(){
        state = IdleTreeState.NOT_IDLE;
    }
    
    public void stop(){
        state = IdleTreeState.NOT_IDLE;
    }
    
    public void simulate(){
        Actor entityActor = EntityUtils.getActor(parent);
        
        boolean hasMovementTree = parent.getDataKeys().contains(EntityDataStrings.DATA_STRING_MOVEMENT_BT);
        GroundMovementTree movementTree = null;
        if(hasMovementTree){
            movementTree = CreatureUtils.getEntityMovementTree(parent);
        }
        
        boolean hasAttackTree = parent.getDataKeys().contains(EntityDataStrings.ATTACK_TREE);
        AttackTree attackTree = null;
        if(hasAttackTree){
            attackTree = CreatureUtils.getAttackTree(parent);
        }
        
        //parse attached network messages
        for(EntityMessage message : networkMessageQueue){
            networkMessageQueue.remove(message);
//            System.out.println("MOVE to " + message.getX() + " " + message.getY() + " " + message.getZ());
            switch(message.getMessageSubtype()){
                case ATTACKUPDATE:
                    switch(message.gettreeState()){
                     case 0:
                            state = IdleTreeState.IDLE;
                            break;
                        case 1:
                            state = IdleTreeState.NOT_IDLE;
                            break;
                    }
                    EntityUtils.getPosition(parent).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
                    CreatureUtils.setMovementVector(parent, new Vector3f(message.getrotationX(),message.getrotationY(),message.getrotationZ()));
                    break;
            }
        }
        
        boolean isIdle;
        
        //state machine
        switch(state){
            case IDLE:
                if(entityActor != null){
                    if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(Animation.ANIMATION_IDLE_1)){
                        entityActor.playAnimation(Animation.ANIMATION_IDLE_1);
                        entityActor.incrementAnimationTime(0.01);
                    }
                }
                isIdle = true;
                if(hasMovementTree){
                    if(movementTree.getState() != MovementTreeState.IDLE){
                        isIdle = false;
                    }
                }
                if(hasAttackTree){
                    if(attackTree.getState() != AttackTreeState.IDLE){
                        isIdle = false;
                    }
                }
                if(!isIdle){
                    state = IdleTreeState.NOT_IDLE;
                }
                break;
            case NOT_IDLE:
                isIdle = true;
                if(hasMovementTree){
                    if(movementTree.getState() != MovementTreeState.IDLE){
                        isIdle = false;
                    }
                }
                if(hasAttackTree){
                    if(attackTree.getState() != AttackTreeState.IDLE){
                        isIdle = false;
                    }
                }
                if(isIdle){
                    state = IdleTreeState.IDLE;
                }
                break;
        }
    }

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