package com.github.steveice10.mc.protocol.packet.ingame.client.window;

import com.github.steveice10.mc.protocol.data.MagicValues;
import com.github.steveice10.mc.protocol.data.game.window.CraftingBookDataType;
import com.github.steveice10.mc.protocol.packet.MinecraftPacket;
import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput;

import java.io.IOException;

public class ClientCraftingBookDataPacket extends MinecraftPacket {
    private CraftingBookDataType type;
    private int recipeId;
    private boolean craftingBookOpen;
    private boolean filterActive;

    @SuppressWarnings("unused")
    private ClientCraftingBookDataPacket() {
    }

    public ClientCraftingBookDataPacket(int recipeId) {
        this.type = CraftingBookDataType.DISPLAYED_RECIPE;
        this.recipeId = recipeId;
    }

    public ClientCraftingBookDataPacket(boolean craftingBookOpen, boolean filterActive) {
        this.type = CraftingBookDataType.CRAFTING_BOOK_STATUS;
        this.craftingBookOpen = craftingBookOpen;
        this.filterActive = filterActive;
    }

    public CraftingBookDataType getType() {
        return type;
    }

    private void ensureType(CraftingBookDataType type, String what) {
        if(this.type != type) {
            throw new IllegalStateException(what + " is only set when type is " + type + " but it is " + this.type);
        }
    }

    public int getRecipeId() {
        ensureType(CraftingBookDataType.DISPLAYED_RECIPE, "recipeId");
        return recipeId;
    }

    public boolean isCraftingBookOpen() {
        ensureType(CraftingBookDataType.CRAFTING_BOOK_STATUS, "craftingBookOpen");
        return craftingBookOpen;
    }

    public boolean isFilterActive() {
        ensureType(CraftingBookDataType.CRAFTING_BOOK_STATUS, "filterActive");
        return filterActive;
    }

    @Override
    public void read(NetInput in) throws IOException {
        switch(this.type = MagicValues.key(CraftingBookDataType.class, in.readVarInt())) {
            case DISPLAYED_RECIPE:
                this.recipeId = in.readInt();
                break;
            case CRAFTING_BOOK_STATUS:
                this.craftingBookOpen = in.readBoolean();
                this.filterActive = in.readBoolean();
                break;
            default:
                throw new IOException("Unknown crafting book data type: " + this.type);
        }
    }

    @Override
    public void write(NetOutput out) throws IOException {
        out.writeVarInt(MagicValues.value(Integer.class, this.type));
        switch(this.type) {
            case DISPLAYED_RECIPE:
                out.writeInt(this.recipeId);
                break;
            case CRAFTING_BOOK_STATUS:
                out.writeBoolean(this.craftingBookOpen);
                out.writeBoolean(this.filterActive);
                break;
            default:
                throw new IOException("Unknown crafting book data type: " + this.type);
        }
    }
}

@@ -523,19 +523,22 @@
 private 
+Str
 in
-t
+g
  recipeI
@@ -596,32 +596,120 @@
 e boolean filter
+CraftingActive;%0A    private boolean smeltingBookOpen;%0A    private boolean filterSmelting
 Active;%0A%0A    @Su
@@ -825,19 +825,22 @@
 aPacket(
+Str
 in
-t
+g
  recipeI
@@ -1020,24 +1020,128 @@
 olean filter
+CraftingActive,%0A                                        boolean smeltingBookOpen, boolean filterSmelting
 Active) %7B%0A  
@@ -1262,32 +1262,40 @@
      this.filter
+Crafting
 Active = filterA
@@ -1289,24 +1289,32 @@
 ive = filter
+Crafting
 Active;%0A    
@@ -1639,11 +1639,14 @@
 lic 
+Str
 in
-t
+g
  get
@@ -1949,24 +1949,32 @@
 ean isFilter
+Crafting
 Active() %7B%0A 
@@ -2037,24 +2037,32 @@
 TUS, %22filter
+Crafting
 Active%22);%0A  
@@ -2076,24 +2076,374 @@
 eturn filter
+CraftingActive;%0A    %7D%0A%0A    public boolean isSmeltingBookOpen() %7B%0A        ensureType(CraftingBookDataType.CRAFTING_BOOK_STATUS, %22smeltingBookOpen%22);%0A        return smeltingBookOpen;%0A    %7D%0A%0A    public boolean isFilterSmeltingActive() %7B%0A        ensureType(CraftingBookDataType.CRAFTING_BOOK_STATUS, %22filterSmeltingActive%22);%0A        return filterSmelting
 Active;%0A    
@@ -2679,19 +2679,22 @@
  in.read
-Int
+String
 ();%0A    
@@ -2832,24 +2832,152 @@
  this.filter
+CraftingActive = in.readBoolean();%0A                this.smeltingBookOpen = in.readBoolean();%0A                this.filterSmelting
 Active = in.
@@ -3370,19 +3370,22 @@
 ut.write
-Int
+String
 (this.re
@@ -3512,16 +3512,16 @@
 kOpen);%0A
-
         
@@ -3556,16 +3556,142 @@
 s.filter
+CraftingActive);%0A                out.writeBoolean(this.smeltingBookOpen);%0A                out.writeBoolean(this.filterSmelting
 Active);

Update ClientCraftingBookDataPacket