package speiger.src.coreengine.rendering.gui.layout.constraints;

import speiger.src.coreengine.rendering.gui.components.base.GuiComponent;
import speiger.src.coreengine.rendering.gui.layout.constraints.IConstraint.Target;

public class ConstraintContainer {
	private static final int CONSTRAINT_LENGTH = 4;
	IConstraint[] constraints = new IConstraint[CONSTRAINT_LENGTH]; 
	
	private ConstraintContainer() {}
	
	public void apply(GuiComponent owner, GuiComponent parent, ConstrainedContext context) {
		for(int i = 0;i<4;i++) {
			if(constraints[i] == null) continue;
			constraints[i].apply(owner, parent, Target.by(i), context);
		}
	}
	
	public void fetch(GuiComponent owner, GuiComponent parent, ConstrainedContext context) {
		for(int i = 2;i<CONSTRAINT_LENGTH;i++) {
			Target target = Target.by(i);
			if(constraints[i] == null) {
				context.addBound(target.get(owner), target.isXAxis());
				continue;
			}
			constraints[i].fetch(owner, parent, target, context);
		}
	}
	
	public static Builder builder() { return new Builder(); }
	public Builder copy() { return new Builder(this); }
	
	public static class Builder {
		ConstraintContainer container = new ConstraintContainer();
		
		private Builder() {}
		private Builder(ConstraintContainer container) {
			System.arraycopy(container.constraints, 0, this.container.constraints, 0, CONSTRAINT_LENGTH);
		}
		
		public Builder x(IConstraint value) { 
			container.constraints[Target.X.ordinal()] = value;
			return this;
		} 
		
		public Builder y(IConstraint value) { 
			container.constraints[Target.Y.ordinal()] = value;
			return this;
		} 
		
		public Builder width(IConstraint value) { 
			container.constraints[Target.WIDTH.ordinal()] = value;
			return this;
		} 
		
		public Builder height(IConstraint value) { 
			container.constraints[Target.HEIGHT.ordinal()] = value;
			return this;
		}
		
		public ConstraintContainer build() {
			var result = container;
			container = null;
			return result;
		}
	}
}
