/*
 * Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * ---------------------------------------------------------------------
 *
 * Portions of this file were modified and ported to Vala by Victor Vintorez in 2026.
 * These modifications are licensed under the European Union Public License (EUPL),
 * Version 1.2 or later. You may obtain a copy of the License at:
 * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
 */

using GLib;

namespace MaterialColorUtilities {
	/** Describes how to fulfill a tone delta pair constraint. */
	public enum DeltaConstraint {
		EXACT,
		NEARER,
		FARTHER
	}

	/**
	 * Documents a constraint between two DynamicColors, in which their tones must have a certain
	 * distance from each other.
	 *
	 * <p>Prefer a DynamicColor with a background, this is for special cases when designers want tonal
	 * distance, literally contrast, between two colors that don't have a background / foreground
	 * relationship or a contrast guarantee.
	 */
	public sealed class ToneDeltaPair : Object {
		/** The first role in a pair. */
		private DynamicColor role_a;

		/** The second role in a pair. */
		private DynamicColor role_b;

		/** Required difference between tones. Absolute value, negative values have undefined behavior. */
		private double delta;

		/** The relative relation between tones of roleA and roleB, as described above. */
		private TonePolarity polarity;

		/**
		 * Whether these two roles should stay on the same side of the "awkward zone" (T50-59). This is
		 * necessary for certain cases where one role has two backgrounds.
		 */
		private bool stay_together;

		/** How to fulfill the tone delta pair constraint. */
		private DeltaConstraint constraint;

		/**
		 * Documents a constraint in tone distance between two DynamicColors.
		 *
		 * The polarity is an adjective that describes "A", compared to "B".
		 *
		 * For instance, ToneDeltaPair(A, B, 15, TonePolarity.DARKER, stay_together) states that A's tone should be
		 * at least 15 darker than B's.
		 *
		 * 'relative_darker' and 'relative_lighter' describes the tone adjustment relative to the
		 * surface color trend (white in light mode; black in dark mode). For instance, ToneDeltaPair(A,
		 * B, 10, TonePolarity.RELATIVE_LIGHTER, true) states that A should be at least 10 lighter than B in
		 * light mode, and at least 10 darker than B in dark mode.
		 *
		 * @param role_a The first role in a pair.
		 * @param role_b The second role in a pair.
		 * @param delta Required difference between tones. Absolute value, negative values have undefined behavior.
		 * @param polarity The relative relation between tones of role_a and role_b, as described above.
		 * @param stay_together Whether these two roles should stay on the same side of the "awkward zone" (T50-59).
		 * @param constraint How to fulfill the tone delta pair constraint.
		 */
		public ToneDeltaPair(DynamicColor role_a,
			DynamicColor role_b,
			double delta,
			TonePolarity polarity,
			bool stay_together = true,
			DeltaConstraint constraint = DeltaConstraint.EXACT) {
			this.role_a = role_a;
			this.role_b = role_b;
			this.delta = delta;
			this.polarity = polarity;
			this.stay_together = stay_together;
			this.constraint = constraint;
		}

		public DynamicColor get_role_a() {
			return role_a;
		}

		public DynamicColor get_role_b() {
			return role_b;
		}

		public double get_delta() {
			return delta;
		}

		public TonePolarity get_polarity() {
			return polarity;
		}

		public bool get_stay_together() {
			return stay_together;
		}

		public DeltaConstraint get_constraint() {
			return constraint;
		}
	}
}
