/*
 * Created on Nov 15, 2006
 *
 * various ways of viewing EDL files
 * 
 */
package com.meapsoft.visualizer;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;

import com.meapsoft.EDLFile;
import com.meapsoft.FeatFile;


/**
 * @author douglas repetto
 *
 */

public class LineGraphRenderer extends Renderer
{		
	JComboBox sOptions;
	JCheckBox connectOption;
	boolean connect;
	
	double currXMulti = 0.0;
	double currHeight = 0.0;
	
	public LineGraphRenderer(FeatFile featFile, EDLFile eDLFile)
	{
		super(featFile, eDLFile, "LineGraph");
	}

	public LineGraphRenderer(Renderer r)
	{
		super(r);
		//have to do this so we're not stuck with invalid
		//multipliers from another renderer
		updateColorMultipliers();
	}

	public void draw(Graphics graphics, int width, int height)
	{	
		//System.out.println("width: " + width + " height: " + height);
		//height *= .5;
		int numChunks = events.size();
		
		//set up scaling factors
		ChunkVisInfo lastChunk = (ChunkVisInfo) events.elementAt(numChunks - 1);
		double xMulti = width/(lastStartTime + lastChunk.length);
		 
		graphics.setColor(Color.white);
		graphics.fillRect(0,0,width,height);
		
		Point[][] previousPoints = new Point[numChunks][numFeatures];
		
		int colorMulti = numColors/numFeatures;
		
		for (int i = 0; i < numChunks; i++)
		{
			ChunkVisInfo cVI = (ChunkVisInfo) events.elementAt(i);
			
			int[] featNum = {0};
			
			for (int j = 0; j < numFeatures; j++)
			{
				double features[] = cVI.getFeatures(featNum);
				double featureValue = features[0] - lowestFeatureValue[j];

				featNum[0] += elementsPerFeature[j];

				//double colorIndex = featureValue * colorMultipliers[j];
				
				int colorIndex = j * colorMulti;
				
				
				Color featureColor = colormap.table[(int)colorIndex];
				
				if (!cVI.selected)
					featureColor = featureColor.darker().darker().darker();
				
				graphics.setColor(featureColor);
				
				int blobSize = (int)Math.round(width/numChunks) - 2;
				if (blobSize <= 1)
					blobSize = 2;
					
				double yMulti = (height - blobSize)/(highestFeatureValue[j] - lowestFeatureValue[j]);

				//draw feats
				int x = (int)(Math.round(cVI.startTime * xMulti));
				//or draw EDL
				if (sOptions.getSelectedIndex() == 1)
					x = (int)(Math.round(cVI.dstTime * xMulti));
				int y = (int)(Math.round(featureValue * yMulti));
				
				graphics.fillOval(x, y, blobSize, blobSize);
				
				if (i > 0 && connectOption.isSelected())
				{
					Point pP = previousPoints[i-1][j];
					if (pP != null)
					{
						int pX = pP.x + (blobSize/2);
						int pY = pP.y + (blobSize/2);
						graphics.setColor(featureColor.brighter());
						graphics.drawLine(x + (blobSize/2), y + (blobSize/2), pX, pY);
					}
				}
				previousPoints[i][j] = new Point(x, y);
				
				//record our position
				if (j == 0)
				{
					cVI.xFeat = x;
					cVI.yFeat = y;
					cVI.width = blobSize;
					cVI.height = blobSize;
				}
			}
		}
		
		currHeight = height;
		
		if (dragRect != null)
		{
			graphics.setColor(Color.black);
			graphics.drawRect(dragRect.x, dragRect.y, dragRect.width, dragRect.height);
		}
	}

		
	public Vector getChunkVisInfosForPoint(Point p)
	{	
		Vector chunks = new Vector();
		
		for (int i = 0; i < events.size(); i++)
		{
			ChunkVisInfo c = (ChunkVisInfo) events.elementAt(i);

			if (p.x >= c.xFeat && p.x <= (c.xFeat + c.width))
			{
				//if (p.y >= c.yFeat && p.y <= (c.yFeat + c.height))
				//{
					chunks.add(c);
				//}
			}
		}

		return chunks;
	}
		
