package org.eclipse.stem.util.analysis.views;

/*******************************************************************************
 * Copyright (c) 2007 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

import java.util.ArrayList;
import java.util.List;

import org.eclipse.birt.chart.device.IDeviceRenderer;
import org.eclipse.birt.chart.exception.ChartException;
import org.eclipse.birt.chart.factory.Generator;
import org.eclipse.birt.chart.model.Chart;
import org.eclipse.birt.chart.model.ChartWithAxes;
import org.eclipse.birt.chart.model.attribute.AxisType;
import org.eclipse.birt.chart.model.attribute.Bounds;
import org.eclipse.birt.chart.model.attribute.ColorDefinition;
import org.eclipse.birt.chart.model.attribute.IntersectionType;
import org.eclipse.birt.chart.model.attribute.TickStyle;
import org.eclipse.birt.chart.model.attribute.impl.BoundsImpl;
import org.eclipse.birt.chart.model.attribute.impl.ColorDefinitionImpl;
import org.eclipse.birt.chart.model.component.Axis;
import org.eclipse.birt.chart.model.component.Series;
import org.eclipse.birt.chart.model.component.impl.SeriesImpl;
import org.eclipse.birt.chart.model.data.NumberDataSet;
import org.eclipse.birt.chart.model.data.SeriesDefinition;
import org.eclipse.birt.chart.model.data.impl.NumberDataElementImpl;
import org.eclipse.birt.chart.model.data.impl.NumberDataSetImpl;
import org.eclipse.birt.chart.model.data.impl.SeriesDefinitionImpl;
import org.eclipse.birt.chart.model.impl.ChartWithAxesImpl;
import org.eclipse.birt.chart.model.layout.Legend;
import org.eclipse.birt.chart.model.layout.Plot;
import org.eclipse.birt.chart.model.type.LineSeries;
import org.eclipse.birt.chart.model.type.ScatterSeries;
import org.eclipse.birt.chart.model.type.impl.ScatterSeriesImpl;
import org.eclipse.birt.chart.util.PluginSettings;
import org.eclipse.stem.util.analysis.Activator;
import org.eclipse.stem.util.analysis.PhaseSpaceCoordinate;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Widget;

/**
 * LyapunovComparisonCanvas is a subclass of {@link Canvas} suitable for chart
 * drawings.
 */
public class LyapunovTrajectoryCanvas extends Canvas {

	protected IDeviceRenderer idr = null;

	/**
	 * This is the {@link Chart} that plots the relative values.
	 */
	protected Chart cm = null;

	/**
	 * The control for this canvas
	 */
	private LyapunovControl control = null;

	/**
	 * These are the values that will be plotted in X
	 * 
	 */
	private final List<List<Double>> relativeValuesX = new ArrayList<List<Double>>();

	/**
	 * These are the values that will be plotted in Y
	 * 
	 */
	private final List<List<Double>> relativeValuesY = new ArrayList<List<Double>>();

	/**
	 * Chart generator instance (reference to a singleton)
	 */
	Generator gr;

	private final List<LineSeries> lineSeriesList = new ArrayList<LineSeries>();
	Axis yAxisPrimary;
	Axis xAxisPrimary;
	double maxX = -1.0;
	double maxY = -1.0;

	ColorDefinition[] lineColors = {    ColorDefinitionImpl.RED(),
										ColorDefinitionImpl.BLUE(), 
										ColorDefinitionImpl.ORANGE(),
										ColorDefinitionImpl.YELLOW(), 
										ColorDefinitionImpl.GREEN(),
										ColorDefinitionImpl.PINK(), 
										ColorDefinitionImpl.BLACK() };

	/**
	 * TODO eventually this should not be hard coded but should be based on the
	 * number of files being read in in the GUI
	 */
	private static final int NUM_TRAJECTORIES = 2;

	/**
	 * Label for Time access (TODO need to nls this)
	 */
	public static final String TIME_LABEL = "time";

	/**
	 * Label for line series Identifier (legend)
	 */
	public static final String RMS_LABEL = "I[A] vs I[B]";

	Image imgChart = null;
	
