package electrosphere.net.parser.net.message;

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

public class WorldMessage extends NetworkMessage {

    public enum WorldMessageType {
        METADATA,
        REQUESTCHUNK,
        UPDATE,
        CHUNKLOADSTART,
        MACROVALUE,
        HEIGHTMAPMODIFICATION,
        SPAWNPOSITION,
    }

    WorldMessageType messageType;
    int worldSizeDiscrete;
    int dynamicInterpolationRatio;
    float randomDampener;
    int worldMinX;
    int worldMinY;
    int worldMaxX;
    int worldMaxY;
    int worldX;
    int worldY;
    float value;
    int locationX;
    int locationY;
    float realLocationX;
    float realLocationY;
    float macroValue00;
    float macroValue01;
    float macroValue02;
    float macroValue03;
    float macroValue04;
    float macroValue10;
    float macroValue11;
    float macroValue12;
    float macroValue13;
    float macroValue14;
    float macroValue20;
    float macroValue21;
    float macroValue22;
    float macroValue23;
    float macroValue24;
    float macroValue30;
    float macroValue31;
    float macroValue32;
    float macroValue33;
    float macroValue34;
    float macroValue40;
    float macroValue41;
    float macroValue42;
    float macroValue43;
    float macroValue44;
    long randomizerValue00;
    long randomizerValue01;
    long randomizerValue02;
    long randomizerValue03;
    long randomizerValue04;
    long randomizerValue10;
    long randomizerValue11;
    long randomizerValue12;
    long randomizerValue13;
    long randomizerValue14;
    long randomizerValue20;
    long randomizerValue21;
    long randomizerValue22;
    long randomizerValue23;
    long randomizerValue24;
    long randomizerValue30;
    long randomizerValue31;
    long randomizerValue32;
    long randomizerValue33;
    long randomizerValue34;
    long randomizerValue40;
    long randomizerValue41;
    long randomizerValue42;
    long randomizerValue43;
    long randomizerValue44;

    WorldMessage(WorldMessageType messageType){
        this.type = MessageType.WORLD_MESSAGE;
        this.messageType = messageType;
    }

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

    public int getworldSizeDiscrete() {
        return worldSizeDiscrete;
    }

    public void setworldSizeDiscrete(int worldSizeDiscrete) {
        this.worldSizeDiscrete = worldSizeDiscrete;
    }

    public int getdynamicInterpolationRatio() {
        return dynamicInterpolationRatio;
    }

    public void setdynamicInterpolationRatio(int dynamicInterpolationRatio) {
        this.dynamicInterpolationRatio = dynamicInterpolationRatio;
    }

    public float getrandomDampener() {
        return randomDampener;
    }

    public void setrandomDampener(float randomDampener) {
        this.randomDampener = randomDampener;
    }

    public int getworldMinX() {
        return worldMinX;
    }

    public void setworldMinX(int worldMinX) {
        this.worldMinX = worldMinX;
    }

    public int getworldMinY() {
        return worldMinY;
    }

    public void setworldMinY(int worldMinY) {
        this.worldMinY = worldMinY;
    }

    public int getworldMaxX() {
        return worldMaxX;
    }

    public void setworldMaxX(int worldMaxX) {
        this.worldMaxX = worldMaxX;
    }

    public int getworldMaxY() {
        return worldMaxY;
    }

    public void setworldMaxY(int worldMaxY) {
        this.worldMaxY = worldMaxY;
    }

    public int getworldX() {
        return worldX;
    }

    public void setworldX(int worldX) {
        this.worldX = worldX;
    }

    public int getworldY() {
        return worldY;
    }

    public void setworldY(int worldY) {
        this.worldY = worldY;
    }

    public float getvalue() {
        return value;
    }

    public void setvalue(float value) {
        this.value = value;
    }

    public int getlocationX() {
        return locationX;
    }

    public void setlocationX(int locationX) {
        this.locationX = locationX;
    }

    public int getlocationY() {
        return locationY;
    }

    public void setlocationY(int locationY) {
        this.locationY = locationY;
    }

    public float getrealLocationX() {
        return realLocationX;
    }

    public void setrealLocationX(float realLocationX) {
        this.realLocationX = realLocationX;
    }

    public float getrealLocationY() {
        return realLocationY;
    }