	public int getFeatureNumberForPoint(Point p)
	{
		int featureNumber = -1;
		
		if (featFile != null)
		{
			for (int i = 0; i < events.size(); i++)
			{
				ChunkVisInfo cVI = (ChunkVisInfo) events.elementAt(i);

				if (p.x >= cVI.xFeat && p.x <= (cVI.xFeat + cVI.width))
				{
					int[] featNum = {0};
		
					for (int j = 0; j < numFeatures; j++)
					{
						double features[] = cVI.getFeatures(featNum);
						double featureValue = features[0] - lowestFeatureValue[j];

						featNum[0] += elementsPerFeature[j];

						double yMulti = currHeight/(highestFeatureValue[j] - lowestFeatureValue[j]);
						int y = (int)(Math.round(featureValue * yMulti));
						
						if (p.y >= y && p.y <= y + cVI.height)
							featureNumber = j;
					}
				}
			}
		}
		
		return featureNumber;
	}
	
	public String getFeatureNameForPoint(Point p)
	{
		String featureName = "i don't know!";
		
		int whichFeature = getFeatureNumberForPoint(p);
		
		if (whichFeature != -1)
		{
			String fullFeatureName = (String) featFile.featureDescriptions.elementAt(whichFeature);
			//we're splitting on "." but have to use an escape sequence!
			String[] chunks = fullFeatureName.split("\\.");
			featureName = chunks[chunks.length-1];
		}
			
		return featureName;	
	}

	public double getFeatureValueForPoint(Point p)
	{
		double value = 0.0;
		
		int whichFeature = getFeatureNumberForPoint(p);
		
		if (whichFeature != -1)
		{
			for (int i = 0; i < events.size(); i++)
			{
				ChunkVisInfo cVI = (ChunkVisInfo) events.elementAt(i);
					
				if (p.x >= cVI.xFeat && p.x <= (cVI.xFeat + cVI.width))
				{
					if (p.y >= cVI.yFeat && p.y <= (cVI.yFeat + cVI.height))
					{
						int[] featNum = {0};
					
						for (int j = 0; j < whichFeature; j++)
							featNum[0] += elementsPerFeature[j];
						value = cVI.getFeatures(featNum)[0];
						return value;
					}
				}
			}
		}
		
		return value;
	}
	
	public void rangeFilterSelectionChanged()
	{
	}
	
	public void setDragRect(Rectangle r, boolean dS)
	{
		dragRect = r;
		dragShift = dS;
		
		if (!dragShift)
		{
			selectNone();
		}
		
		for (int i = 0; i < events.size(); i++)
		{
			ChunkVisInfo cVI = (ChunkVisInfo)events.elementAt(i);
			Rectangle chunkRect = null;
			
			//if (sOptions.getSelectedIndex() == 0)
			//{
				chunkRect = new Rectangle(cVI.xFeat, cVI.yFeat, cVI.width, cVI.height);
			//}
			//else
			//{
			//	chunkRect = new Rectangle(cVI.xEDL, cVI.yEDL, cVI.width, cVI.height);
			//}
			if ((dragRect.x >= chunkRect.x && 
				dragRect.x <= chunkRect.x + chunkRect.width) ||
				(dragRect.x + dragRect.width >= chunkRect.x && 
				dragRect.x + dragRect.width <= chunkRect.x + chunkRect.width) ||
				(dragRect.x <= chunkRect.x && 
				dragRect.x + dragRect.width >= chunkRect.x + chunkRect.width))
				cVI.selected = true;
		}
		
		dragRect = null;
		dragShift = false;
		
		drawingPanel.repaint();	
	}
	/*
	public void actionPerformed(ActionEvent arg0)
	{		
		Object source = arg0.getSource();
		String command = arg0.getActionCommand();
		
		super.actionPerformed(arg0);
	}
	*/
	public JPanel buildGUI(Color bgColor)
	{
		
		JPanel panel = super.buildGUI(bgColor);
		
		JPanel cSPanel = new JPanel();
		cSPanel.setBackground(bgColor);
		cSPanel.setLayout(new BoxLayout(cSPanel, BoxLayout.Y_AXIS));
		
		connectOption = new JCheckBox("connect dots");
		connectOption.setBackground(bgColor);
		connectOption.setActionCommand("connect");
		connectOption.addActionListener(this);
		
		cSPanel.add(connectOption);

		JLabel sCL = new JLabel("show: ");
		sCL.setBackground(bgColor);
		cSPanel.add(sCL);
		
		String[] showOptions = {"feat file", "EDL file"};
		
		sOptions = new JComboBox(showOptions);
		sOptions.setBackground(bgColor);
		sOptions.setActionCommand("sOptions");
		sOptions.addActionListener(this);
		cSPanel.add(sOptions);
		
		controlsPanel.add(cSPanel);
		
		return panel;
	}


}



