package speiger.src.coreengine.platform.graphics.api.sampler;

import java.util.Objects;
import java.util.Optional;

import speiger.src.coreengine.platform.graphics.api.sampler.states.BorderMode;
import speiger.src.coreengine.platform.graphics.api.sampler.states.SampleMode;

public record SamplerSettings(BorderMode wrapS, BorderMode wrapT, Optional<BorderMode> wrapR, SampleMode minSample, SampleMode magSample) {
	
	public SamplerSettings {
		Objects.requireNonNull(wrapS);
		Objects.requireNonNull(wrapT);
		Objects.requireNonNull(wrapR);
		Objects.requireNonNull(minSample);
		Objects.requireNonNull(magSample);
	}
	
	public static Builder builder() {
		return new Builder();
	}
	
	public static class Builder {
		BorderMode wrapS;
		BorderMode wrapT;
		BorderMode wrapR;
		SampleMode minSample;
		SampleMode magSample;
		
		public Builder wrap(BorderMode mode) {
			return wrap(mode, false);
		}
		
		public Builder wrap(BorderMode mode, boolean includeR) {
			wrapS = Objects.requireNonNull(mode);
			wrapT = Objects.requireNonNull(mode);
			if(includeR) {
				wrapR = Objects.requireNonNull(mode);
			}
			return this;
		}
		
		public Builder wrapS(BorderMode mode) {
			wrapS = Objects.requireNonNull(mode);
			return this;
		}
		
		public Builder wrapT(BorderMode mode) {
			wrapT = Objects.requireNonNull(mode);
			return this;
		}
		
		public Builder wrapR(BorderMode mode) {
			wrapR = mode;
			return this;
		}
		
		public Builder sampler(SampleMode mode) {
			minSample = Objects.requireNonNull(mode);
			if(mode != SampleMode.LINEAR && mode != SampleMode.NEAREST) throw new IllegalArgumentException("["+mode+"] is not supported in mag filter");
			magSample = Objects.requireNonNull(mode);
			return this;
		}
		
		public Builder minSample(SampleMode mode) {
			minSample = Objects.requireNonNull(mode);
			return this;
		}
		
		public Builder magSample(SampleMode mode) {
			if(mode != SampleMode.LINEAR && mode != SampleMode.NEAREST) throw new IllegalArgumentException("["+mode+"] is not supported in mag filter");
			magSample = Objects.requireNonNull(mode);
			return this;
		}
		
		public SamplerSettings build() {
			return new SamplerSettings(Objects.requireNonNull(wrapS, "X Wrap should be defined"), 
					Objects.requireNonNull(wrapT, "Y Wrap should be defined"), 
					Optional.ofNullable(wrapR), 
					Objects.requireNonNull(minSample, "Min Sample should be defined"),
					Objects.requireNonNull(magSample, "Mag Sample should be defined"));
		}
	}
}
