package net.glowstone.block.entity.state;

import com.destroystokyo.paper.loottable.LootableBlockInventory;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import lombok.Data;
import lombok.EqualsAndHashCode;
import net.glowstone.block.GlowBlock;
import net.glowstone.block.GlowBlockState;
import org.bukkit.Nameable;
import org.bukkit.block.Container;
import org.bukkit.block.Lockable;
import org.bukkit.inventory.Inventory;

@EqualsAndHashCode(callSuper = true)
@Data
public abstract class GlowContainer extends GlowBlockState implements LootableBlockInventory,
    Lockable, Nameable, Container {
    private final AtomicLong nextRefill = new AtomicLong(-1);
    private final AtomicLong lootTableSeed = new AtomicLong(0);
    private String lock;
    private String customName;

    public GlowContainer(GlowBlock block) {
        super(block);
    }

    // TODO: Lootable implementation

    @Override
    public String getLootTableName() {
        return null;
    }

    @Override
    public boolean hasLootTable() {
        return false;
    }

    @Override
    public String setLootTable(String name) {
        return null;
    }

    @Override
    public String setLootTable(String s, long l) {
        return null;
    }

    @Override
    public long getLootTableSeed() {
        return lootTableSeed.get();
    }

    @Override
    public long setLootTableSeed(long seed) {
        return lootTableSeed.getAndSet(seed);
    }

    @Override
    public void clearLootTable() {

    }

    @Override
    public boolean isRefillEnabled() {
        return false;
    }

    @Override
    public boolean hasBeenFilled() {
        return false;
    }

    @Override
    public boolean hasPlayerLooted(UUID uuid) {
        return false;
    }

    @Override
    public Long getLastLooted(UUID uuid) {
        return null;
    }

    @Override
    public boolean setHasPlayerLooted(UUID uuid, boolean b) {
        return false;
    }

    @Override
    public boolean hasPendingRefill() {
        return getNextRefill() >= 0;
    }

    @Override
    public long getLastFilled() {
        return 0;
    }

    @Override
    public long getNextRefill() {
        return nextRefill.get();
    }

    @Override
    public long setNextRefill(long l) {
        return nextRefill.getAndSet(l);
    }

    @Override
    public boolean isLocked() {
        return lock != null;
    }

    @Override
    public Inventory getSnapshotInventory() {
        throw new UnsupportedOperationException();
    }
}

@@ -101,16 +101,38 @@
 entory;%0A
+import java.util.Map;%0A
 import j
@@ -178,25 +178,124 @@
 ent.
-atomic.AtomicLong
+ConcurrentHashMap;%0Aimport java.util.concurrent.atomic.AtomicLong;%0Aimport java.util.concurrent.atomic.AtomicReference
 ;%0Aim
@@ -306,20 +306,22 @@
  lombok.
-Data
+Getter
 ;%0Aimport
@@ -328,33 +328,22 @@
  lombok.
-EqualsAndHashCode
+Setter
 ;%0Aimport
@@ -558,51 +558,8 @@
 y;%0A%0A
-@EqualsAndHashCode(callSuper = true)%0A@Data%0A
 publ
@@ -684,16 +684,78 @@
 ainer %7B%0A
+    private final AtomicLong lastFilled = new AtomicLong(-1);%0A
     priv
@@ -872,16 +872,207 @@
 ong(0);%0A
+    private final AtomicReference%3CString%3E lootTable = new AtomicReference%3C%3E(null);%0A    private final Map%3CUUID, Long%3E playersWhoHaveLooted = new ConcurrentHashMap%3C%3E();%0A    @Getter%0A    @Setter%0A
     priv
@@ -1088,16 +1088,40 @@
 g lock;%0A
+    @Getter%0A    @Setter%0A
     priv
@@ -1315,36 +1315,47 @@
 %0A        return 
-null
+lootTable.get()
 ;%0A    %7D%0A%0A    @Ov
@@ -1404,37 +1404,55 @@
 %0A        return 
-false
+lootTable.get() != null
 ;%0A    %7D%0A%0A    @Ov
@@ -1511,36 +1511,53 @@
 %0A        return 
-null
+setLootTable(name, 0)
 ;%0A    %7D%0A%0A    @Ov
@@ -1605,17 +1605,23 @@
 ing 
-s
+name
 , long 
-l
+seed
 ) %7B%0A
@@ -1624,35 +1624,88 @@
 ) %7B%0A        
-return null
+setLootTableSeed(seed);%0A        return lootTable.getAndSet(name)
 ;%0A    %7D%0A%0A   
@@ -1957,16 +1957,43 @@
 ble() %7B%0A
+        setLootTable(null);
 %0A    %7D%0A%0A
@@ -2037,32 +2037,48 @@
 fillEnabled() %7B%0A
+        // TODO%0A
         return f
@@ -2148,37 +2148,53 @@
 %0A        return 
-false
+lastFilled.get() %3E= 0
 ;%0A    %7D%0A%0A    @Ov
@@ -2255,37 +2255,70 @@
 %0A        return 
-false
+playersWhoHaveLooted.containsKey(uuid)
 ;%0A    %7D%0A%0A    @Ov
@@ -2382,20 +2382,46 @@
  return 
-null
+playersWhoHaveLooted.get(uuid)
 ;%0A    %7D%0A
@@ -2504,37 +2504,176 @@
 %0A        return 
-false
+b%0A                ? playersWhoHaveLooted.put(uuid, getWorld().getFullTime()) != null%0A                : playersWhoHaveLooted.remove(uuid) != null
 ;%0A    %7D%0A%0A    @Ov
@@ -2749,25 +2749,52 @@
 Refill() %3E= 
-0
+Math.max(0, getLastFilled())
 ;%0A    %7D%0A%0A   
@@ -2853,17 +2853,32 @@
  return 
-0
+lastFilled.get()
 ;%0A    %7D%0A
@@ -3128,20 +3128,25 @@
  return 
-l
+getL
 ock
+()
  != null
@@ -3210,24 +3210,40 @@
 ventory() %7B%0A
+        // TODO%0A
         thro

Implement more of GlowContainer (#819)