package electrosphere.net.server;

import electrosphere.entity.Entity;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.game.server.terrain.manager.ServerTerrainChunk;
import electrosphere.game.server.terrain.models.TerrainModification;
import electrosphere.main.Globals;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.net.parser.net.message.NetworkMessage;
import electrosphere.net.parser.net.message.WorldMessage;

public class ServerProtocol {
    
    ServerConnectionHandler connectionHandler;
    
    public ServerProtocol(ServerConnectionHandler connectionHandler){
        this.connectionHandler = connectionHandler;
    }
    
    void handleMessage(NetworkMessage message){
        switch(message.getType()){
            case ENTITY_MESSAGE:
                handleEntityMessage((EntityMessage)message);
                break;
            case WORLD_MESSAGE:
                handleWorldMessage((WorldMessage)message);
                break;
        }
    }
    
    void handleEntityMessage(EntityMessage message){
        Entity targetEntity;
        switch(message.getMessageSubtype()){
            case CREATE:
                break;
            case DESTROY:
                break;
            case MOVE:
                targetEntity = Globals.entityManager.getEntityFromId(message.getentityID());
                if(targetEntity != null){
                    CreatureUtils.attachEntityMessageToMovementTree(targetEntity,message);
                }
                break;
            case SETBEHAVIORTREE:
                break;
            case MOVEUPDATE:
                targetEntity = Globals.entityManager.getEntityFromId(message.getentityID());
                if(targetEntity != null){
                    CreatureUtils.attachEntityMessageToMovementTree(targetEntity,message);
                }
                break;
            case ATTACKUPDATE:
                targetEntity = Globals.entityManager.getEntityFromId(message.getentityID());
                if(targetEntity != null){
                    CreatureUtils.attachEntityMessageToAttackTree(targetEntity,message);
                }
                break;
        }
    }
    
    void handleWorldMessage(WorldMessage message){
        switch(message.getMessageSubtype()){
            case REQUESTCHUNK:
                /*
                int locationX,
                int locationY,
                float macroValue00,
                float macroValue01,
                float macroValue02,
                float macroValue10,
                float macroValue11,
                float macroValue12,
                float macroValue20,
                float macroValue21,
                float macroValue22,
                long randomizerValue00,
                long randomizerValue01,
                long randomizerValue02,
                long randomizerValue10,
                long randomizerValue11,
                long randomizerValue12,
                long randomizerValue20,
                long randomizerValue21,
                long randomizerValue22
                */
                
//                System.out.println("Received request for chunk " + message.getworldX() + " " + message.getworldY());
                
                ServerTerrainChunk chunk = Globals.serverTerrainManager.getChunk(message.getworldX(), message.getworldY());
                
                float[][] macroValues = chunk.getMacroValues();//Globals.serverTerrainManager.getRad5MacroValues(message.getworldX(), message.getworldY());
                
                long[][] randomizer = chunk.getRandomizer();//Globals.serverTerrainManager.getRandomizer(message.getworldX(), message.getworldY());
                
                int numMessages = 2 + chunk.getModifications().size();
                
                connectionHandler.addMessagetoOutgoingQueue(
                        WorldMessage.constructchunkLoadStartMessage(message.getworldX(), message.getworldY(), numMessages)
                );
                
                connectionHandler.addMessagetoOutgoingQueue(
                        WorldMessage.constructMacroValueMessage(
                                message.getworldX(),
                                message.getworldY(),
                                
                                
                                macroValues[0][0],
                                macroValues[0][1],
                                macroValues[0][2],
                                macroValues[0][3],
                                macroValues[0][4],
                                macroValues[1][0],
                                macroValues[1][1],
                                macroValues[1][2],
                                macroValues[1][3],
                                macroValues[1][4],
                                macroValues[2][0],
                                macroValues[2][1],
                                macroValues[2][2],
                                macroValues[2][3],
                                macroValues[2][4],
                                macroValues[3][0],
                                macroValues[3][1],
                                macroValues[3][2],
                                macroValues[3][3],
                                macroValues[3][4],
                                macroValues[4][0],
                                macroValues[4][1],
                                macroValues[4][2],
                                macroValues[4][3],
                                macroValues[4][4],
                                
                                
                                randomizer[0][0],
                                randomizer[0][1],
                                randomizer[0][2],
                                randomizer[0][3],
                                randomizer[0][4],
                                randomizer[1][0],
                                randomizer[1][1],
                                randomizer[1][2],
                                randomizer[1][3],
                                randomizer[1][4],
                                randomizer[2][0],
                                randomizer[2][1],
                                randomizer[2][2],
                                randomizer[2][3],
                                randomizer[2][4],
                                randomizer[3][0],
                                randomizer[3][1],
                                randomizer[3][2],
                                randomizer[3][3],
                                randomizer[3][4],
                                randomizer[4][0],
                                randomizer[4][1],
                                randomizer[4][2],
                                randomizer[4][3],
                                randomizer[4][4]
                                )
                );
                
                for(TerrainModification modification : chunk.getModifications()){
                    connectionHandler.addMessagetoOutgoingQueue(
                            WorldMessage.constructheightMapModificationMessage(
                                    modification.getValue(),
                                    modification.getWorldX(),
                                    modification.getWorldY(),
                                    modification.getLocationX(),
                                    modification.getLocationY()
                            )
                    );
                }
                break;
        }
    }
    
}
