<commit_before>/**
 * File: Color.java
 * License: The MIT License (MIT)
 *  
 *  Copyright (c) 2015 <NAME>
 *  
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to deal
 *  in the Software without restriction, including without limitation the rights
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 *  
 *  The above copyright notice and this permission notice shall be included in all
 *  copies or substantial portions of the Software.
 *  
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 *  SOFTWARE.
 */
package schermer.color;

import static schermer.Utility.clamp;
import static schermer.Utility.indexOfMax;
import static schermer.Utility.maxOf;
import static schermer.Utility.minOf;

import java.io.Serializable;
import java.util.regex.Pattern;

import schermer.UnreachableCodeException;
import schermer.math.Vector3f;


/**
 * The Color class is used to encapsulate a single color.
 * <p>
 * <b> Constructors: </b>
 * <p>
 * <p>
 * {@link Color#named(String)}: Constructs a color by looking up the given name
 * in a color database.
 * <p>
 * {@link Color#fromAwtColor(java.awt.Color)}: Constructs a color from a given
 * awt.Color instance.
 * <p>
 * {@link Color#parseRgbHex(int)}: Constructs a color from a 6-digit RGB hex
 * value string.
 * <p>
 * {@link Color#fromRgbHex(int)}: Constructs a color from a 6-digit RGB hex
 * value.
 * <p>
 * {@link Color#fromRgbOctet(int, int, int)}: Constructs a color from RGB values
 * in the range 0-255.
 * <p>
 * {@link Color#fromRgb(float, float, float)}: Constructs a color from RGB
 * proportions.
 * <p>
 * {@link Color#fromRgbPercent(int, int, int)}: Constructs a color from RGB
 * proportions as percents.
 * <p>
 * {@link Color#fromRgbVector(Vector3f)}: Construcs a color from an RGB
 * component vector.
 * <p>
 * {@link Color#fromHsv(float, float, float)}: Constructs a color from HSV
 * proportions.
 * <p>
 * {@link Color#fromHsvPercent(float, int, int)}: Constructs a color from HSV
 * proportions as percents.
 * <p>
 * {@link Color#fromHsl(float, float, float)}: Constructs a color from HSL
 * proportions.
 * <p>
 * {@link Color#fromHslPercent(float, int, int)}: Constructs a color from RSL
 * proportions as percents.
 * <p>
 * {@link Color#fromCmyk(float, float, float, float)}: Constructs a color from
 * CMYK proportions.
 * <p>
 * {@link Color#fromCmykPercent(int, int, int, int)}: Constructs a color from
 * CMYK proportions as percents.
 * 
 * @version 0.2.1 (12 June 2015)
 * @author <NAME>
 */
public class Color implements Serializable {

	// Constants =============================================================
	private static final long serialVersionUID = 20L;
	/** Regex pattern string for parsers. Matches a six-digit hex code. */
	public static final String COLOR_PATTERN = "#([0-9a-fA-F]{6})";

	private static final int COMPONENT_BIT_MASK = 0xFF;

	private static final int ENCODING_RED_OFFSET = 16;
	private static final int ENCODING_BLUE_OFFSET = 8;
	private static final int ENCODING_GREEN_OFFSET = 0;

	private static final int ENCODING_RED_BIT_MASK = COMPONENT_BIT_MASK << ENCODING_RED_OFFSET;
	private static final int ENCODING_BLUE_BIT_MASK = COMPONENT_BIT_MASK << ENCODING_BLUE_OFFSET;
	private static final int ENCODING_GREEN_BIT_MASK = COMPONENT_BIT_MASK << ENCODING_GREEN_OFFSET;
	private static final int ENCODING_RGB_BIT_MASK = ENCODING_RED_BIT_MASK | 
													 ENCODING_GREEN_BIT_MASK | 
													 ENCODING_BLUE_BIT_MASK;


	// Static Fields =========================================================
	private static ColorNameSource colorNameSource = null;
	private static String colorNameFile = ColorNameSource.DEFAULT_COLOR_NAME_FILE;


	// Fields ================================================================
	private int srgbEncoding;


	// Constructors ==========================================================
	/**
	 * Constructs a Color from its total internal state.
	 * 
	 * @param srgbaEncoding
	 *        the SRGB+A encoding of the color.
	 */
	private Color(int srgbaEncoding) {

		this.srgbEncoding = srgbaEncoding;
	}


