/*
 * Copyright 2014 Fraunhofer IGD
 *
 * 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.
 */

package main;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.util.Random;

import javax.swing.JPanel;

import colormaps.Colormap2D;
import de.fhg.igd.pcolor.PColor;
import de.fhg.igd.pcolor.colorspace.CS_sRGB;
import de.fhg.igd.pcolor.colorspace.ViewingConditions;
import de.fhg.igd.pcolor.util.ColorTools;

/**
 * Displays a scatterplot of perceptual color distance over color map distance.
 * @author Simon Thum
 * 	who shamelessly used as a template code from
 * @author Martin Steiger
 */
public class MismatchScatterplotPanel extends JPanel implements ColormapPanel
{
	private static final long serialVersionUID = 4842610449905121603L;

	private static ViewingConditions comparisonVc = ViewingConditions.sRGB_typical_envirnonment;

	private Colormap2D colormap;

	private int points = 10000;
	
	private boolean useLog;
	
	/**
	 * @param colormap the colormap for the points
	 * @param useLog use logarithmic scale
	 */
	public MismatchScatterplotPanel(Colormap2D colormap, boolean useLog)
	{
		this.colormap = colormap;
		this.useLog = useLog;
	}

	/**
	 * @param colormap the colormap for the points
	 */
	@Override
	public void setColormap(Colormap2D colormap)
	{
		this.colormap = colormap;
		repaint();
	}
	
	/**
	 * @param numPoints the number of points
	 */
	public void setPointNumber(int numPoints)
	{
		this.points = numPoints;
	}
	
	@Override
	protected void paintComponent(Graphics g1)
	{
		super.paintComponent(g1);
		Graphics2D g = (Graphics2D)g1;
		
		Random r = new Random(123456);
		int dia = 3;

		double maxX = getWidth() - dia;
		double maxY = getHeight() - dia;

		Object oldAAhint = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

		for (int i = 0; i < points; i++)
		{
			float ax = r.nextFloat();
			float ay = r.nextFloat();
			
			float bx = r.nextFloat();
			float by = r.nextFloat();
			
			// distance on color map - 0 to 1
			double mapdistance = Math.hypot(bx - ax, by - ay) / Math.sqrt(2.0);
			
			Color colorA = colormap.getColor(ax, ay);
			Color colorB = colormap.getColor(bx, by);
			
			// roughly 0-100
			double cdist = colorDiff(colorA, colorB) / 120f;
			
			g.setColor(new Color(0, 0, 0, 0.1f));
			int xCoord = (int)(maxX * mapdistance);
			int yCoord;
			if (useLog)
				yCoord = (int)((Math.log(cdist / mapdistance)/3)*maxY + (maxY/2));
			else
				yCoord = (int)(maxY * cdist);
			g.fillOval(xCoord, yCoord, dia, dia);
		}
		
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAAhint);
	}
	
	private PColor convert(Color color) {
		return PColor.create(CS_sRGB.instance, color.getColorComponents(new float[3]));
	}
	
	private double colorDiff(Color c1, Color c2) {
		return ColorTools.distance(convert(c1), convert(c2), comparisonVc);
	}

}

@@ -1241,16 +1241,167 @@
 Panel%0A%7B%0A
+%09private static final Color NORMAL_DOT_COLOR = new Color(0, 0, 0, 0.1f);%0A%0A%09private static final Color BORDERLINE_DOT_COLOR = new Color(1,0,0,0.5f);%0A%09%0A%0A
 %09private
@@ -1609,17 +1609,17 @@
 oints = 
-1
+5
 0000;%0A%09%0A
@@ -2771,16 +2771,19 @@
 - 0 to 1
+.41
 %0A%09%09%09doub
@@ -2831,25 +2831,8 @@
  ay)
- / Math.sqrt(2.0)
 ;%0A%09%09
@@ -2994,23 +2994,113 @@
 orB)
- / 120f;
+;%0A%09%09%09%0A%09%09%09// make less relevant dots red%0A%09%09%09if (cdist %3C 1.0 %7C%7C mapdistance == 0 %7C%7C mapdistance %3E 1.0f)
 %0A%09%09%09
-%0A%09%09
 %09g.s
@@ -3111,34 +3111,150 @@
 lor(
-new Color(0, 0, 0, 0.1f));
+BORDERLINE_DOT_COLOR);%0A%09%09%09else%0A%09%09%09%09g.setColor(NORMAL_DOT_COLOR);%0A%09%09%09%0A%09%09%09// normalize%0A%09%09%09cdist /= 120f;  %0A%09%09%09mapdistance /= Math.sqrt(2.0);%0A%09%09%09
 %0A%09%09%09

mark less relevant dots red