package electrosphere.net.parser.net.message;

import electrosphere.net.parser.util.ByteStreamUtils;
import electrosphere.net.parser.net.raw.CircularByteBuffer;
import java.util.LinkedList;
import java.util.List;

public class PlayerMessage extends NetworkMessage {

    public enum PlayerMessageType {
        SET_ID,
        SETINITIALDISCRETEPOSITION,
    }

    PlayerMessageType messageType;
    int playerID;
    int initialDiscretePositionX;
    int initialDiscretePositionY;
    int initialDiscretePositionZ;

    PlayerMessage(PlayerMessageType messageType){
        this.type = MessageType.PLAYER_MESSAGE;
        this.messageType = messageType;
    }

    public PlayerMessageType getMessageSubtype(){
        return this.messageType;
    }

    public int getplayerID() {
        return playerID;
    }

    public void setplayerID(int playerID) {
        this.playerID = playerID;
    }

    public int getinitialDiscretePositionX() {
        return initialDiscretePositionX;
    }

    public void setinitialDiscretePositionX(int initialDiscretePositionX) {
        this.initialDiscretePositionX = initialDiscretePositionX;
    }

    public int getinitialDiscretePositionY() {
        return initialDiscretePositionY;
    }

    public void setinitialDiscretePositionY(int initialDiscretePositionY) {
        this.initialDiscretePositionY = initialDiscretePositionY;
    }

    public int getinitialDiscretePositionZ() {
        return initialDiscretePositionZ;
    }

    public void setinitialDiscretePositionZ(int initialDiscretePositionZ) {
        this.initialDiscretePositionZ = initialDiscretePositionZ;
    }

    static void stripPacketHeader(CircularByteBuffer byteBuffer){
        byteBuffer.read(2);
    }

    public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){
        switch(secondByte){
            case TypeBytes.PLAYER_MESSAGE_TYPE_SET_ID:
                if(byteBuffer.getRemaining() >= TypeBytes.PLAYER_MESSAGE_TYPE_SET_ID_SIZE){
                    return true;
                } else {
                    return false;
                }
            case TypeBytes.PLAYER_MESSAGE_TYPE_SETINITIALDISCRETEPOSITION:
                if(byteBuffer.getRemaining() >= TypeBytes.PLAYER_MESSAGE_TYPE_SETINITIALDISCRETEPOSITION_SIZE){
                    return true;
                } else {
                    return false;
                }
        }
        return false;
    }

    public static PlayerMessage parseSet_IDMessage(CircularByteBuffer byteBuffer){
        PlayerMessage rVal = new PlayerMessage(PlayerMessageType.SET_ID);
        stripPacketHeader(byteBuffer);
        rVal.setplayerID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        return rVal;
    }

    public static PlayerMessage constructSet_IDMessage(int playerID){
        PlayerMessage rVal = new PlayerMessage(PlayerMessageType.SET_ID);
        rVal.setplayerID(playerID);
        rVal.serialize();
        return rVal;
    }

    public static PlayerMessage parseSetInitialDiscretePositionMessage(CircularByteBuffer byteBuffer){
        PlayerMessage rVal = new PlayerMessage(PlayerMessageType.SETINITIALDISCRETEPOSITION);
        stripPacketHeader(byteBuffer);
        rVal.setinitialDiscretePositionX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setinitialDiscretePositionY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setinitialDiscretePositionZ(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        return rVal;
    }

    public static PlayerMessage constructSetInitialDiscretePositionMessage(int initialDiscretePositionX,int initialDiscretePositionY,int initialDiscretePositionZ){
        PlayerMessage rVal = new PlayerMessage(PlayerMessageType.SETINITIALDISCRETEPOSITION);
        rVal.setinitialDiscretePositionX(initialDiscretePositionX);
        rVal.setinitialDiscretePositionY(initialDiscretePositionY);
        rVal.setinitialDiscretePositionZ(initialDiscretePositionZ);
        rVal.serialize();
        return rVal;
    }

    @Override
    void serialize(){
        byte[] intValues = new byte[8];
        byte[] stringBytes;
        switch(this.messageType){
            case SET_ID:
                rawBytes = new byte[2+4];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_PLAYER;
                //entity messaage header
                rawBytes[1] = TypeBytes.PLAYER_MESSAGE_TYPE_SET_ID;
                intValues = ByteStreamUtils.serializeIntToBytes(playerID);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                break;
            case SETINITIALDISCRETEPOSITION:
                rawBytes = new byte[2+4+4+4];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_PLAYER;
                //entity messaage header
                rawBytes[1] = TypeBytes.PLAYER_MESSAGE_TYPE_SETINITIALDISCRETEPOSITION;
                intValues = ByteStreamUtils.serializeIntToBytes(initialDiscretePositionX);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(initialDiscretePositionY);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(initialDiscretePositionZ);
                for(int i = 0; i < 4; i++){
                    rawBytes[10+i] = intValues[i];
                }
                break;
        }
        serialized = true;
    }

}
