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 SynchronizationMessage extends NetworkMessage {

    public enum SynchronizationMessageType {
        UPDATECLIENTSTATE,
        UPDATECLIENTSTRINGSTATE,
        UPDATECLIENTINTSTATE,
        UPDATECLIENTLONGSTATE,
        UPDATECLIENTFLOATSTATE,
        UPDATECLIENTDOUBLESTATE,
        CLIENTREQUESTBTREEACTION,
        SERVERNOTIFYBTREETRANSITION,
        ATTACHTREE,
        DETATCHTREE,
        LOADSCENE,
    }

    SynchronizationMessageType messageType;
    int entityId;
    int bTreeId;
    int fieldId;
    int bTreeValue;
    String stringValue;
    int intValue;
    long longValue;
    float floatValue;
    double doubleValue;

    SynchronizationMessage(SynchronizationMessageType messageType){
        this.type = MessageType.SYNCHRONIZATION_MESSAGE;
        this.messageType = messageType;
    }

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

    public int getentityId() {
        return entityId;
    }

    public void setentityId(int entityId) {
        this.entityId = entityId;
    }

    public int getbTreeId() {
        return bTreeId;
    }

    public void setbTreeId(int bTreeId) {
        this.bTreeId = bTreeId;
    }

    public int getfieldId() {
        return fieldId;
    }

    public void setfieldId(int fieldId) {
        this.fieldId = fieldId;
    }

    public int getbTreeValue() {
        return bTreeValue;
    }

    public void setbTreeValue(int bTreeValue) {
        this.bTreeValue = bTreeValue;
    }

    public String getstringValue() {
        return stringValue;
    }

    public void setstringValue(String stringValue) {
        this.stringValue = stringValue;
    }

    public int getintValue() {
        return intValue;
    }

    public void setintValue(int intValue) {
        this.intValue = intValue;
    }

    public long getlongValue() {
        return longValue;
    }

    public void setlongValue(long longValue) {
        this.longValue = longValue;
    }

    public float getfloatValue() {
        return floatValue;
    }

    public void setfloatValue(float floatValue) {
        this.floatValue = floatValue;
    }

    public double getdoubleValue() {
        return doubleValue;
    }

    public void setdoubleValue(double doubleValue) {
        this.doubleValue = doubleValue;
    }

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

    public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){
        switch(secondByte){
            case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTSTATE:
                if(byteBuffer.getRemaining() >= TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTSTATE_SIZE){
                    return true;
                } else {
                    return false;
                }
            case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTSTRINGSTATE:
                return SynchronizationMessage.canParseUpdateClientStringStateMessage(byteBuffer);
            case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTINTSTATE:
                if(byteBuffer.getRemaining() >= TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTINTSTATE_SIZE){
                    return true;
                } else {
                    return false;
                }
            case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTLONGSTATE:
                if(byteBuffer.getRemaining() >= TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTLONGSTATE_SIZE){
                    return true;
                } else {
                    return false;
                }
            case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTFLOATSTATE:
                if(byteBuffer.getRemaining() >= TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTFLOATSTATE_SIZE){
                    return true;
                } else {
                    return false;
                }
            case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTDOUBLESTATE:
                if(byteBuffer.getRemaining() >= TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTDOUBLESTATE_SIZE){
                    return true;
                } else {
                    return false;
                }
            case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_CLIENTREQUESTBTREEACTION:
                if(byteBuffer.getRemaining() >= TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_CLIENTREQUESTBTREEACTION_SIZE){
                    return true;
                } else {
                    return false;
                }
            case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_SERVERNOTIFYBTREETRANSITION:
                if(byteBuffer.getRemaining() >= TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_SERVERNOTIFYBTREETRANSITION_SIZE){
                    return true;
                } else {
                    return false;
                }
            case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_ATTACHTREE:
                if(byteBuffer.getRemaining() >= TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_ATTACHTREE_SIZE){
                    return true;
                } else {
                    return false;
                }
            case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_DETATCHTREE:
                if(byteBuffer.getRemaining() >= TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_DETATCHTREE_SIZE){
                    return true;
                } else {
                    return false;
                }
            case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_LOADSCENE:
                return SynchronizationMessage.canParseLoadSceneMessage(byteBuffer);
        }
        return false;
    }

    public static SynchronizationMessage parseUpdateClientStateMessage(CircularByteBuffer byteBuffer){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.UPDATECLIENTSTATE);
        stripPacketHeader(byteBuffer);
        rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setbTreeId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setfieldId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setbTreeValue(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        return rVal;
    }

    public static SynchronizationMessage constructUpdateClientStateMessage(int entityId,int bTreeId,int fieldId,int bTreeValue){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.UPDATECLIENTSTATE);
        rVal.setentityId(entityId);
        rVal.setbTreeId(bTreeId);
        rVal.setfieldId(fieldId);
        rVal.setbTreeValue(bTreeValue);
        rVal.serialize();
        return rVal;
    }

    public static boolean canParseUpdateClientStringStateMessage(CircularByteBuffer byteBuffer){
        int currentStreamLength = byteBuffer.getRemaining();
        List<Byte> temporaryByteQueue = new LinkedList<Byte>();
        if(currentStreamLength < 6){
            return false;
        }
        if(currentStreamLength < 10){
            return false;
        }
        if(currentStreamLength < 14){
            return false;
        }
        int stringValueSize = 0;
        if(currentStreamLength < 18){
            return false;
        } else {
            temporaryByteQueue.add(byteBuffer.peek(14 + 0));
            temporaryByteQueue.add(byteBuffer.peek(14 + 1));
            temporaryByteQueue.add(byteBuffer.peek(14 + 2));
            temporaryByteQueue.add(byteBuffer.peek(14 + 3));
            stringValueSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
        }
        if(currentStreamLength < 18 + stringValueSize){
            return false;
        }
        return true;
    }

    public static SynchronizationMessage parseUpdateClientStringStateMessage(CircularByteBuffer byteBuffer){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.UPDATECLIENTSTRINGSTATE);
        stripPacketHeader(byteBuffer);
        rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setbTreeId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setfieldId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setstringValue(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
        return rVal;
    }

    public static SynchronizationMessage constructUpdateClientStringStateMessage(int entityId,int bTreeId,int fieldId,String stringValue){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.UPDATECLIENTSTRINGSTATE);
        rVal.setentityId(entityId);
        rVal.setbTreeId(bTreeId);
        rVal.setfieldId(fieldId);
        rVal.setstringValue(stringValue);
        rVal.serialize();
        return rVal;
    }

    public static SynchronizationMessage parseUpdateClientIntStateMessage(CircularByteBuffer byteBuffer){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.UPDATECLIENTINTSTATE);
        stripPacketHeader(byteBuffer);
        rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setbTreeId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setfieldId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setintValue(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        return rVal;
    }

    public static SynchronizationMessage constructUpdateClientIntStateMessage(int entityId,int bTreeId,int fieldId,int intValue){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.UPDATECLIENTINTSTATE);
        rVal.setentityId(entityId);
        rVal.setbTreeId(bTreeId);
        rVal.setfieldId(fieldId);
        rVal.setintValue(intValue);
        rVal.serialize();
        return rVal;
    }

    public static SynchronizationMessage parseUpdateClientLongStateMessage(CircularByteBuffer byteBuffer){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.UPDATECLIENTLONGSTATE);
        stripPacketHeader(byteBuffer);
        rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setbTreeId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setfieldId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setlongValue(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
        return rVal;
    }

    public static SynchronizationMessage constructUpdateClientLongStateMessage(int entityId,int bTreeId,int fieldId,long longValue){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.UPDATECLIENTLONGSTATE);
        rVal.setentityId(entityId);
        rVal.setbTreeId(bTreeId);
        rVal.setfieldId(fieldId);
        rVal.setlongValue(longValue);
        rVal.serialize();
        return rVal;
    }

    public static SynchronizationMessage parseUpdateClientFloatStateMessage(CircularByteBuffer byteBuffer){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.UPDATECLIENTFLOATSTATE);
        stripPacketHeader(byteBuffer);
        rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setbTreeId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setfieldId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setfloatValue(ByteStreamUtils.popFloatFromByteQueue(byteBuffer));
        return rVal;
    }

    public static SynchronizationMessage constructUpdateClientFloatStateMessage(int entityId,int bTreeId,int fieldId,float floatValue){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.UPDATECLIENTFLOATSTATE);
        rVal.setentityId(entityId);
        rVal.setbTreeId(bTreeId);
        rVal.setfieldId(fieldId);
        rVal.setfloatValue(floatValue);
        rVal.serialize();
        return rVal;
    }

    public static SynchronizationMessage parseUpdateClientDoubleStateMessage(CircularByteBuffer byteBuffer){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.UPDATECLIENTDOUBLESTATE);
        stripPacketHeader(byteBuffer);
        rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setbTreeId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setfieldId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setdoubleValue(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
        return rVal;
    }

    public static SynchronizationMessage constructUpdateClientDoubleStateMessage(int entityId,int bTreeId,int fieldId,double doubleValue){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.UPDATECLIENTDOUBLESTATE);
        rVal.setentityId(entityId);
        rVal.setbTreeId(bTreeId);
        rVal.setfieldId(fieldId);
        rVal.setdoubleValue(doubleValue);
        rVal.serialize();
        return rVal;
    }

    public static SynchronizationMessage parseClientRequestBTreeActionMessage(CircularByteBuffer byteBuffer){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.CLIENTREQUESTBTREEACTION);
        stripPacketHeader(byteBuffer);
        rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setbTreeId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setbTreeValue(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        return rVal;
    }

    public static SynchronizationMessage constructClientRequestBTreeActionMessage(int entityId,int bTreeId,int bTreeValue){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.CLIENTREQUESTBTREEACTION);
        rVal.setentityId(entityId);
        rVal.setbTreeId(bTreeId);
        rVal.setbTreeValue(bTreeValue);
        rVal.serialize();
        return rVal;
    }

    public static SynchronizationMessage parseServerNotifyBTreeTransitionMessage(CircularByteBuffer byteBuffer){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.SERVERNOTIFYBTREETRANSITION);
        stripPacketHeader(byteBuffer);
        rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setbTreeId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setfieldId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setbTreeValue(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        return rVal;
    }

    public static SynchronizationMessage constructServerNotifyBTreeTransitionMessage(int entityId,int bTreeId,int fieldId,int bTreeValue){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.SERVERNOTIFYBTREETRANSITION);
        rVal.setentityId(entityId);
        rVal.setbTreeId(bTreeId);
        rVal.setfieldId(fieldId);
        rVal.setbTreeValue(bTreeValue);
        rVal.serialize();
        return rVal;
    }

    public static SynchronizationMessage parseAttachTreeMessage(CircularByteBuffer byteBuffer){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.ATTACHTREE);
        stripPacketHeader(byteBuffer);
        rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setbTreeId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        return rVal;
    }

    public static SynchronizationMessage constructAttachTreeMessage(int entityId,int bTreeId){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.ATTACHTREE);
        rVal.setentityId(entityId);
        rVal.setbTreeId(bTreeId);
        rVal.serialize();
        return rVal;
    }

    public static SynchronizationMessage parseDetatchTreeMessage(CircularByteBuffer byteBuffer){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.DETATCHTREE);
        stripPacketHeader(byteBuffer);
        rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        rVal.setbTreeId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
        return rVal;
    }

    public static SynchronizationMessage constructDetatchTreeMessage(int entityId,int bTreeId){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.DETATCHTREE);
        rVal.setentityId(entityId);
        rVal.setbTreeId(bTreeId);
        rVal.serialize();
        return rVal;
    }

    public static boolean canParseLoadSceneMessage(CircularByteBuffer byteBuffer){
        int currentStreamLength = byteBuffer.getRemaining();
        List<Byte> temporaryByteQueue = new LinkedList<Byte>();
        int stringValueSize = 0;
        if(currentStreamLength < 6){
            return false;
        } else {
            temporaryByteQueue.add(byteBuffer.peek(2 + 0));
            temporaryByteQueue.add(byteBuffer.peek(2 + 1));
            temporaryByteQueue.add(byteBuffer.peek(2 + 2));
            temporaryByteQueue.add(byteBuffer.peek(2 + 3));
            stringValueSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
        }
        if(currentStreamLength < 6 + stringValueSize){
            return false;
        }
        return true;
    }

    public static SynchronizationMessage parseLoadSceneMessage(CircularByteBuffer byteBuffer){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.LOADSCENE);
        stripPacketHeader(byteBuffer);
        rVal.setstringValue(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
        return rVal;
    }

    public static SynchronizationMessage constructLoadSceneMessage(String stringValue){
        SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.LOADSCENE);
        rVal.setstringValue(stringValue);
        rVal.serialize();
        return rVal;
    }

    @Override
    void serialize(){
        byte[] intValues = new byte[8];
        byte[] stringBytes;
        switch(this.messageType){
            case UPDATECLIENTSTATE:
                rawBytes = new byte[2+4+4+4+4];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION;
                //entity messaage header
                rawBytes[1] = TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTSTATE;
                intValues = ByteStreamUtils.serializeIntToBytes(entityId);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(bTreeId);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(fieldId);
                for(int i = 0; i < 4; i++){
                    rawBytes[10+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(bTreeValue);
                for(int i = 0; i < 4; i++){
                    rawBytes[14+i] = intValues[i];
                }
                break;
            case UPDATECLIENTSTRINGSTATE:
                rawBytes = new byte[2+4+4+4+4+stringValue.length()];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION;
                //entity messaage header
                rawBytes[1] = TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTSTRINGSTATE;
                intValues = ByteStreamUtils.serializeIntToBytes(entityId);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(bTreeId);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(fieldId);
                for(int i = 0; i < 4; i++){
                    rawBytes[10+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(stringValue.length());
                for(int i = 0; i < 4; i++){
                    rawBytes[14+i] = intValues[i];
                }
                stringBytes = stringValue.getBytes();
                for(int i = 0; i < stringValue.length(); i++){
                    rawBytes[18+i] = stringBytes[i];
                }
                break;
            case UPDATECLIENTINTSTATE:
                rawBytes = new byte[2+4+4+4+4];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION;
                //entity messaage header
                rawBytes[1] = TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTINTSTATE;
                intValues = ByteStreamUtils.serializeIntToBytes(entityId);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(bTreeId);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(fieldId);
                for(int i = 0; i < 4; i++){
                    rawBytes[10+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(intValue);
                for(int i = 0; i < 4; i++){
                    rawBytes[14+i] = intValues[i];
                }
                break;
            case UPDATECLIENTLONGSTATE:
                rawBytes = new byte[2+4+4+4+8];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION;
                //entity messaage header
                rawBytes[1] = TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTLONGSTATE;
                intValues = ByteStreamUtils.serializeIntToBytes(entityId);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(bTreeId);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(fieldId);
                for(int i = 0; i < 4; i++){
                    rawBytes[10+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(longValue);
                for(int i = 0; i < 8; i++){
                    rawBytes[14+i] = intValues[i];
                }
                break;
            case UPDATECLIENTFLOATSTATE:
                rawBytes = new byte[2+4+4+4+4];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION;
                //entity messaage header
                rawBytes[1] = TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTFLOATSTATE;
                intValues = ByteStreamUtils.serializeIntToBytes(entityId);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(bTreeId);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(fieldId);
                for(int i = 0; i < 4; i++){
                    rawBytes[10+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeFloatToBytes(floatValue);
                for(int i = 0; i < 4; i++){
                    rawBytes[14+i] = intValues[i];
                }                break;
            case UPDATECLIENTDOUBLESTATE:
                rawBytes = new byte[2+4+4+4+8];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION;
                //entity messaage header
                rawBytes[1] = TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTDOUBLESTATE;
                intValues = ByteStreamUtils.serializeIntToBytes(entityId);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(bTreeId);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(fieldId);
                for(int i = 0; i < 4; i++){
                    rawBytes[10+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeDoubleToBytes(doubleValue);
                for(int i = 0; i < 8; i++){
                    rawBytes[14+i] = intValues[i];
                }
                break;
            case CLIENTREQUESTBTREEACTION:
                rawBytes = new byte[2+4+4+4];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION;
                //entity messaage header
                rawBytes[1] = TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_CLIENTREQUESTBTREEACTION;
                intValues = ByteStreamUtils.serializeIntToBytes(entityId);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(bTreeId);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(bTreeValue);
                for(int i = 0; i < 4; i++){
                    rawBytes[10+i] = intValues[i];
                }
                break;
            case SERVERNOTIFYBTREETRANSITION:
                rawBytes = new byte[2+4+4+4+4];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION;
                //entity messaage header
                rawBytes[1] = TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_SERVERNOTIFYBTREETRANSITION;
                intValues = ByteStreamUtils.serializeIntToBytes(entityId);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(bTreeId);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(fieldId);
                for(int i = 0; i < 4; i++){
                    rawBytes[10+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(bTreeValue);
                for(int i = 0; i < 4; i++){
                    rawBytes[14+i] = intValues[i];
                }
                break;
            case ATTACHTREE:
                rawBytes = new byte[2+4+4];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION;
                //entity messaage header
                rawBytes[1] = TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_ATTACHTREE;
                intValues = ByteStreamUtils.serializeIntToBytes(entityId);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(bTreeId);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }
                break;
            case DETATCHTREE:
                rawBytes = new byte[2+4+4];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION;
                //entity messaage header
                rawBytes[1] = TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_DETATCHTREE;
                intValues = ByteStreamUtils.serializeIntToBytes(entityId);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(bTreeId);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }
                break;
            case LOADSCENE:
                rawBytes = new byte[2+4+stringValue.length()];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION;
                //entity messaage header
                rawBytes[1] = TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_LOADSCENE;
                intValues = ByteStreamUtils.serializeIntToBytes(stringValue.length());
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                stringBytes = stringValue.getBytes();
                for(int i = 0; i < stringValue.length(); i++){
                    rawBytes[6+i] = stringBytes[i];
                }
                break;
        }
        serialized = true;
    }

}
