package info.u_team.u_team_core.blockentity;

import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.Connection;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;

/**
 * Basic implementation of {@link BlockEntity} with some extra data synchronization methods.
 *
 * @author HyCraftHD
 */
public abstract class UBlockEntity extends BlockEntity {
	
	public UBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
		super(type, pos, state);
	}
	
	@Override
	public CompoundTag save(CompoundTag tag) {
		super.save(tag);
		saveNBT(tag);
		return tag;
	}
	
	@Override
	public void load(CompoundTag tag) {
		super.load(tag);
		loadNBT(tag);
	}
	
	/**
	 * Save data to disk. The {@link #setChanged()} method must be called before.
	 *
	 * @param tag
	 */
	public void saveNBT(CompoundTag tag) {
	}
	
	/**
	 * Reads data from disk.
	 *
	 * @param state
	 * @param tag
	 */
	public void loadNBT(CompoundTag tag) {
	}
	
	// sync server -> client
	
	// synchronization on chunk load
	
	@Override
	public CompoundTag getUpdateTag() {
		final var tag = super.getUpdateTag();
		sendChunkLoadData(tag);
		return tag;
	}
	
	@Override
	public void handleUpdateTag(CompoundTag tag) {
		super.load(tag);
		handleChunkLoadData(tag);
	}
	
	/**
	 * Data here will be send to the client side when the chunk is loaded. The data is received in
	 * {@link UBlockEntity#handleChunkLoadData(CompoundNBT)}
	 *
	 * @param tag
	 */
	public void sendChunkLoadData(CompoundTag tag) {
	}
	
	/**
	 * The data from the chunk load is received here. The data is send from
	 * {@link UBlockEntity#sendChunkLoadData(CompoundNBT)}
	 *
	 * @param tag
	 */
	public void handleChunkLoadData(CompoundTag tag) {
	}
	
	// synchronization on block update
	
	@Override
	public ClientboundBlockEntityDataPacket getUpdatePacket() {
		final var tag = new CompoundTag();
		sendUpdateStateData(tag);
		if (!tag.isEmpty()) {
			return new ClientboundBlockEntityDataPacket(worldPosition, -1, tag);
		}
		return null;
	}
	
	@Override
	public void onDataPacket(Connection connection, ClientboundBlockEntityDataPacket packet) {
		handleUpdateStateData(packet.getTag());
	}
	
	/**
	 * Data here will be send to the client side when the block is updated. The data is received in
	 * {@link UBlockEntity#handleUpdateStateData(CompoundNBT)}. To trigger an update call
	 * {@link World#notifyBlockUpdate(net.minecraft.util.math.BlockPos, BlockState, BlockState, int)} or
	 * {@link UBlockEntity#sendChangesToClient(int)}
	 *
	 * @param tag
	 */
	public void sendUpdateStateData(CompoundTag tag) {
	}
	
	/**
	 * The data from the block update is received here. The data is send from
	 * {@link UBlockEntity#sendUpdateStateData(CompoundNBT)}
	 *
	 * @param tag
	 */
	public void handleUpdateStateData(CompoundTag tag) {
	}
	
	/**
	 * Calls {@link UBlockEntity#sendChangesToClient(int)} with flag 2 (send changes to client)
	 */
	public void sendChangesToClient() {
		sendChangesToClient(2);
	}
	
	/**
	 * Triggers a block update to send the data from the server to the client. For flags see here:
	 * {@link World#setBlockState(net.minecraft.util.math.BlockPos, BlockState, int)}
	 *
	 * @param flags Are described above
	 */
	public void sendChangesToClient(int flags) {
		final var state = getBlockState();
		level.sendBlockUpdated(worldPosition, state, state, flags);
	}
	
}

@@ -730,24 +730,27 @@
 lic 
-CompoundTag save
+void saveAdditional
 (Com
@@ -777,16 +777,26 @@
 per.save
+Additional
 (tag);%0A%09
@@ -806,38 +806,24 @@
 veNBT(tag);%0A
-%09%09return tag;%0A
 %09%7D%0A%09%0A%09@Overr
@@ -932,18 +932,52 @@
  disk. T
-he
+o mark the block entity to save data
  %7B@link 
@@ -990,23 +990,16 @@
 anged()%7D
- method
  must be
@@ -1009,15 +1009,8 @@
 lled
- before
 .%0A%09 
@@ -1115,25 +1115,8 @@
 %09 *%0A
-%09 * @param state%0A
 %09 * 
@@ -1238,18 +1238,115 @@
 nk load%0A
-
 %09%0A
+%09// TODO save methods have changed. Some parts here might not work, Wait for some forge changes!%0A
 %09@Overri
@@ -2243,20 +2243,16 @@
 %09return 
-new 
 Clientbo
@@ -2279,31 +2279,20 @@
 cket
-(worldPosition, -1, tag
+.create(this
 );%0A%09

Add note to ublock entity