/*******************************************************************************
 * This file is part of GECAMed.
 * 
 * GECAMed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (L-GPL) as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GECAMed is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License (L-GPL)
 * along with GECAMed.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * GECAMed is Copyrighted by the Centre de Recherche Public Henri Tudor (http://www.tudor.lu)
 * (c) CRP Henri Tudor, Luxembourg, 2008
 *******************************************************************************/
package lu.tudor.santec.gecamed.core.gui;

import static java.lang.Math.pow;

import java.awt.Color;

import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource;

//***************************************************************************
//* Class Definition and Members                                            *
//***************************************************************************

/**
 * @author Johannes Hermen johannes.hermen(at)tudor.lu
 *
 * static class that defines the colors used in the GECAMed client.
 * and overwrites some colors of the look and feel with own values
 *
 * @Version
 * <br>$Log$
 * <br>Revision 1.21  2014-01-16 15:49:02  ferring
 * <br>DSP Warning color is now darker
 * <br>
 * <br>Revision 1.20  2013-10-09 13:36:35  ferring
 * <br>eSanté icon changed and tree view initialised
 * <br>
 * <br>Revision 1.19  2010-12-30 15:08:15  ferring
 * <br>Red Colors are darker
 * <br>
 * <br>Revision 1.18  2009-03-06 17:15:18  mack
 * <br>Slight color change for green color of even rows. Have chosen a slightly darker shade
 * <br>
 * <br>Revision 1.17  2008-09-25 09:43:07  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.16  2008-07-04 13:08:31  mack
 * <br>Added Modified Title Color
 * <br>
 * <br>Revision 1.15  2008-04-16 14:24:28  heinemann
 * <br>*** empty log message ***
 * <br>
 * <br>Revision 1.14  2008-02-11 16:46:33  heinemann
 * <br>moved computeColor to GECAMedColors
 * <br>
 * <br>Revision 1.13  2008-01-18 16:09:43  heinemann
 * <br>added static method rgb2lab
 * <br>
 * <br>Revision 1.12  2008-01-15 09:29:39  hermen
 * <br>updated Javadoc and refactured code
 * <br>
 * <br>Revision 1.11  2007-12-03 10:59:02  hermen
 * <br>updated Javadoc
 * <br>
 *
 */
public class GECAMedColors 
{
	
//***************************************************************************
//* Class Constants                                                         *
//***************************************************************************

	public static final Color c_LabelColor = new Color(100, 100, 100);
	
	public static final Color c_OddLineBackground  = new Color (237,243,254);
//	public static final Color c_OddLineBackground  = new Color (215,238,255);
    
	public static final Color c_EvenLineBackground = new Color (255,255,255);
//	public static final Color c_EvenLineBackground = new Color (255,255,255);

	public static final Color c_OddLineSearchBackground  = new Color (217,223,234);
    
	public static final Color c_EvenLineSearchBackground = new Color (227,233,244);
	
	public static final Color c_InvalidFieldForeground = new Color (255,0,0);
    
    public static final Color c_InvalidFieldBackground = new Color (255,200,200);
    
    public static final Color c_WarnFieldForeground = new Color(255, 145, 0);
    
    public static final Color c_WarnFieldBackground = new Color(255, 255, 204);

    public static final Color c_ValidFieldForeground = new Color(2, 125, 80);
    
    public static final Color c_ValidFieldBackground = new Color(200, 240, 210);
	
//	public static final Color c_RedOddLineBackground = new Color (255,224,224);
	public static final Color c_RedOddLineBackground = new Color (255,200,200);
  	
//	public static final Color c_RedEvenLineBackground = new Color (255,240,240);
	public static final Color c_RedEvenLineBackground = new Color (255,224,224);
    
	public static final Color c_RedOddLineSearchBackground = new Color (235,204,204);
  	
	public static final Color c_RedEvenLineSearchBackground = new Color (235,220,220);
  	
	public static final Color c_GreenOddLineBackground = new Color (224,255,224);
    
    public static final Color c_GreenEvenLineBackground = new Color (235,255,235);
    
	public static final Color c_YellowOddLineBackground = new Color (243,171,43);
    
    public static final Color c_YellowEvenLineBackground = new Color (254,221,141);
    
    public static final Color c_ScrollPaneBackground = Color.WHITE;
    
    public static final Color c_GECAMedTitledBorder = Color.BLACK;

	public static final Color c_ModuleBorderColor = Color.red;
    
    public static final Color c_GECAMedBackground = new Color (237,243,254);
   
    public static final Color c_GECAMedDarkerBackground = new Color (202,220,252);
	
	public static final Color c_TabSelection = new Color (230,235,254);
	
	public static final Color c_ModifiedTitleBackground = Color.YELLOW;
	
	public static final Color c_ListSelectionBackground = new Color(169, 192, 219);

	public static final Color c_EvenGrayBackground = new Color(244, 244, 244);

	public static final Color c_OddGrayBackground = new Color(224, 224, 224);

	public static final Color c_WARNING = new Color(255, 150, 0);

	
		