	// Static Constructors ===================================================
	/**
	 * Constructs a Color by looking in a color name database.
	 * <commit_msg>FEATURE: Added HSL/RGB distance function constants.<commit_after>/**
 * File: Color.java
 * License: The MIT License (MIT)
 *  
 *  Copyright (c) 2015 <NAME>
 *  
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to deal
 *  in the Software without restriction, including without limitation the rights
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 *  
 *  The above copyright notice and this permission notice shall be included in all
 *  copies or substantial portions of the Software.
 *  
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 *  SOFTWARE.
 */
package schermer.color;

import static schermer.Utility.clamp;
import static schermer.Utility.indexOfMax;
import static schermer.Utility.maxOf;
import static schermer.Utility.minOf;

import java.io.Serializable;
import java.util.function.ToDoubleBiFunction;
import java.util.regex.Pattern;

import schermer.UnreachableCodeException;
import schermer.math.Vector3f;


/**
 * The Color class is used to encapsulate a single color.
 * <p>
 * <b> Constructors: </b>
 * <p>
 * <p>
 * {@link Color#named(String)}: Constructs a color by looking up the given name
 * in a color database.
 * <p>
 * {@link Color#fromAwtColor(java.awt.Color)}: Constructs a color from a given
 * awt.Color instance.
 * <p>
 * {@link Color#parseRgbHex(int)}: Constructs a color from a 6-digit RGB hex
 * value string.
 * <p>
 * {@link Color#fromRgbHex(int)}: Constructs a color from a 6-digit RGB hex
 * value.
 * <p>
 * {@link Color#fromRgbOctet(int, int, int)}: Constructs a color from RGB values
 * in the range 0-255.
 * <p>
 * {@link Color#fromRgb(float, float, float)}: Constructs a color from RGB
 * proportions.
 * <p>
 * {@link Color#fromRgbPercent(int, int, int)}: Constructs a color from RGB
 * proportions as percents.
 * <p>
 * {@link Color#fromRgbVector(Vector3f)}: Construcs a color from an RGB
 * component vector.
 * <p>
 * {@link Color#fromHsv(float, float, float)}: Constructs a color from HSV
 * proportions.
 * <p>
 * {@link Color#fromHsvPercent(float, int, int)}: Constructs a color from HSV
 * proportions as percents.
 * <p>
 * {@link Color#fromHsl(float, float, float)}: Constructs a color from HSL
 * proportions.
 * <p>
 * {@link Color#fromHslPercent(float, int, int)}: Constructs a color from RSL
 * proportions as percents.
 * <p>
 * {@link Color#fromCmyk(float, float, float, float)}: Constructs a color from
 * CMYK proportions.
 * <p>
 * {@link Color#fromCmykPercent(int, int, int, int)}: Constructs a color from
 * CMYK proportions as percents.
 * 
 * @version 0.2.1 (12 June 2015)
 * @author <NAME>
 */
public class Color implements Serializable {

	// Constants =============================================================
	private static final long serialVersionUID = 20L;
	/** Regex pattern string for parsers. Matches a six-digit hex code. */
	public static final String COLOR_PATTERN = "#([0-9a-fA-F]{6})";

	private static final int COMPONENT_BIT_MASK = 0xFF;

	private static final int ENCODING_RED_OFFSET = 16;
	private static final int ENCODING_BLUE_OFFSET = 8;
	private static final int ENCODING_GREEN_OFFSET = 0;

	private static final int ENCODING_RED_BIT_MASK = COMPONENT_BIT_MASK << ENCODING_RED_OFFSET;
	private static final int ENCODING_BLUE_BIT_MASK = COMPONENT_BIT_MASK << ENCODING_BLUE_OFFSET;
	private static final int ENCODING_GREEN_BIT_MASK = COMPONENT_BIT_MASK << ENCODING_GREEN_OFFSET;
	private static final int ENCODING_RGB_BIT_MASK = ENCODING_RED_BIT_MASK | 
													 ENCODING_GREEN_BIT_MASK | 
													 ENCODING_BLUE_BIT_MASK;

	/** Function for computing the distance between two colors in RGB space. */
	public static final ToDoubleBiFunction<Color, Color> RGB_DISTANCE_FUNCTION = (a, b) -> {
		return a.hslDistanceTo(b);
	};
	
	/** Function for computing the distance between two colors in HSL space. */
	public static final ToDoubleBiFunction<Color, Color> HSL_DISTANCE_FUNCTION = (a, b) -> {
		return a.hslDistanceTo(b);
	};
	
	// Static Fields =========================================================
	private static ColorNameSource colorNameSource = null;
	private static String colorNameFile = ColorNameSource.DEFAULT_COLOR_NAME_FILE;


	// Fields ================================================================
	private int srgbEncoding;


	// Constructors ==========================================================
	/**
	 * Constructs a Color from its total internal state.
	 * 
	 * @param srgbaEncoding
	 *        the SRGB+A encoding of the color.
	 */
	private Color(int srgbaEncoding) {

		this.srgbEncoding = srgbaEncoding;
	}


	// Static Constructors ===================================================
	/**
	 * Constructs a Color by looking in a color name database.
	 * 
{'fraction_non_alphanumeric': 0.14463331714424477, 'fraction_numerical': 0.006022340942204954, 'mean_word_length': 4.390575916230366, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3284128', 'n_tokens_mistral': 3274, 'n_tokens_neox': 3004, 'n_words': 1099}