package client.renderer.blockmodel;

import java.util.ArrayList;
import java.util.List;

import client.renderer.texture.Sprite;
import common.collect.Lists;
import common.model.GuiPosition;
import common.util.Facing;

public record BakedModel(List<BakedQuad> getQuads, List<List<BakedQuad>> getFace, boolean isGui3d, Sprite getBaseTexture, GuiPosition getTransforms) implements IBakedModel {
	public List<BakedQuad> getFace(Facing face) {
		return this.getFace.get(face.ordinal());
	}

	public boolean isBuiltin() {
		return false;
	}

	public static class Builder {
		private final List<BakedQuad> quads;
		private final List<List<BakedQuad>> faces;
		private Sprite texture;
		private boolean gui3d;
		private GuiPosition transforms;

		public Builder(ModelBlock model) {
			this(model.isGui3d(), model.getTransform());
		}

		public Builder(IBakedModel model, Sprite texture) {
			this(model.isGui3d(), model.getTransforms());
			this.texture = model.getBaseTexture();

			for(Facing face : Facing.values()) {
				this.addFaceBreakingFours(model, texture, face);
			}

			this.addGeneralBreakingFours(model, texture);
		}

		private void addFaceBreakingFours(IBakedModel model, Sprite texture, Facing facing) {
			for(BakedQuad quad : model.getFace(facing)) {
				this.addFaceQuad(facing, new BreakingFour(quad, texture));
			}
		}

		private void addGeneralBreakingFours(IBakedModel model, Sprite texture) {
			for(BakedQuad quad : model.getQuads()) {
				this.addGeneralQuad(new BreakingFour(quad, texture));
			}
		}

		private Builder(boolean gui3d, GuiPosition transforms) {
			this.quads = Lists.<BakedQuad>newArrayList();
			this.faces = new ArrayList<List<BakedQuad>>(6);

			for(Facing face : Facing.values()) {
				this.faces.add(Lists.<BakedQuad>newArrayList());
			}

			this.gui3d = gui3d;
			this.transforms = transforms;
		}

		public BakedModel.Builder addFaceQuad(Facing face, BakedQuad quad) {
			this.faces.get(face.ordinal()).add(quad);
			return this;
		}

		public BakedModel.Builder addGeneralQuad(BakedQuad quad) {
			this.quads.add(quad);
			return this;
		}

		public BakedModel.Builder setTexture(Sprite texture) {
			this.texture = texture;
			return this;
		}

		public BakedModel makeBakedModel() {
			if(this.texture == null)
				throw new RuntimeException("Fehlende Basistextur");
			return new BakedModel(this.quads, this.faces, this.gui3d, this.texture, this.transforms);
		}
	}
}