	static {
		// ==============================================================================
		// we make the UI a bit nicer
		// adjustments on the look and feel
		//
		// ==============================================================================
		UIManager.put("TabbedPane.selected", c_TabSelection);
		UIManager.put("TabbedPane.contentAreaColor", c_TabSelection);

		UIManager.put("TabbedPane.unselectedBackground", c_ScrollPaneBackground);
		
		UIManager.put("TextField.inactiveBackground", new ColorUIResource(252,252,252));
		UIManager.put("TextField.inactiveForeground", new ColorUIResource(Color.BLACK));

		UIManager.put("FormattedTextField.inactiveBackground", new ColorUIResource(252,252,252));
		UIManager.put("FormattedTextField.inactiveForeground", new ColorUIResource(Color.BLACK));

		UIManager.put("ComboBox.disabledBackground", new ColorUIResource(252,252,252));
		UIManager.put("ComboBox.disabledForeground", new ColorUIResource(Color.BLACK));
		UIManager.put("ComboBox.background", new ColorUIResource(Color.WHITE));
		// ===============================================================================

		
//		// this is how to list all UI Defaults		
//		UIDefaults uiDefaults = UIManager.getDefaults();
//		Enumeration enume = uiDefaults.keys();
//		while (enume.hasMoreElements())
//		{
//		    Object key = enume.nextElement();
//		    Object val = uiDefaults.get(key);
//		    System.out.println("[" + key.toString() + "]:[" +
//		        (null != val ? val.toString() : "(null)") +
//		        "]");
//		} 
	}
	
	
	
	
	/**
	 * Convert RGB color to LAB color mode
	 * 
	 *
	 * @param red
	 * @param green
	 * @param blue
	 * @param lab
	 */
	public static void rgb2lab(int red, int green, int blue, int[] lab) {
		/* ================================================== */
		float Ls, as, bs;
		float k = 24389.f / 27.f;
		float eps = 216.f / 24389.f;
		float r, g, b, X, Y, Z, fx, fy, fz, xr, yr, zr;

		float refX = 0.964221f;
		float refY = 1.0f;
		float refZ = 0.825211f;

		// RGB -> XYZ
		r = red / 255.f; 
		g = green / 255.f; 
		b = blue / 255.f; 

		// assuming sRGB (D65)
		if (r <= 0.04045)
			r = r / 12;
		else
			r = (float) Math.pow((r + 0.055) / 1.055, 2.4);

		if (g <= 0.04045)
			g = g / 12;
		else
			g = (float) Math.pow((g + 0.055) / 1.055, 2.4);

		if (b <= 0.04045)
			b = b / 12;
		else
			b = (float) Math.pow((b + 0.055) / 1.055, 2.4);

		X = 0.436052025f * r + 0.385081593f * g + 0.143087414f * b;
		Y = 0.222491598f * r + 0.71688606f * g + 0.060621486f * b;
		Z = 0.013929122f * r + 0.097097002f * g + 0.71418547f * b;

		// XYZ to Lab
		xr = X / refX;
		yr = Y / refY;
		zr = Z / refZ;

		if (xr > eps)
			fx = (float) Math.pow(xr, 1 / 3.);
		else
			fx = (float) ((k * xr + 16.) / 116.);

		if (yr > eps)
			fy = (float) Math.pow(yr, 1 / 3.);
		else
			fy = (float) ((k * yr + 16.) / 116.);

		if (zr > eps)
			fz = (float) Math.pow(zr, 1 / 3.);
		else
			fz = (float) ((k * zr + 16.) / 116);

		Ls = (116 * fy) - 16;
		as = 500 * (fx - fy);
		bs = 200 * (fy - fz);

		lab[0] = (int) (2.55 * Ls + .5);
		lab[1] = (int) (as + .5);
		lab[2] = (int) (bs + .5);
		/* ================================================== */
	}
	
	
	
	/**
	 * Computes the color of the font. If the bg color is to dark, white is
	 * choosen, otherwise its black.
	 *
	 * @param bg
	 * @return
	 */
	public static Color computeForeground(Color bg) {
		/* ================================================== */
		if (bg == null) {
			return Color.WHITE;
		}
		// Δe = sqrt(pow(ΔL) + pow(Δa) + pow(Δb))
		//
		// a well trained human can detect colors that have a Δe=2
		// so we must choose a Δe that fits the capability of John Doe
		// ============================================================
		// first we must convert the RGB colors to LAB

		// LAB of white
		int[] labWhite = new int[3];
		int[] labBlack = new int[3];
		int[] labBg = new int[3];
		/* ------------------------------------------------------- */
		// lab of white
		GECAMedColors.rgb2lab(Color.WHITE.getRed(), Color.WHITE.getGreen(), Color.WHITE
				.getBlue(), labWhite);
		// lab of black
		GECAMedColors.rgb2lab(Color.BLACK.getRed(), Color.BLACK.getGreen(), Color.BLACK
				.getBlue(), labBlack);
		// lab of bg
		GECAMedColors.rgb2lab(bg.getRed(), bg.getGreen(), bg.getBlue(), labBg);
		/* ------------------------------------------------------- */

		int deltaBgWhite = deltaE(labBg, labWhite);
		int deltaBgBlack = deltaE(labBg, labBlack);

		// choose the biggest deltaE
		if (deltaBgBlack > deltaBgWhite)
			return Color.BLACK;
		
		return Color.WHITE;
		/* ================================================== */
	}

	private static int deltaE(int[] lab1, int[] lab2) {
		/* ================================================== */
		int deltaE = 0;

		double deltaL = lab2[0] - lab1[0];
		double deltaA = lab2[1] - lab1[1];
		double deltaB = lab2[2] - lab1[2];

		deltaE = (int) Math.sqrt(pow(deltaL, 2.0) + pow(deltaA, 2.0)
				+ pow(deltaB, 2.0));

		return deltaE;
		/* ================================================== */
	}
	
	
//***************************************************************************
//* End of Class                                                            *
//***************************************************************************
	
}