    public void setrealLocationY(float realLocationY) {
        this.realLocationY = realLocationY;
    }

    public float getmacroValue00() {
        return macroValue00;
    }

    public void setmacroValue00(float macroValue00) {
        this.macroValue00 = macroValue00;
    }

    public float getmacroValue01() {
        return macroValue01;
    }

    public void setmacroValue01(float macroValue01) {
        this.macroValue01 = macroValue01;
    }

    public float getmacroValue02() {
        return macroValue02;
    }

    public void setmacroValue02(float macroValue02) {
        this.macroValue02 = macroValue02;
    }

    public float getmacroValue03() {
        return macroValue03;
    }

    public void setmacroValue03(float macroValue03) {
        this.macroValue03 = macroValue03;
    }

    public float getmacroValue04() {
        return macroValue04;
    }

    public void setmacroValue04(float macroValue04) {
        this.macroValue04 = macroValue04;
    }

    public float getmacroValue10() {
        return macroValue10;
    }

    public void setmacroValue10(float macroValue10) {
        this.macroValue10 = macroValue10;
    }

    public float getmacroValue11() {
        return macroValue11;
    }

    public void setmacroValue11(float macroValue11) {
        this.macroValue11 = macroValue11;
    }

    public float getmacroValue12() {
        return macroValue12;
    }

    public void setmacroValue12(float macroValue12) {
        this.macroValue12 = macroValue12;
    }

    public float getmacroValue13() {
        return macroValue13;
    }

    public void setmacroValue13(float macroValue13) {
        this.macroValue13 = macroValue13;
    }

    public float getmacroValue14() {
        return macroValue14;
    }

    public void setmacroValue14(float macroValue14) {
        this.macroValue14 = macroValue14;
    }

    public float getmacroValue20() {
        return macroValue20;
    }

    public void setmacroValue20(float macroValue20) {
        this.macroValue20 = macroValue20;
    }

    public float getmacroValue21() {
        return macroValue21;
    }

    public void setmacroValue21(float macroValue21) {
        this.macroValue21 = macroValue21;
    }

    public float getmacroValue22() {
        return macroValue22;
    }

    public void setmacroValue22(float macroValue22) {
        this.macroValue22 = macroValue22;
    }

    public float getmacroValue23() {
        return macroValue23;
    }

    public void setmacroValue23(float macroValue23) {
        this.macroValue23 = macroValue23;
    }

    public float getmacroValue24() {
        return macroValue24;
    }

    public void setmacroValue24(float macroValue24) {
        this.macroValue24 = macroValue24;
    }

    public float getmacroValue30() {
        return macroValue30;
    }

    public void setmacroValue30(float macroValue30) {
        this.macroValue30 = macroValue30;
    }

    public float getmacroValue31() {
        return macroValue31;
    }

    public void setmacroValue31(float macroValue31) {
        this.macroValue31 = macroValue31;
    }

    public float getmacroValue32() {
        return macroValue32;
    }

    public void setmacroValue32(float macroValue32) {
        this.macroValue32 = macroValue32;
    }

    public float getmacroValue33() {
        return macroValue33;
    }

    public void setmacroValue33(float macroValue33) {
        this.macroValue33 = macroValue33;
    }

    public float getmacroValue34() {
        return macroValue34;
    }

    public void setmacroValue34(float macroValue34) {
        this.macroValue34 = macroValue34;
    }

    public float getmacroValue40() {
        return macroValue40;
    }

    public void setmacroValue40(float macroValue40) {
        this.macroValue40 = macroValue40;
    }

    public float getmacroValue41() {
        return macroValue41;
    }

    public void setmacroValue41(float macroValue41) {
        this.macroValue41 = macroValue41;
    }

    public float getmacroValue42() {
        return macroValue42;
    }

    public void setmacroValue42(float macroValue42) {
        this.macroValue42 = macroValue42;
    }

    public float getmacroValue43() {
        return macroValue43;
    }

    public void setmacroValue43(float macroValue43) {
        this.macroValue43 = macroValue43;
    }

    public float getmacroValue44() {
        return macroValue44;
    }

    public void setmacroValue44(float macroValue44) {
        this.macroValue44 = macroValue44;
    }

    public long getrandomizerValue00() {
        return randomizerValue00;
    }

