/*
 * 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 {
	/** A Dynamic Color theme with 2 source colors. */
	public class SchemeCmf : DynamicScheme {
		public SchemeCmf (Hct source_color_hct,
			bool is_dark,
			double contrast_level,
			SpecVersion spec_version = SpecVersion.SPEC_2026,
			Platform platform = DEFAULT_PLATFORM,
			Hct[]? source_color_hct_list = null) {
			Hct[] list = source_color_hct_list ?? new Hct[] { source_color_hct };
			Hct first = list[0];

			base (
			      source_color_hct,
			      list,
			      Variant.CMF,
			      is_dark,
			      contrast_level,
			      platform,
			      spec_version,
			      TonalPalette.from_hue_and_chroma (first.hue, first.chroma),
			      TonalPalette.from_hue_and_chroma (first.hue, first.chroma * 0.5),
			      get_tertiary_palette (list),
			      TonalPalette.from_hue_and_chroma (first.hue, first.chroma * 0.2),
			      TonalPalette.from_hue_and_chroma (first.hue, first.chroma * 0.2),
			      TonalPalette.from_hue_and_chroma (get_error_hue (first.hue, get_tertiary_palette (list).hue), Math.fmax (first.chroma, 50.0))
			);

			if (spec_version != SpecVersion.SPEC_2026) {
				GLib.error ("IllegalArgumentException: SchemeCmf can only be used with spec version 2026.");
			}
		}

		private static TonalPalette get_tertiary_palette (Hct[] source_color_hct_list) {
			Hct source_color_hct = source_color_hct_list[0];
			Hct secondary_source_color_hct = source_color_hct_list.length > 1 ? source_color_hct_list[1] : source_color_hct;
			if (source_color_hct.to_int () == secondary_source_color_hct.to_int ()) {
				return TonalPalette.from_hue_and_chroma (source_color_hct.hue, source_color_hct.chroma * 0.75);
			} else {
				return TonalPalette.from_hue_and_chroma (secondary_source_color_hct.hue, secondary_source_color_hct.chroma);
			}
		}

		private static double get_error_hue (double primary_hue, double tertiary_hue) {
			if (primary_hue <= 8) {
				return tertiary_hue <= 24 ? 28.0 : (tertiary_hue <= 32 ? 16.0 : 20.0);
			} else if (primary_hue <= 16) {
				return tertiary_hue <= 24 ? 32.0 : (tertiary_hue <= 32 ? 20.0 : 24.0);
			} else if (primary_hue <= 20) {
				return tertiary_hue <= 28 ? 32.0 : (tertiary_hue <= 32 ? 24.0 : 28.0);
			} else if (primary_hue <= 28) {
				return tertiary_hue <= 24 ? 32.0 : 16.0;
			} else if (primary_hue <= 32) {
				return tertiary_hue <= 20 ? 24.0 : (tertiary_hue <= 28 ? 16.0 : 20.0);
			} else if (primary_hue <= 40) {
				return (tertiary_hue > 20 && tertiary_hue <= 28) ? 16.0 : 24.0;
			} else if (primary_hue <= 152) {
				return (tertiary_hue > 24 && tertiary_hue <= 36) ? 20.0 : 32.0;
			} else if (primary_hue <= 272) {
				return (tertiary_hue > 20 && tertiary_hue <= 28) ? 16.0 : 24.0;
			} else {
				return (tertiary_hue > 12 && tertiary_hue <= 28) ? 32.0 : 16.0;
			}
		}
	}
}