	/**
	 * Constructor.
	 * 
	 * @param parent
	 *            the SWT parent of the {@link Widget}
	 */
	public LyapunovTrajectoryCanvas(final Composite parent) {
		super(parent, SWT.DOUBLE_BUFFERED | SWT.BORDER);
		while (relativeValuesX.size() < NUM_TRAJECTORIES) {
			relativeValuesX.add(new ArrayList<Double>());
		}
		while (relativeValuesY.size() < NUM_TRAJECTORIES) {
			relativeValuesY.add(new ArrayList<Double>());
		}
		resetData();
		gr = Generator.instance();

		try {
			idr = PluginSettings.instance().getDevice("dv.SWT"); //$NON-NLS-1$			
		} catch (final ChartException pex) {
			Activator.logError("Problem initializing chart", pex); //$NON-NLS-1$
			return;
		}

		control = (LyapunovControl) parent;

		cm = createLyapunovTrajectoryChart(relativeValuesX, relativeValuesY,
				Messages.getString("PH.title")); //$NON-NLS-1$
		addPaintListener(new PaintListener() {
			public void paintControl(final PaintEvent pe) {

				final Composite source = (Composite) pe.getSource();
				final org.eclipse.swt.graphics.Rectangle d = source
						.getClientArea();

				if(imgChart != null) imgChart.dispose();
				imgChart = new Image(source.getDisplay(), d);
				
				idr.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT, new GC(
						imgChart));
				final Bounds bounds = BoundsImpl.create(d.x, d.y, d.width,
						d.height);
				bounds.scale(72d / idr.getDisplayServer().getDpiResolution());
				// BOUNDS MUST BE SPECIFIED IN POINTS

				try {
					gr.render(idr, gr.build(idr.getDisplayServer(), cm, bounds,
							null, null, null));
					pe.gc.drawImage(imgChart, d.x, d.y);
				} catch (final ChartException ce) {
					Activator.logError("Problem rendering chart", ce); //$NON-NLS-1$
				}

			} // paintControl
		} // PaintListener

		);

	} // LyapunovComparisonCanvas

	/**
	 * The method which gets the {@link LyapunovTrajectoryCanvas}' reports list,
	 * and draws it on the {@link LyapunovTrajectoryCanvas}.
	 * 
	 */
	public void draw() {
		// Has a relative value provider been provided?
		clearData();
		setColorDefs(lineSeriesList);

		// set up to autoscale
		maxX = -1.0;
		maxY = -1.0;

		for (int i = 0; i < NUM_TRAJECTORIES; i++) {

			final PhaseSpaceCoordinate[] trajectory = control.getPointValues(i);

			if (trajectory.length > 0) {

				for (int j = 0; j < trajectory.length; j++) {

					if (trajectory[j].getXValue() >= maxX) {
						maxX = trajectory[j].getXValue();
						xAxisPrimary.getScale().setMax(
								NumberDataElementImpl.create(maxX));
					}

					if (trajectory[j].getYValue() >= maxY) {
						maxY = trajectory[j].getYValue();
						yAxisPrimary.getScale().setMax(
								NumberDataElementImpl.create(maxY));
					}
				}

				for (int cycleNumber = 0; cycleNumber < trajectory.length; cycleNumber++) {
					this.relativeValuesX.get(i).add(
							new Double(trajectory[cycleNumber].getXValue()));
					this.relativeValuesY.get(i).add(
							new Double(trajectory[cycleNumber].getYValue()));
				} // for cycleNumber
			} else {
				resetData();
			}
		}// for NUM_TRAJECTORIES
		if (!this.isDisposed()) {
			redraw();
		}
	} // paintControl

	/**
	 * @param relativeValuesX
	 *            the <code>List</code> that will contain the relative X axis
	 *            values (0.0-1.0) to plot
	 * @param relativeValuesY
	 *            that will contain the relative Y axis values (0.0-1.0) to plot
	 * @param seriesIdentifier
	 *            the title of the graph
	 * @return a <code>Chart</code>
	 */
	@SuppressWarnings("deprecation")
	public final Chart createLyapunovTrajectoryChart(
			final List<List<Double>> relativeValuesX,
			final List<List<Double>> relativeValuesY,
			final String seriesIdentifier) {
		final ChartWithAxes retValue = ChartWithAxesImpl.create();

		// get the NLS default labels
		// defaultAxisLabel_X = Messages.getString("XAXISDEF.title");
		// defaultAxisLabel_Y = Messages.getString("YAXISDEF.title");
		String defaultAxisLabel_X = "S";
		String defaultAxisLabel_Y = "I";

		// Plot
		retValue.getBlock().setBackground(ColorDefinitionImpl.WHITE());
		final Plot p = retValue.getPlot();
		p.getClientArea().setBackground(
				ColorDefinitionImpl.create(255, 255, 225));

		// Title
		// cwaLine.getTitle( ).getLabel( ).getCaption( ).setValue( "Line Chart"
		// );//$NON-NLS-1$
		retValue.getTitle().setVisible(false);

		// Legend
		final Legend lg = retValue.getLegend();
		lg.setVisible(false);
		/*
		 * final LineAttributes lia = lg.getOutline();
		 * lg.getText().getFont().setSize(8);
		 * lia.setStyle(LineStyle.SOLID_LITERAL); lg.getInsets().set(10, 5, 0,
		 * 0); lg.getOutline().setVisible(false);
		 * lg.setAnchor(Anchor.NORTH_LITERAL);
		 * lg.setPosition(Position.BELOW_LITERAL);
		 */
		// cwaLine.getLegend( ).getText().getFont().setSize(16);;
		// cwaLine.getLegend( ).setVisible( true );
		// X-Axis
		xAxisPrimary = retValue.getPrimaryBaseAxes()[0];
		xAxisPrimary.setType(AxisType.LINEAR_LITERAL);
		xAxisPrimary.getMajorGrid().setTickStyle(TickStyle.BELOW_LITERAL);
		xAxisPrimary.getOrigin().setType(IntersectionType.VALUE_LITERAL);
		xAxisPrimary.getTitle().getCaption().getFont().setSize(8);
		String xAxisLabel = defaultAxisLabel_X;
		xAxisPrimary.getTitle().getCaption().setValue(xAxisLabel);
		xAxisPrimary.getTitle().setVisible(true);
		
		// Y-Axis
		yAxisPrimary = retValue.getPrimaryOrthogonalAxis(xAxisPrimary);
		yAxisPrimary.getMajorGrid().setTickStyle(TickStyle.LEFT_LITERAL);
		yAxisPrimary.getTitle().getCaption().getFont().setSize(8);
		String yAxisLabel = defaultAxisLabel_Y;
		yAxisPrimary.getTitle().getCaption().setValue(yAxisLabel);
		yAxisPrimary.getTitle().setVisible(true);

		final int MAXCOLORS = lineColors.length;
		// for all relative values lists
		// X must be same size as Y
		for (int i = 0; i < relativeValuesX.size(); i++) {
			final NumberDataSet orthoValuesX = NumberDataSetImpl.create(relativeValuesX.get(i));
			final NumberDataSet orthoValuesY = NumberDataSetImpl.create(relativeValuesY.get(i));

			// X-Series
			final Series lsx = SeriesImpl.create();
			//final LineSeries lsx = (ScatterSeries) ScatterSeriesImpl.create();
			// seCategory.setDataSet(orthoValuesX);
			lsx.setDataSet(orthoValuesX);

			// Y-Series
			final ScatterSeries lsy = (ScatterSeries) ScatterSeriesImpl.create();
			lsy.setDataSet(orthoValuesY);
			lsy.getLineAttributes().setVisible(true);

			int colorIndex = i % MAXCOLORS;
			lsy.getLineAttributes().setColor(lineColors[colorIndex]);
			// fix to bug 375126
			// The latest version of birt uses Palette colors by default. In order to set the color the way we want
			// we must first issue:
			lsy.setPaletteLineColor(false);
			lsy.setSeriesIdentifier(seriesIdentifier);
			
			lsy.getMarkers().clear();

			final SeriesDefinition sdX = SeriesDefinitionImpl.create();
			final SeriesDefinition sdY = SeriesDefinitionImpl.create();

			sdY.getSeriesPalette().update(-2);

			xAxisPrimary.getSeriesDefinitions().add(sdX);
			yAxisPrimary.getSeriesDefinitions().add(sdY);

			// sdX.getSeries().add(seCategory);
			sdX.getSeries().add(lsx);
			sdY.getSeries().add(lsy);

		}// FOR ALL DATA SETS

		xAxisPrimary.setCategoryAxis(false);
		xAxisPrimary.getScale().setMin(NumberDataElementImpl.create(0.0));
		xAxisPrimary.getScale().setMax(NumberDataElementImpl.create(1.0));
		xAxisPrimary.getScale().setStep(0.25);
		xAxisPrimary.getLabel().getCaption().getFont().setSize(9);

		yAxisPrimary.getScale().setMin(NumberDataElementImpl.create(0.0));
		yAxisPrimary.getScale().setMax(NumberDataElementImpl.create(1.0));
		yAxisPrimary.getScale().setStep(0.25);
		yAxisPrimary.getLabel().getCaption().getFont().setSize(9);

		return retValue;
	} // createPhaseSpaceLineChart

	/**
	 * Sets the colors for a n array of LineSeries all to blue TODO: eventually
	 * we need to pick some better colors and connect to a legend...
	 * 
	 * @param lsList
	 */
	public static void setColorDefs(final List<LineSeries> lsList) {
		// the default line color
		for (int i = 0; i < lsList.size(); i++) {
			ColorDefinition color = ColorDefinitionImpl.BLUE();
			// fix to bug 375126
			// The latest version of birt uses Palette colors by default. In order to set the color the way we want
			// we must first issue the following line
			lsList.get(i).setPaletteLineColor(false);
			lsList.get(i).getLineAttributes().setColor(color);
		}
		return;
	}// getColorDef

	/**
	 * Disposes the Color objects
	 */
	@Override
	public void dispose() {
		super.dispose();
	}

	/**
	 * reset
	 */
	public void reset() {
		resetData();
		redraw();
	}

	protected void resetData() {

		clearData();
		for (int i = 0; i < relativeValuesX.size(); i++) {
			relativeValuesX.get(i).add(new Double(1.0));
			relativeValuesY.get(i).add(new Double(0.0));
		}
	}

	private void clearData() {
		for (int i = 0; i < relativeValuesX.size(); i++) {
			relativeValuesX.get(i).clear();
			relativeValuesY.get(i).clear();
		}
	}
} // LyapunovComparisonCanvas