    public void setrandomizerValue00(long randomizerValue00) {
        this.randomizerValue00 = randomizerValue00;
    }

    public long getrandomizerValue01() {
        return randomizerValue01;
    }

    public void setrandomizerValue01(long randomizerValue01) {
        this.randomizerValue01 = randomizerValue01;
    }

    public long getrandomizerValue02() {
        return randomizerValue02;
    }

    public void setrandomizerValue02(long randomizerValue02) {
        this.randomizerValue02 = randomizerValue02;
    }

    public long getrandomizerValue03() {
        return randomizerValue03;
    }

    public void setrandomizerValue03(long randomizerValue03) {
        this.randomizerValue03 = randomizerValue03;
    }

    public long getrandomizerValue04() {
        return randomizerValue04;
    }

    public void setrandomizerValue04(long randomizerValue04) {
        this.randomizerValue04 = randomizerValue04;
    }

    public long getrandomizerValue10() {
        return randomizerValue10;
    }

    public void setrandomizerValue10(long randomizerValue10) {
        this.randomizerValue10 = randomizerValue10;
    }

    public long getrandomizerValue11() {
        return randomizerValue11;
    }

    public void setrandomizerValue11(long randomizerValue11) {
        this.randomizerValue11 = randomizerValue11;
    }

    public long getrandomizerValue12() {
        return randomizerValue12;
    }

    public void setrandomizerValue12(long randomizerValue12) {
        this.randomizerValue12 = randomizerValue12;
    }

    public long getrandomizerValue13() {
        return randomizerValue13;
    }

    public void setrandomizerValue13(long randomizerValue13) {
        this.randomizerValue13 = randomizerValue13;
    }

    public long getrandomizerValue14() {
        return randomizerValue14;
    }

    public void setrandomizerValue14(long randomizerValue14) {
        this.randomizerValue14 = randomizerValue14;
    }

    public long getrandomizerValue20() {
        return randomizerValue20;
    }

    public void setrandomizerValue20(long randomizerValue20) {
        this.randomizerValue20 = randomizerValue20;
    }

    public long getrandomizerValue21() {
        return randomizerValue21;
    }

    public void setrandomizerValue21(long randomizerValue21) {
        this.randomizerValue21 = randomizerValue21;
    }

    public long getrandomizerValue22() {
        return randomizerValue22;
    }

    public void setrandomizerValue22(long randomizerValue22) {
        this.randomizerValue22 = randomizerValue22;
    }

    public long getrandomizerValue23() {
        return randomizerValue23;
    }

    public void setrandomizerValue23(long randomizerValue23) {
        this.randomizerValue23 = randomizerValue23;
    }

    public long getrandomizerValue24() {
        return randomizerValue24;
    }

    public void setrandomizerValue24(long randomizerValue24) {
        this.randomizerValue24 = randomizerValue24;
    }

    public long getrandomizerValue30() {
        return randomizerValue30;
    }

    public void setrandomizerValue30(long randomizerValue30) {
        this.randomizerValue30 = randomizerValue30;
    }

    public long getrandomizerValue31() {
        return randomizerValue31;
    }

    public void setrandomizerValue31(long randomizerValue31) {
        this.randomizerValue31 = randomizerValue31;
    }

    public long getrandomizerValue32() {
        return randomizerValue32;
    }

    public void setrandomizerValue32(long randomizerValue32) {
        this.randomizerValue32 = randomizerValue32;
    }

    public long getrandomizerValue33() {
        return randomizerValue33;
    }

    public void setrandomizerValue33(long randomizerValue33) {
        this.randomizerValue33 = randomizerValue33;
    }

    public long getrandomizerValue34() {
        return randomizerValue34;
    }

    public void setrandomizerValue34(long randomizerValue34) {
        this.randomizerValue34 = randomizerValue34;
    }

    public long getrandomizerValue40() {
        return randomizerValue40;
    }

    public void setrandomizerValue40(long randomizerValue40) {
        this.randomizerValue40 = randomizerValue40;
    }

    public long getrandomizerValue41() {
        return randomizerValue41;
    }

    public void setrandomizerValue41(long randomizerValue41) {
        this.randomizerValue41 = randomizerValue41;
    }

    public long getrandomizerValue42() {
        return randomizerValue42;
    }

    public void setrandomizerValue42(long randomizerValue42) {
        this.randomizerValue42 = randomizerValue42;
    }

    public long getrandomizerValue43() {
        return randomizerValue43;
    }

    public void setrandomizerValue43(long randomizerValue43) {
        this.randomizerValue43 = randomizerValue43;
    }

    public long getrandomizerValue44() {
        return randomizerValue44;
    }

    public void setrandomizerValue44(long randomizerValue44) {
        this.randomizerValue44 = randomizerValue44;
    }

    static void stripPacketHeader(List<Byte> byteStream){
        byteStream.remove(0);
        byteStream.remove(0);
    }

    public static boolean canParseMessage(List<Byte> byteStream, byte secondByte){
        switch(secondByte){
            case TypeBytes.WORLD_MESSAGE_TYPE_METADATA:
                if(byteStream.size() >= TypeBytes.WORLD_MESSAGE_TYPE_METADATA_SIZE){
                    return true;
                } else {
                    return false;
                }
            case TypeBytes.WORLD_MESSAGE_TYPE_REQUESTCHUNK:
                if(byteStream.size() >= TypeBytes.WORLD_MESSAGE_TYPE_REQUESTCHUNK_SIZE){
                    return true;
                } else {
                    return false;
                }
            case TypeBytes.WORLD_MESSAGE_TYPE_UPDATE:
                if(byteStream.size() >= TypeBytes.WORLD_MESSAGE_TYPE_UPDATE_SIZE){
                    return true;
                } else {
                    return false;
                }
            case TypeBytes.WORLD_MESSAGE_TYPE_CHUNKLOADSTART:
                if(byteStream.size() >= TypeBytes.WORLD_MESSAGE_TYPE_CHUNKLOADSTART_SIZE){
                    return true;
                } else {
                    return false;
                }
            case TypeBytes.WORLD_MESSAGE_TYPE_MACROVALUE:
                if(byteStream.size() >= TypeBytes.WORLD_MESSAGE_TYPE_MACROVALUE_SIZE){
                    return true;
                } else {
                    return false;
                }
            case TypeBytes.WORLD_MESSAGE_TYPE_HEIGHTMAPMODIFICATION:
                if(byteStream.size() >= TypeBytes.WORLD_MESSAGE_TYPE_HEIGHTMAPMODIFICATION_SIZE){
                    return true;
                } else {
                    return false;
                }
            case TypeBytes.WORLD_MESSAGE_TYPE_SPAWNPOSITION:
                if(byteStream.size() >= TypeBytes.WORLD_MESSAGE_TYPE_SPAWNPOSITION_SIZE){
                    return true;
                } else {
                    return false;
                }
        }
        return false;
    }

    public static WorldMessage parseMetadataMessage(List<Byte> byteStream){
        WorldMessage rVal = new WorldMessage(WorldMessageType.METADATA);
        stripPacketHeader(byteStream);
        rVal.setworldSizeDiscrete(ByteStreamUtils.popIntFromByteQueue(byteStream));
        rVal.setdynamicInterpolationRatio(ByteStreamUtils.popIntFromByteQueue(byteStream));
        rVal.setrandomDampener(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setworldMinX(ByteStreamUtils.popIntFromByteQueue(byteStream));
        rVal.setworldMinY(ByteStreamUtils.popIntFromByteQueue(byteStream));
        rVal.setworldMaxX(ByteStreamUtils.popIntFromByteQueue(byteStream));
        rVal.setworldMaxY(ByteStreamUtils.popIntFromByteQueue(byteStream));
        return rVal;
    }

    public static WorldMessage constructMetadataMessage(int worldSizeDiscrete,int dynamicInterpolationRatio,float randomDampener,int worldMinX,int worldMinY,int worldMaxX,int worldMaxY){
        WorldMessage rVal = new WorldMessage(WorldMessageType.METADATA);
        rVal.setworldSizeDiscrete(worldSizeDiscrete);
        rVal.setdynamicInterpolationRatio(dynamicInterpolationRatio);
        rVal.setrandomDampener(randomDampener);
        rVal.setworldMinX(worldMinX);
        rVal.setworldMinY(worldMinY);
        rVal.setworldMaxX(worldMaxX);
        rVal.setworldMaxY(worldMaxY);
        rVal.serialize();
        return rVal;
    }

    public static WorldMessage parseRequestChunkMessage(List<Byte> byteStream){
        WorldMessage rVal = new WorldMessage(WorldMessageType.REQUESTCHUNK);
        stripPacketHeader(byteStream);
        rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteStream));
        rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteStream));
        return rVal;
    }

    public static WorldMessage constructRequestChunkMessage(int worldX,int worldY){
        WorldMessage rVal = new WorldMessage(WorldMessageType.REQUESTCHUNK);
        rVal.setworldX(worldX);
        rVal.setworldY(worldY);
        rVal.serialize();
        return rVal;
    }

    public static WorldMessage parseUpdateMessage(List<Byte> byteStream){
        WorldMessage rVal = new WorldMessage(WorldMessageType.UPDATE);
        stripPacketHeader(byteStream);
        rVal.setlocationX(ByteStreamUtils.popIntFromByteQueue(byteStream));
        rVal.setlocationY(ByteStreamUtils.popIntFromByteQueue(byteStream));
        return rVal;
    }

    public static WorldMessage constructUpdateMessage(int locationX,int locationY){
        WorldMessage rVal = new WorldMessage(WorldMessageType.UPDATE);
        rVal.setlocationX(locationX);
        rVal.setlocationY(locationY);
        rVal.serialize();
        return rVal;
    }

    public static WorldMessage parsechunkLoadStartMessage(List<Byte> byteStream){
        WorldMessage rVal = new WorldMessage(WorldMessageType.CHUNKLOADSTART);
        stripPacketHeader(byteStream);
        rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteStream));
        rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteStream));
        rVal.setvalue(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        return rVal;
    }

    public static WorldMessage constructchunkLoadStartMessage(int worldX,int worldY,float value){
        WorldMessage rVal = new WorldMessage(WorldMessageType.CHUNKLOADSTART);
        rVal.setworldX(worldX);
        rVal.setworldY(worldY);
        rVal.setvalue(value);
        rVal.serialize();
        return rVal;
    }

    public static WorldMessage parseMacroValueMessage(List<Byte> byteStream){
        WorldMessage rVal = new WorldMessage(WorldMessageType.MACROVALUE);
        stripPacketHeader(byteStream);
        rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteStream));
        rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteStream));
        rVal.setmacroValue00(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue01(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue02(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue03(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue04(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue10(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue11(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue12(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue13(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue14(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue20(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue21(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue22(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue23(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue24(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue30(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue31(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue32(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue33(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue34(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue40(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue41(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue42(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue43(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setmacroValue44(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setrandomizerValue00(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue01(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue02(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue03(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue04(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue10(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue11(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue12(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue13(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue14(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue20(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue21(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue22(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue23(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue24(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue30(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue31(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue32(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue33(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue34(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue40(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue41(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue42(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue43(ByteStreamUtils.popLongFromByteQueue(byteStream));
        rVal.setrandomizerValue44(ByteStreamUtils.popLongFromByteQueue(byteStream));
        return rVal;
    }

    public static WorldMessage constructMacroValueMessage(int worldX,int worldY,float macroValue00,float macroValue01,float macroValue02,float macroValue03,float macroValue04,float macroValue10,float macroValue11,float macroValue12,float macroValue13,float macroValue14,float macroValue20,float macroValue21,float macroValue22,float macroValue23,float macroValue24,float macroValue30,float macroValue31,float macroValue32,float macroValue33,float macroValue34,float macroValue40,float macroValue41,float macroValue42,float macroValue43,float macroValue44,long randomizerValue00,long randomizerValue01,long randomizerValue02,long randomizerValue03,long randomizerValue04,long randomizerValue10,long randomizerValue11,long randomizerValue12,long randomizerValue13,long randomizerValue14,long randomizerValue20,long randomizerValue21,long randomizerValue22,long randomizerValue23,long randomizerValue24,long randomizerValue30,long randomizerValue31,long randomizerValue32,long randomizerValue33,long randomizerValue34,long randomizerValue40,long randomizerValue41,long randomizerValue42,long randomizerValue43,long randomizerValue44){
        WorldMessage rVal = new WorldMessage(WorldMessageType.MACROVALUE);
        rVal.setworldX(worldX);
        rVal.setworldY(worldY);
        rVal.setmacroValue00(macroValue00);
        rVal.setmacroValue01(macroValue01);
        rVal.setmacroValue02(macroValue02);
        rVal.setmacroValue03(macroValue03);
        rVal.setmacroValue04(macroValue04);
        rVal.setmacroValue10(macroValue10);
        rVal.setmacroValue11(macroValue11);
        rVal.setmacroValue12(macroValue12);
        rVal.setmacroValue13(macroValue13);
        rVal.setmacroValue14(macroValue14);
        rVal.setmacroValue20(macroValue20);
        rVal.setmacroValue21(macroValue21);
        rVal.setmacroValue22(macroValue22);
        rVal.setmacroValue23(macroValue23);
        rVal.setmacroValue24(macroValue24);
        rVal.setmacroValue30(macroValue30);
        rVal.setmacroValue31(macroValue31);
        rVal.setmacroValue32(macroValue32);
        rVal.setmacroValue33(macroValue33);
        rVal.setmacroValue34(macroValue34);
        rVal.setmacroValue40(macroValue40);
        rVal.setmacroValue41(macroValue41);
        rVal.setmacroValue42(macroValue42);
        rVal.setmacroValue43(macroValue43);
        rVal.setmacroValue44(macroValue44);
        rVal.setrandomizerValue00(randomizerValue00);
        rVal.setrandomizerValue01(randomizerValue01);
        rVal.setrandomizerValue02(randomizerValue02);
        rVal.setrandomizerValue03(randomizerValue03);
        rVal.setrandomizerValue04(randomizerValue04);
        rVal.setrandomizerValue10(randomizerValue10);
        rVal.setrandomizerValue11(randomizerValue11);
        rVal.setrandomizerValue12(randomizerValue12);
        rVal.setrandomizerValue13(randomizerValue13);
        rVal.setrandomizerValue14(randomizerValue14);
        rVal.setrandomizerValue20(randomizerValue20);
        rVal.setrandomizerValue21(randomizerValue21);
        rVal.setrandomizerValue22(randomizerValue22);
        rVal.setrandomizerValue23(randomizerValue23);
        rVal.setrandomizerValue24(randomizerValue24);
        rVal.setrandomizerValue30(randomizerValue30);
        rVal.setrandomizerValue31(randomizerValue31);
        rVal.setrandomizerValue32(randomizerValue32);
        rVal.setrandomizerValue33(randomizerValue33);
        rVal.setrandomizerValue34(randomizerValue34);
        rVal.setrandomizerValue40(randomizerValue40);
        rVal.setrandomizerValue41(randomizerValue41);
        rVal.setrandomizerValue42(randomizerValue42);
        rVal.setrandomizerValue43(randomizerValue43);
        rVal.setrandomizerValue44(randomizerValue44);
        rVal.serialize();
        return rVal;
    }

    public static WorldMessage parseheightMapModificationMessage(List<Byte> byteStream){
        WorldMessage rVal = new WorldMessage(WorldMessageType.HEIGHTMAPMODIFICATION);
        stripPacketHeader(byteStream);
        rVal.setvalue(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteStream));
        rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteStream));
        rVal.setlocationX(ByteStreamUtils.popIntFromByteQueue(byteStream));
        rVal.setlocationY(ByteStreamUtils.popIntFromByteQueue(byteStream));
        return rVal;
    }

    public static WorldMessage constructheightMapModificationMessage(float value,int worldX,int worldY,int locationX,int locationY){
        WorldMessage rVal = new WorldMessage(WorldMessageType.HEIGHTMAPMODIFICATION);
        rVal.setvalue(value);
        rVal.setworldX(worldX);
        rVal.setworldY(worldY);
        rVal.setlocationX(locationX);
        rVal.setlocationY(locationY);
        rVal.serialize();
        return rVal;
    }

    public static WorldMessage parseSpawnPositionMessage(List<Byte> byteStream){
        WorldMessage rVal = new WorldMessage(WorldMessageType.SPAWNPOSITION);
        stripPacketHeader(byteStream);
        rVal.setrealLocationX(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        rVal.setrealLocationY(ByteStreamUtils.popFloatFromByteQueue(byteStream));
        return rVal;
    }

    public static WorldMessage constructSpawnPositionMessage(float realLocationX,float realLocationY){
        WorldMessage rVal = new WorldMessage(WorldMessageType.SPAWNPOSITION);
        rVal.setrealLocationX(realLocationX);
        rVal.setrealLocationY(realLocationY);
        rVal.serialize();
        return rVal;
    }

    @Override
    void serialize(){
        byte[] intValues = new byte[8];
        byte[] stringBytes;
        switch(this.messageType){
            case METADATA:
                rawBytes = new byte[2+4+4+4+4+4+4+4];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_WORLD;
                //entity messaage header
                rawBytes[1] = TypeBytes.WORLD_MESSAGE_TYPE_METADATA;
                intValues = ByteStreamUtils.serializeIntToBytes(worldSizeDiscrete);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(dynamicInterpolationRatio);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeFloatToBytes(randomDampener);
                for(int i = 0; i < 4; i++){
                    rawBytes[10+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeIntToBytes(worldMinX);
                for(int i = 0; i < 4; i++){
                    rawBytes[14+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(worldMinY);
                for(int i = 0; i < 4; i++){
                    rawBytes[18+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(worldMaxX);
                for(int i = 0; i < 4; i++){
                    rawBytes[22+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(worldMaxY);
                for(int i = 0; i < 4; i++){
                    rawBytes[26+i] = intValues[i];
                }
                break;
            case REQUESTCHUNK:
                rawBytes = new byte[2+4+4];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_WORLD;
                //entity messaage header
                rawBytes[1] = TypeBytes.WORLD_MESSAGE_TYPE_REQUESTCHUNK;
                intValues = ByteStreamUtils.serializeIntToBytes(worldX);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(worldY);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }
                break;
            case UPDATE:
                rawBytes = new byte[2+4+4];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_WORLD;
                //entity messaage header
                rawBytes[1] = TypeBytes.WORLD_MESSAGE_TYPE_UPDATE;
                intValues = ByteStreamUtils.serializeIntToBytes(locationX);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(locationY);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }
                break;
            case CHUNKLOADSTART:
                rawBytes = new byte[2+4+4+4];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_WORLD;
                //entity messaage header
                rawBytes[1] = TypeBytes.WORLD_MESSAGE_TYPE_CHUNKLOADSTART;
                intValues = ByteStreamUtils.serializeIntToBytes(worldX);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(worldY);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeFloatToBytes(value);
                for(int i = 0; i < 4; i++){
                    rawBytes[10+i] = intValues[i];
                }                break;
            case MACROVALUE:
                rawBytes = new byte[2+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_WORLD;
                //entity messaage header
                rawBytes[1] = TypeBytes.WORLD_MESSAGE_TYPE_MACROVALUE;
                intValues = ByteStreamUtils.serializeIntToBytes(worldX);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(worldY);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue00);
                for(int i = 0; i < 4; i++){
                    rawBytes[10+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue01);
                for(int i = 0; i < 4; i++){
                    rawBytes[14+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue02);
                for(int i = 0; i < 4; i++){
                    rawBytes[18+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue03);
                for(int i = 0; i < 4; i++){
                    rawBytes[22+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue04);
                for(int i = 0; i < 4; i++){
                    rawBytes[26+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue10);
                for(int i = 0; i < 4; i++){
                    rawBytes[30+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue11);
                for(int i = 0; i < 4; i++){
                    rawBytes[34+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue12);
                for(int i = 0; i < 4; i++){
                    rawBytes[38+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue13);
                for(int i = 0; i < 4; i++){
                    rawBytes[42+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue14);
                for(int i = 0; i < 4; i++){
                    rawBytes[46+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue20);
                for(int i = 0; i < 4; i++){
                    rawBytes[50+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue21);
                for(int i = 0; i < 4; i++){
                    rawBytes[54+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue22);
                for(int i = 0; i < 4; i++){
                    rawBytes[58+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue23);
                for(int i = 0; i < 4; i++){
                    rawBytes[62+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue24);
                for(int i = 0; i < 4; i++){
                    rawBytes[66+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue30);
                for(int i = 0; i < 4; i++){
                    rawBytes[70+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue31);
                for(int i = 0; i < 4; i++){
                    rawBytes[74+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue32);
                for(int i = 0; i < 4; i++){
                    rawBytes[78+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue33);
                for(int i = 0; i < 4; i++){
                    rawBytes[82+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue34);
                for(int i = 0; i < 4; i++){
                    rawBytes[86+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue40);
                for(int i = 0; i < 4; i++){
                    rawBytes[90+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue41);
                for(int i = 0; i < 4; i++){
                    rawBytes[94+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue42);
                for(int i = 0; i < 4; i++){
                    rawBytes[98+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue43);
                for(int i = 0; i < 4; i++){
                    rawBytes[102+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(macroValue44);
                for(int i = 0; i < 4; i++){
                    rawBytes[106+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue00);
                for(int i = 0; i < 8; i++){
                    rawBytes[110+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue01);
                for(int i = 0; i < 8; i++){
                    rawBytes[118+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue02);
                for(int i = 0; i < 8; i++){
                    rawBytes[126+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue03);
                for(int i = 0; i < 8; i++){
                    rawBytes[134+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue04);
                for(int i = 0; i < 8; i++){
                    rawBytes[142+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue10);
                for(int i = 0; i < 8; i++){
                    rawBytes[150+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue11);
                for(int i = 0; i < 8; i++){
                    rawBytes[158+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue12);
                for(int i = 0; i < 8; i++){
                    rawBytes[166+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue13);
                for(int i = 0; i < 8; i++){
                    rawBytes[174+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue14);
                for(int i = 0; i < 8; i++){
                    rawBytes[182+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue20);
                for(int i = 0; i < 8; i++){
                    rawBytes[190+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue21);
                for(int i = 0; i < 8; i++){
                    rawBytes[198+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue22);
                for(int i = 0; i < 8; i++){
                    rawBytes[206+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue23);
                for(int i = 0; i < 8; i++){
                    rawBytes[214+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue24);
                for(int i = 0; i < 8; i++){
                    rawBytes[222+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue30);
                for(int i = 0; i < 8; i++){
                    rawBytes[230+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue31);
                for(int i = 0; i < 8; i++){
                    rawBytes[238+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue32);
                for(int i = 0; i < 8; i++){
                    rawBytes[246+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue33);
                for(int i = 0; i < 8; i++){
                    rawBytes[254+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue34);
                for(int i = 0; i < 8; i++){
                    rawBytes[262+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue40);
                for(int i = 0; i < 8; i++){
                    rawBytes[270+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue41);
                for(int i = 0; i < 8; i++){
                    rawBytes[278+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue42);
                for(int i = 0; i < 8; i++){
                    rawBytes[286+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue43);
                for(int i = 0; i < 8; i++){
                    rawBytes[294+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue44);
                for(int i = 0; i < 8; i++){
                    rawBytes[302+i] = intValues[i];
                }
                break;
            case HEIGHTMAPMODIFICATION:
                rawBytes = new byte[2+4+4+4+4+4];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_WORLD;
                //entity messaage header
                rawBytes[1] = TypeBytes.WORLD_MESSAGE_TYPE_HEIGHTMAPMODIFICATION;
                intValues = ByteStreamUtils.serializeFloatToBytes(value);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeIntToBytes(worldX);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(worldY);
                for(int i = 0; i < 4; i++){
                    rawBytes[10+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(locationX);
                for(int i = 0; i < 4; i++){
                    rawBytes[14+i] = intValues[i];
                }
                intValues = ByteStreamUtils.serializeIntToBytes(locationY);
                for(int i = 0; i < 4; i++){
                    rawBytes[18+i] = intValues[i];
                }
                break;
            case SPAWNPOSITION:
                rawBytes = new byte[2+4+4];
                //message header
                rawBytes[0] = TypeBytes.MESSAGE_TYPE_WORLD;
                //entity messaage header
                rawBytes[1] = TypeBytes.WORLD_MESSAGE_TYPE_SPAWNPOSITION;
                intValues = ByteStreamUtils.serializeFloatToBytes(realLocationX);
                for(int i = 0; i < 4; i++){
                    rawBytes[2+i] = intValues[i];
                }                intValues = ByteStreamUtils.serializeFloatToBytes(realLocationY);
                for(int i = 0; i < 4; i++){
                    rawBytes[6+i] = intValues[i];
                }                break;
        }
        serialized = true;
    }

}
