package org.eclipse.stem.ui.reports.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.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

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.Anchor;
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.JavaNumberFormatSpecifier;
import org.eclipse.birt.chart.model.attribute.LineAttributes;
import org.eclipse.birt.chart.model.attribute.LineStyle;
import org.eclipse.birt.chart.model.attribute.Marker;
import org.eclipse.birt.chart.model.attribute.NumberFormatSpecifier;
import org.eclipse.birt.chart.model.attribute.Position;
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.attribute.impl.JavaNumberFormatSpecifierImpl;
import org.eclipse.birt.chart.model.attribute.impl.NumberFormatSpecifierImpl;
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.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.ItemPropertyDescriptor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.stem.core.model.Decorator;
import org.eclipse.stem.core.model.STEMTime;
import org.eclipse.stem.definitions.adapters.relativevalue.history.RelativeValueHistoryProvider;
import org.eclipse.stem.definitions.adapters.relativevalue.history.RelativeValueHistoryProviderAdapter;
import org.eclipse.stem.jobs.simulation.ISimulation;
import org.eclipse.stem.ui.preferences.VisualizationPreferencePage;
import org.eclipse.stem.ui.reports.Activator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
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.Menu;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IWorkbenchActionConstants;

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

	protected IDeviceRenderer idr = null;

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

	/**
	 * The provider of relative values.
	 */
	private RelativeValueHistoryProvider rvhp;

	private ReportControl control = null;
	
	/**
	 * some extra colors
	 */
	protected static final ColorDefinition[] colorDefault = {
															ColorDefinitionImpl.BLUE(), 
															ColorDefinitionImpl.BLACK(), 
															ColorDefinitionImpl.GREY(),
															ColorDefinitionImpl.CYAN(),
															ColorDefinitionImpl.ORANGE() 
															};
	
	/**
	 * used to index the line series so we can step through default colors
	 * when a user custom color is not yet assigned
	 */
	protected int seriesCount  = 0;

	/**
	 * Log of zero is negative infinity so for each location we will cut off the minimum value
	 * of log(y) at 0.1/POPULATION for display purposes only
	 */
	private double minLogScaleValue = 1.0;
	
	/**
	 * once time > DEFAULT_AUTOAXIS_THRESHOLD we start to autoreset the time axis 
	 * tick marks and scale so we don't have too many tick marks
	 */
	private static final int DEFAULT_AUTOAXIS_THRESHOLD = 5;
	
	/**
	 * the max value for the time (x) axis
	 */
	private int maxTimeAxisValue = DEFAULT_AUTOAXIS_THRESHOLD;
	
	/**
	 * the minimum number of time axis ticks 
	 */
	private static final int MIN_TICKS = 5;
	
	/**
	 * the maximum number of time axis ticks  after time=DEFAULT_AUTOAXIS_THRESHOLD;
	 */
	private static final int MAX_TICKS = 10;
	
	/**
	 * used to set the autoaxis tick
	 */
	private static final int TICK_TRIGGER = MAX_TICKS/MIN_TICKS;

	/**
	 * This is a map of properties of the label updated by the selected
	 * {@link Decorator} whose relative value might be plotted (context menu allows us to toggle the individual
	 * properties to plot
	 */
	protected Map<ItemPropertyDescriptor,Boolean> propertiesToPlot = new HashMap<ItemPropertyDescriptor,Boolean>();

	/**
	 * TODO this is temporary code and should be in user preferences
	 * we want to hide a few of the possible line-series on start up
	 */
	private static final String[] HIDE_ON_STARTUP = {"IR","IF","Incidence","Births","Deaths","Population Count", "Disease Deaths"};
	private static final Set<String> defaultHideSet = new HashSet<String>();

	/**
	 * this is a map of the DataSeries object (keyed by property name)
	 */
	protected final Map<String,DataSeries> dataSeriesMap = new HashMap<String,DataSeries>();
	
	
	/**
	 * These are the cycle numbers that match the relative values that will be
	 * plotted
	 *
	 * @see #relativeValues
	 */
	private final List<Integer> cycleNumbers = new ArrayList<Integer>();

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

	
	Axis yAxisPrimary;
	Axis xAxisPrimary;

	
	/**
	 * A context menu for this view
	 */
	Menu popUpMenu = null;
	
	// Init a Context Menu Manager
	final MenuManager contextMenuManager = new MenuManager();

	/**
	 * set y axis to a linear scale
	 */
	private LinearScaleAction linearTimeAction;
	/**
	 * set y axis to a log scale
	 */
	private LogScaleAction logTimeAction;
	protected boolean useLinearTimeScale = true;
	
	/**
	 * show the legend (true by default)
	 */
	private LegendViewAction viewLegend;

	/**
	 * Clear the properties from the time series
	 */
	
	private ClearAction clearAction;
	
	List<DisplayableProperty> displayableProperties;
	
	/**
	 * hide the legend 
	 */
	private LegendHideAction hideLegend;
	protected boolean showLegend = true;
	
	protected Legend legend = null;
	
	private static final String defaultKey = "";

	Image imgChart = null;
	
	/**
	 * Constructor.
	 *
	 * @param parent
	 *            the SWT parent of the {@link Widget}
	 */
	public TimeSeriesCanvas(final Composite parent) {
		super(parent, SWT.DOUBLE_BUFFERED | SWT.BORDER);
		
		// init
	 	for (int i = 0; i < HIDE_ON_STARTUP.length; i ++) {
	 		defaultHideSet.add(HIDE_ON_STARTUP[i]);
	 	}
	

		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 = (ReportControl) parent;
		rvhp = control.rvhp;
		
		cm = createSimpleLineChart(dataSeriesMap, cycleNumbers, Messages
				.getString("CC.title")); //$NON-NLS-1$
		resetData();
		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

		);

		//Create a context menu for the canvas
		createContextMenu(this);

	} // TimeSeriesCanvas

	/**
	 * The method which gets the {@link TimeSeriesCanvas}' reports list, and
	 * draws it on the {@link TimeSeriesCanvas}.
	 *
	 */
	public synchronized void draw() {

		
		// Has a relative value provider been provided?
		if (rvhp != null) {
			double maxY = Double.MIN_VALUE;
			double minY = Double.MAX_VALUE;

			// Yes
			// build up the set of properties to plot
			
			// First we disable all series so that we only turn on the ones that are enabled.
			for(DataSeries d: dataSeriesMap.values())
				d.hide();
					
			List<ItemPropertyDescriptor> itemList = new ArrayList<ItemPropertyDescriptor>();
			itemList.addAll(propertiesToPlot.keySet());		
			Collections.sort(itemList, new Comparator<ItemPropertyDescriptor>() {

				public int compare(ItemPropertyDescriptor o1,
						ItemPropertyDescriptor o2) {
					return o1.getDisplayName(o1).compareTo(o2.getDisplayName(o2));
				}
			});
				
			
			List<ItemPropertyDescriptor> displayedPropertyList = new ArrayList<ItemPropertyDescriptor>();
			for(ItemPropertyDescriptor property: itemList){
				boolean visible = propertiesToPlot.get(property).booleanValue();
				displayedPropertyList.add(property);
				if(visible) {
					if(dataSeriesMap.containsKey(property.getDisplayName(property))) {
						DataSeries series = dataSeriesMap.get(property.getDisplayName(property));
						// remove it
						if(!series.isVisible()) {
							series.show();
						}
					}
				} else {
					if(dataSeriesMap.containsKey(property.getDisplayName(property))) {
						DataSeries series = dataSeriesMap.get(property.getDisplayName(property));
						// remove it
						if(series.isVisible()) {
							series.hide();
						}
					}
				}// visible?
			}// all displayedProperties


			/////////////////////////////////////////////////////////////
			// Log(0.0) is negative infinity so for display purposes only
			// we set the minimum axis value at 0.1/POPULATION
			double denom = rvhp.getDenominator(null);
			if(denom <=0.0) denom = 1.0;
			minLogScaleValue = 0.1/denom;
			/////////////////////////////////////////////////////////////

			// clear
			resetData();
			
			
			
			boolean setCycles = false;
			// Get the values for the property to be plotted
			int maxPoints = 0;
			STEMTime[] time = rvhp.getAllHistoricTimeValues();
			cycleNumbers.clear();
			cycleNumbers.add(Integer.valueOf(0));
			
			
			for (int i = 0; i < displayedPropertyList.size(); i++) {
				ItemPropertyDescriptor property = displayedPropertyList.get(i);
				String propertyName = property.getDisplayName(property);
				
				//TESTING
				//System.out.println("looking for "+property.getDisplayName(property));
				final double[] doubleValues = rvhp.getHistoricInstances(property,time);

				// Any values?
				if (doubleValues.length > 0) {
					if (maxPoints < doubleValues.length) {
						maxPoints = doubleValues.length;
					}

					// this might be a new display
					// so we have to fill any empty data set
					if (!dataSeriesMap.containsKey(property.getDisplayName(property))) {
						
						DataSeries series = new DataSeries(propertyName, seriesCount);
						// we are out of data (properties) so we need to fill in
						// zeros for any unused lines
						// fill in the empty arrays
						if(doubleValues.length < maxPoints) {
							for(int ii = doubleValues.length; ii < maxPoints-1; ii ++) {
								// pad with zeros
								series.addValue(new Double(0.0));
							}
						}
						
						dataSeriesMap.put(propertyName, series);
					}

					
					final int earliestCycleNumber = rvhp.getEarliestCycleNumber();
					DataSeries series = dataSeriesMap.get(property.getDisplayName(property));
					series.setColorDefs(property.getDisplayName(property));
					
					
					for (int cycleNumber = 0; cycleNumber < doubleValues.length; cycleNumber++) {
						Double value;
						double displayValue = doubleValues[cycleNumber];
						if (displayValue <= minLogScaleValue && !useLinearTimeScale) {
							// Log(0.0) is negative infinity so for display purposes only
							// we set the minimum axis value at 0.1/POPULATION
							displayValue = minLogScaleValue;
						}
						if (useLinearTimeScale) {
							value = new Double(displayValue);
						} else {
							value = new Double(Math.log(displayValue));
						}
						if(maxY < displayValue && series.isVisible()) {
							maxY = displayValue;
						}
						
						if(minY > displayValue && series.isVisible()) {
							minY = displayValue;
						}
					
						series.addValue(value);
						
						if (!setCycles) {
							this.cycleNumbers.add(Integer.valueOf(
									earliestCycleNumber + cycleNumber + 1));
							
							/*
							 * We don't want to add x (time) axis ticks ad infinitum so we we need to dynamically
							 * change the scale. This will toggle between 5-10 ticks every time the max time doubles
							 * past an initial value of maxTimeAxisValue = DEFAULT_AUTOAXIS_THRESHOLD (= 25)
							 */
							if(this.cycleNumbers.size()>TICK_TRIGGER*maxTimeAxisValue) {
								maxTimeAxisValue = this.cycleNumbers.size()+1 ;
								int stepX = maxTimeAxisValue / MIN_TICKS;
								xAxisPrimary.getScale().setStep(stepX);
							}
						}
						
						
					} // for cycleNumber
					//Activator.logInformation("  "+series.propertyName+"cycles = "+this.cycleNumbers.size()+" datasize = "+series.getDataSize());
					setCycles = true; // we set them only once
				} else {
					resetData();
				}

				
			} // for i properties


			// Set the new min/max but only for linear scale
			if(useLinearTimeScale) {
				if(maxY == Double.MIN_VALUE) {
					// No plots
					yAxisPrimary.getScale().setMax(NumberDataElementImpl.create(1.0));
					yAxisPrimary.getScale().setMin(NumberDataElementImpl.create(0.0));
					yAxisPrimary.getScale().setStep(0.25);
					setYAxisNumberFormatFromMaxY(1.0);
				} else if(maxY-minY != 0.0) {
					yAxisPrimary.getScale().setMax(NumberDataElementImpl.create(maxY));
					yAxisPrimary.getScale().setMin(NumberDataElementImpl.create(0.0));
					yAxisPrimary.getScale().setStep((maxY-minY)/MIN_TICKS);
					setYAxisNumberFormatFromMaxY(maxY);
 				} else if(maxY == minY && maxY > 0.0) {
					yAxisPrimary.getScale().setMax(NumberDataElementImpl.create(maxY));
					yAxisPrimary.getScale().setMin(NumberDataElementImpl.create(0.0));
					yAxisPrimary.getScale().setStep((maxY)/MIN_TICKS);
					setYAxisNumberFormatFromMaxY(maxY);
				} else {
					yAxisPrimary.getScale().setMax(NumberDataElementImpl.create(1.0));
					yAxisPrimary.getScale().setMin(NumberDataElementImpl.create(0.0));
					yAxisPrimary.getScale().setStep(0.25);
					setYAxisNumberFormatFromMaxY(1.0);
				}
			} else setYAxisLogNumberFormat();
			
		} // if a relative value provider has been provided
		else {
			// No
			// Need to clear everything
			resetData();
		}

		// Check each data series in the map to make sure they have enough Y values in them 
		for(DataSeries ds:this.dataSeriesMap.values()) {
			if(ds.relativeValues.size() < this.cycleNumbers.size()) {
				ds.relativeValues.clear();
				for(int n=0;n<this.cycleNumbers.size();++n) ds.addValue(new Double(0.0));
			}
		}
		
		if (!this.isDisposed()) {
			redraw();
		}
	} // paintControl

	private void setYAxisLogNumberFormat() {
		NumberFormatSpecifier jnfs = null;
		jnfs = NumberFormatSpecifierImpl.create();
		yAxisPrimary.setFormatSpecifier(jnfs);
	}

	/**
	 * Create the view's context menu and add the action handlers to it.
	 */
	private void createContextMenu(final Composite parent) {

		

		// ---------------------------------------------------------------------
		linearTimeAction = new LinearScaleAction();
		logTimeAction = new LogScaleAction();
		contextMenuManager.add(linearTimeAction);
		contextMenuManager.add(logTimeAction);
		// Place Holder for Menu Additions
		contextMenuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
		// ---------------------------------------------------------------------
		viewLegend = new LegendViewAction();
		hideLegend = new LegendHideAction();
		contextMenuManager.add(viewLegend);
		contextMenuManager.add(hideLegend);
		// ---------------------------------------------------------------------
		// Place Holder for Menu Additions
		contextMenuManager.add(new Separator(
				IWorkbenchActionConstants.MB_ADDITIONS));
		popUpMenu = contextMenuManager.createContextMenu(parent);
		// Set the context menu for the viewer
		parent.setMenu(popUpMenu);

	} // createContextMenu


	/**
	 * Update the view's context menu and add the action handlers to it.
	 */
	private void updateContextMenu(final Composite parent) {

		popUpMenu.dispose();
		
		// Init a Context Menu Manager
	
		contextMenuManager.removeAll();
		// ---------------------------------------------------------------------
		if(linearTimeAction==null) linearTimeAction = new LinearScaleAction();
		if(logTimeAction==null) logTimeAction = new LogScaleAction();
		contextMenuManager.add(linearTimeAction);
		contextMenuManager.add(logTimeAction);
		contextMenuManager.update();
		
		// ---------------------------------------------------------------------
		// Place Holder for Menu Additions
		contextMenuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
		// ---------------------------------------------------------------------
		viewLegend = new LegendViewAction();
		hideLegend = new LegendHideAction();
		contextMenuManager.add(viewLegend);
		contextMenuManager.add(hideLegend);
		// ---------------------------------------------------------------------
		// Place Holder for Menu Additions
		contextMenuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
		// ---------------------------------------------------------------------
		// add the displayable properties
		if(displayableProperties == null) {
			displayableProperties = new ArrayList<DisplayableProperty>();
		}
		else {
			displayableProperties.clear();
		}
		if(rvhp!= null) {
					//List<IItemPropertyDescriptor>  properties = rvhp.getProperties();
					contextMenuManager.update();
					Iterator<ItemPropertyDescriptor> iter = propertiesToPlot.keySet().iterator();
					
					//for(int i = 0; i < properties.size(); i ++) {
					while((iter!=null)&&(iter.hasNext()))  {
						ItemPropertyDescriptor nextProp = iter.next();
						DisplayableProperty property = new DisplayableProperty(nextProp);
						displayableProperties.add(property);
						contextMenuManager.add(property);
					}// for all properties
					contextMenuManager.updateAll(true);
				}// rvhp not null
		
		// ---------------------------------------------------------------------

		// Place Holder for Menu Additions
		contextMenuManager.add(new Separator(
				IWorkbenchActionConstants.MB_ADDITIONS));

		// ---------------------------------------------------------------------
		
		clearAction = new ClearAction();
		
		contextMenuManager.add(clearAction);
		contextMenuManager.update();
		contextMenuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
		final Menu popUpMenu = contextMenuManager.createContextMenu(parent);

		// Set the context menu for the viewer
		parent.setMenu(popUpMenu);


	} // updateContextMenu


	/**
	 * @param dataSeriesMap the {@link Map} that will contain the relative values
	 *            (0.0-1.0) to plot
	 * @param cycleNumbers
	 *            the {@link List} of simulation cycle numbers that match the
	 *            relative values
	 * @param seriesIdentifier
	 *            the title of the chart
	 * @return a <code>Chart</code>
	 */
	public final Chart createSimpleLineChart(
			final Map<String, DataSeries> dataSeriesMap,
			final List<Integer> cycleNumbers, final String seriesIdentifier) {
		
		final ChartWithAxes chartWithAxes = ChartWithAxesImpl.create();

	
		// Plot
		chartWithAxes.getBlock().setBackground(ColorDefinitionImpl.create(50, 50,50));
		final Plot p = chartWithAxes.getPlot();
		p.getClientArea().setBackground( ColorDefinitionImpl.create(0, 0, 0));

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

		// Legend
		legend = chartWithAxes.getLegend();
		final LineAttributes lia = legend.getOutline();
		legend.getText().getFont().setSize(8);
		lia.setStyle(LineStyle.SOLID_LITERAL);
		legend.getInsets().set(10, 5, 0, 0);
		legend.getOutline().setVisible(false);
		legend.setAnchor(Anchor.NORTH_LITERAL);
		legend.setPosition(Position.BELOW_LITERAL);
		legend.getText().setColor(ColorDefinitionImpl.create(255, 255, 255));
		legend.getOutline().setColor(ColorDefinitionImpl.create(255, 255, 255));

		// /////////
		// X-Axis
		xAxisPrimary = chartWithAxes.getPrimaryBaseAxes()[0];
		xAxisPrimary.getMajorGrid().setTickStyle(TickStyle.BELOW_LITERAL);
		xAxisPrimary.getOrigin().setType(IntersectionType.VALUE_LITERAL);
		xAxisPrimary.getTitle().setVisible(false);
		xAxisPrimary.getTitle().getCaption().getFont().setSize(9);
		xAxisPrimary.getTitle().getCaption().setColor(ColorDefinitionImpl.create(255, 255, 255));
		xAxisPrimary.getLabel().getCaption().setColor(ColorDefinitionImpl.create(255, 255, 255));
		xAxisPrimary.setType(AxisType.LINEAR_LITERAL);
	
		final Series seCategory = SeriesImpl.create();

		// new colors
		seCategory.getLabel().getCaption().setColor(ColorDefinitionImpl.create(255, 255, 255));
		seCategory.getLabel().getOutline().setColor(ColorDefinitionImpl.create(255, 255, 255));
		//

		final NumberDataSet categoryValues = NumberDataSetImpl
				.create(cycleNumbers);
		seCategory.setDataSet(categoryValues);
		final SeriesDefinition sdX = SeriesDefinitionImpl.create();

		xAxisPrimary.getSeriesDefinitions().add(sdX);
		sdX.getSeries().add(seCategory);

		// ////////
		// Y-Axis
		this.yAxisPrimary = chartWithAxes.getPrimaryOrthogonalAxis(xAxisPrimary);
		yAxisPrimary.getMajorGrid().setTickStyle(TickStyle.LEFT_LITERAL);
		// end Y-Series

		xAxisPrimary.getScale().setMin(NumberDataElementImpl.create(0.0));
		xAxisPrimary.getScale().setStep(1);
		
		//xAxisPrimary.getScale().setMax(NumberDataElementImpl.create(TICK_TRIGGER*DEFAULT_AUTOAXIS_THRESHOLD));
		//int numTicks = TICK_TRIGGER*DEFAULT_AUTOAXIS_THRESHOLD/MIN_TICKS;
		//
		
		
		
		xAxisPrimary.getLabel().getCaption().getFont().setSize(9);
//		xAxisPrimary.getLabel().getCaption().setColor(foreGround);
		setTimeLabel();

		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);
		yAxisPrimary.getLabel().getCaption().setColor(ColorDefinitionImpl.create(255, 255, 255));
		yAxisPrimary.getTitle().getCaption().setColor(ColorDefinitionImpl.create(255, 255, 255));
		setYAxisNumberFormatFromMaxY(1.0);
		
		
		// yAxisPrimary.getMajorGrid().getLineAttributes().setColor(foreGround);
		
		// for now get ready to create only one line - we have no data yet.
		// we will add more lines as we need them
		// handle null
		if(!dataSeriesMap.containsKey(defaultKey)) {
			DataSeries series = new DataSeries(defaultKey, seriesCount);
			dataSeriesMap.put(defaultKey, series);
		}

		return chartWithAxes;
	} // createSimpleLineChart

	private void setYAxisNumberFormatFromMaxY(double maxY) {
		JavaNumberFormatSpecifier jnfs = null;
		if(maxY < 0.001) 
			jnfs = JavaNumberFormatSpecifierImpl.create("0.####E0");
		else
			jnfs = JavaNumberFormatSpecifierImpl.create("0.#####");
		yAxisPrimary.setFormatSpecifier(jnfs);
		
	}

	void setTimeLabel() {
		String val = "";
		if (control != null) {
			final ISimulation sim = control.simulation;
			if (sim != null) {
				final long timeDelta = sim.getScenario().getSequencer()
						.getTimeDelta();

				if (timeDelta < STEMTime.Units.MINUTE.getMilliseconds()) {
					val = "secs";
					xAxisPrimary.getTitle().setVisible(true);
					xAxisPrimary.getTitle().getCaption().setValue(val);
					return;
				} else if (timeDelta < STEMTime.Units.HOUR.getMilliseconds()) {
					val = "mins";
					xAxisPrimary.getTitle().setVisible(true);
					xAxisPrimary.getTitle().getCaption().setValue(val);
					return;
				} else if (timeDelta < STEMTime.Units.DAY.getMilliseconds()) {
					val = "hrs";
					xAxisPrimary.getTitle().setVisible(true);
					xAxisPrimary.getTitle().getCaption().setValue(val);
					return;

				} else if (timeDelta <= STEMTime.Units.WEEK.getMilliseconds()) {
					val = "days";
					xAxisPrimary.getTitle().setVisible(true);
					xAxisPrimary.getTitle().getCaption().setValue(val);
					return;

				} else if (timeDelta < 4 * STEMTime.Units.WEEK
						.getMilliseconds()) {
					val = "weeks";
					xAxisPrimary.getTitle().setVisible(true);
					xAxisPrimary.getTitle().getCaption().setValue(val);
					return;
				} else if (timeDelta < STEMTime.Units.YEAR.getMilliseconds()) {
					val = "months";
					xAxisPrimary.getTitle().setVisible(true);
					xAxisPrimary.getTitle().getCaption().setValue(val);
					return;
				} else {
					val = "years";
					xAxisPrimary.getTitle().setVisible(true);
					xAxisPrimary.getTitle().getCaption().setValue(val);
					return;
				}

			} // sim ! null
		}// control ! null

	} // setTimeLabel()

	
	
	
	/**
	 * @param rvhp
	 * @param propertiesToPlotList
	 */
	public synchronized void setDataSourceAndRedraw(
			final RelativeValueHistoryProviderAdapter rvhp,
			final List<IItemPropertyDescriptor> propertiesToPlotList) {
		
		
		
		if(rvhp!=this.rvhp) {
			this.rvhp= rvhp;
			removeDataSeries();
			this.propertiesToPlot.clear();
			this.propertiesToPlot = addProperties(propertiesToPlotList);
		}
		
		updateContextMenu(this);
		draw();
	} // setDataSourceAndRedraw

	/**
	 * Filters a list of ItemPropertyDescriptors to show preferred properties if
	 * at least one exists. If not, just returns the entire list.
	 *
	 * @return filteredList<ItemPropertyDescriptor>
	 */
	protected List<ItemPropertyDescriptor> filterPreferredProperties(
			final List<ItemPropertyDescriptor> fullList) {
		final List<ItemPropertyDescriptor> propertyList = new ArrayList<ItemPropertyDescriptor>();
		// Are any of the labels in the preference set?
		final Set<String> prefSet = VisualizationPreferencePage
				.getPreferenceSet();

		for (int i = 0; i < fullList.size(); i++) {
			final ItemPropertyDescriptor property = fullList.get(i);
			if (prefSet.contains(property.getDisplayName(property))) {
				propertyList.add(property);
			}
		}
		// if we didn't find any in the preferences then just add them all
		if (propertyList.size() == 0) {
			propertyList.addAll(fullList);
		}
		return propertyList;
	}


	/**
	 * Filters a list of ItemPropertyDescriptors to show preferred properties if
	 * at least one exists. If not, just returns the entire list.
	 *
	 * @return filteredList<ItemPropertyDescriptor>
	 */
	protected Map<ItemPropertyDescriptor,Boolean> addProperties(final List<IItemPropertyDescriptor> propertiesToPlotList) {

		for (int i = 0; i < propertiesToPlotList.size(); i++) {
			final ItemPropertyDescriptor property = (ItemPropertyDescriptor)propertiesToPlotList.get(i);
			if(!propertiesToPlot.containsKey(property)) {
				boolean visible = true;
				if(defaultHideSet.contains(property.getDisplayName(property))) visible = false;
				Boolean bObj = Boolean.valueOf(visible); //default visibility
				this.propertiesToPlot.put(property,bObj);
			}
		}

		return this.propertiesToPlot;
	}

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

	protected void resetData() {
		clearData();
		// for now get ready to create only one line - we have no data yet.
		// we will add more lines as we need them
		
		if(!dataSeriesMap.containsKey(defaultKey)) {
			DataSeries series = new DataSeries(defaultKey, seriesCount);
			
			dataSeriesMap.put(defaultKey, series);
		} 
		// handle null
		
		cycleNumbers.add(Integer.valueOf(0));
	}

	/**
	 * clearsAllData
	 */
	private void clearData() {
		
		Iterator<String> iter = dataSeriesMap.keySet().iterator();
		while((iter!=null)&&(iter.hasNext())) {
			String key = iter.next();
			DataSeries series = dataSeriesMap.get(key);
			series.relativeValues.clear();
			series.addValue(new Double(0.0));
			xAxisPrimary.getScale().setMin(NumberDataElementImpl.create(0.0));
			maxTimeAxisValue = DEFAULT_AUTOAXIS_THRESHOLD;
			//xAxisPrimary.getScale().setMax(NumberDataElementImpl.create(TICK_TRIGGER*DEFAULT_AUTOAXIS_THRESHOLD));
			//int numTicks = TICK_TRIGGER*DEFAULT_AUTOAXIS_THRESHOLD/MIN_TICKS;
			xAxisPrimary.getScale().setStep(1);
		}
		cycleNumbers.clear();
	}
	
	/**
	 * removeData is called when switching between decorators. For example, when switching from display of a disease to dispaly of a population,
	 * the properties are different and the lineSeries, propetries, and axis labels must be removed. SEE also: DataSeries.removeLineSeries()
	 */
	private void removeDataSeries() {
		if(displayableProperties!=null) displayableProperties.clear();
		Iterator<ItemPropertyDescriptor> iter = propertiesToPlot.keySet().iterator();
		while((iter!=null)&&(iter.hasNext())) {
			ItemPropertyDescriptor propertyToRemove = iter.next();
			String key = propertyToRemove.getDisplayName(propertyToRemove);
			DataSeries series = dataSeriesMap.get(key);
		    //series.hide();
			if(series != null) {
				 series.removeLineSeries(key);
			    //series.lineSeries.setVisible(false);
				 dataSeriesMap.remove(key);
			    series = null;
			} // if series not null
		}
		propertiesToPlot.clear();
	}//removeDataSeries
	
	

	/**
	 * toggle the scale from logarithmic to linear
	 */
	void toggleAxisScale() {
		if (useLinearTimeScale) { //Switch to logarithmic scale
			logTimeAction.setChecked(true);
			linearTimeAction.setChecked(false);
			//Just using the following axis type, to move to log scale, didn't work
			//yAxisPrimary.setType(AxisType.LOGARITHMIC_LITERAL);
			yAxisPrimary.getScale().setMin(null);
			yAxisPrimary.getScale().setMax(null);
			yAxisPrimary.getScale().unsetStep();
			yAxisPrimary.getScale().unsetStepNumber();
		}
		else { //Switch to linear scale
			logTimeAction.setChecked(false);
			linearTimeAction.setChecked(true);
			//yAxisPrimary.setType(AxisType.LINEAR_LITERAL);
			yAxisPrimary.getScale().setMin(NumberDataElementImpl.create(0.0));
			yAxisPrimary.getScale().setMax(NumberDataElementImpl.create(1.0));
			yAxisPrimary.getScale().setStep(0.25);
		}
		useLinearTimeScale = !useLinearTimeScale;
		this.draw();
	}
	
	
	/**
	 * toggle the scale from logarithmic to linear
	 */
	void toggleLegend() {
		if (showLegend) { //Switch to hide
			viewLegend.setChecked(false);
			hideLegend.setChecked(true);
			legend.setVisible(false);
		}
		else { //Switch to view
			viewLegend.setChecked(true);
			hideLegend.setChecked(false);
			legend.setVisible(true);
		}
		showLegend = !showLegend;
		this.draw();
	}

	/**
	 * switch to linear plot 
	 * 
	 */
	protected class LinearScaleAction extends Action {
		public LinearScaleAction()
		{
			super(Messages.getString("ContextMenu.LinearTimeScale"), IAction.AS_CHECK_BOX);
			setChecked(useLinearTimeScale);
		}

		/**
		 * @see org.eclipse.jface.action.Action#getText()
		 */
		@Override
		public String getText() {
			return Messages.getString("ContextMenu.LinearTimeScale");
		}

		/**
		 * @see org.eclipse.jface.action.Action#run()
		 */
		@Override
		public void run() {
			if (useLinearTimeScale) {
				setChecked(true);
				//Nothing to do. It's already linear-time.
			}
			else {
				toggleAxisScale();
			}
		}
	} //LinearScaleAction

	/**
	 * switch to semi-log plot (log scale on y axis)
	 * 
	 */
	class LogScaleAction extends Action 	{
		public LogScaleAction()
		{
			super(Messages.getString("ContextMenu.LogTimeScale"), IAction.AS_CHECK_BOX);
			setChecked(!useLinearTimeScale);
		}

		/**
		 * @see org.eclipse.jface.action.Action#getText()
		 */
		@Override
		public String getText() {
			return Messages.getString("ContextMenu.LogTimeScale");
		}

		/**
		 * @see org.eclipse.jface.action.Action#run()
		 */
		@Override
		public void run() {
			if (!useLinearTimeScale) {
				setChecked(true);
				//Nothing to do. It's already log-time.
			}
			else {
				toggleAxisScale();
			}
		}
	}//LogScaleAction

	/**
	 * Action to show the legend
	 */
	protected class LegendViewAction extends Action {
		public LegendViewAction()
		{
			super(Messages.getString("ContextMenu.ShowLegend"), IAction.AS_CHECK_BOX);
			setChecked(showLegend);
		}

		/**
		 * @see org.eclipse.jface.action.Action#getText()
		 */
		@Override
		public String getText() {
			return Messages.getString("ContextMenu.ShowLegend");
		}

		/**
		 * @see org.eclipse.jface.action.Action#run()
		 */
		@Override
		public void run() {
			if (showLegend) {
				setChecked(true);
				//Nothing to do. It's already linear-time.
			}
			else {
				toggleLegend();
			}
		}
	} //LegendViewAction
	
	/**
	 * Action to hide the legend
	 */
	class LegendHideAction extends Action 	{
		public LegendHideAction()
		{
			super(Messages.getString("ContextMenu.HideLegend"), IAction.AS_CHECK_BOX);
			setChecked(!showLegend);
		}

		/**
		 * @see org.eclipse.jface.action.Action#getText()
		 */
		@Override
		public String getText() {
			return Messages.getString("ContextMenu.HideLegend");
		}

		/**
		 * @see org.eclipse.jface.action.Action#run()
		 */
		@Override
		public void run() {
			if (!showLegend) {
				setChecked(true);
				//Nothing to do. It's already log-time.
			}
			else {
				toggleLegend();
			}
		}
	}//LegendHideAction


	/**
	 * DisplayableProperty
	 *
	 */
	protected class DisplayableProperty extends Action
	{
		ItemPropertyDescriptor property = null;
		public DisplayableProperty(ItemPropertyDescriptor property)
		{
					super(property.getDisplayName(property), IAction.AS_CHECK_BOX);
					this.property = property;
					if(propertiesToPlot.containsKey(property)) {
						setChecked(propertiesToPlot.get(property).booleanValue());
					} else {
						propertiesToPlot.put(property,new Boolean(true));
						setChecked(propertiesToPlot.get(property).booleanValue());
					}
					
		}

		/**
		 * @see org.eclipse.jface.action.Action#getText()
		 */
		@Override
		public String getText() {
			return property.getDisplayName(property);
		}

		/**
		 * Toggle the state
		 * @see org.eclipse.jface.action.Action#run()
		 */
		@Override
		public void run() {
			    boolean state = !propertiesToPlot.get(property).booleanValue();
			    propertiesToPlot.put(property, Boolean.valueOf(state));
				setChecked(state);
				
				draw();
		}
		public ItemPropertyDescriptor getProperty() {
			return property;
		}
	}// DisplayableProperty
	

	/**
	 * Action to show the legend
	 */
	protected class ClearAction extends Action {
		public ClearAction()
		{
			super(Messages.getString("ContextMenu.Clear"), IAction.AS_PUSH_BUTTON);
		}

		/**
		 * @see org.eclipse.jface.action.Action#getText()
		 */
		@Override
		public String getText() {
			return Messages.getString("ContextMenu.Clear");
		}

		/**
		 * @see org.eclipse.jface.action.Action#run()
		 */
		@SuppressWarnings("boxing")
		@Override
		public void run() {
			for(ItemPropertyDescriptor ipd:propertiesToPlot.keySet()) {
				boolean state = !propertiesToPlot.get(ipd).booleanValue();
			    propertiesToPlot.put(ipd, false);
			    for(DisplayableProperty dp:displayableProperties) 
			    	if(dp.getProperty().equals(ipd)) {dp.setChecked(false);break;}
				draw();
			}
		}
	} //ClearAction
	
	
	protected class DataSeries 
	{
		public String propertyName = "";
		

		public List<Double> relativeValues = new ArrayList<Double>();
		public LineSeries lineSeries = null;
		private boolean visible = true;
		private SeriesDefinition sdY = null;
		
		private int seriesIndex = 0;
		
		
		public boolean isVisible() {
			return visible;
		}

		/**
		 * 
		 * @param propertyName
		 * @param index
		 */
		public DataSeries(String propertyName, int index) {
			this.propertyName = propertyName;
			this.seriesIndex = index;
			seriesCount ++;
			relativeValues = new ArrayList<Double>();
			relativeValues.add(new Double(0.0));
			addLineSeries(propertyName);
		}
		
		public void addValue(Double val) {
			if(relativeValues==null) relativeValues = new ArrayList<Double>();
			relativeValues.add(val);
		}
		
		/**
		 * @param propertyName
		 * 
		 */
		@SuppressWarnings("cast")
		public void addLineSeries(final String propertyName) {
			final NumberDataSet orthoValues = NumberDataSetImpl
					.create(relativeValues);
			if(lineSeries == null) lineSeries = (ScatterSeries) ScatterSeriesImpl.create();
			lineSeries.setDataSet(orthoValues);

			lineSeries.getLineAttributes().setVisible(true);
			
			// Assign the line color
			// based on selected property. Default is Blue
			setColorDefs(propertyName);
			
			// replaces deprecated code: lineSeries.getMarker().setVisible(false);
			if (!lineSeries.getMarkers().isEmpty()) {
				Marker marker = (Marker)lineSeries.getMarkers().get(0);
				marker.setVisible(false);
			}
			
			// the series def
			sdY = SeriesDefinitionImpl.create();
			//sdY.getSeriesPalette().update(-2);
			sdY.getSeries().add(lineSeries);
			yAxisPrimary.getSeriesDefinitions().add(sdY);
			setTimeLabel();
			return;
		}
		
		/**
		 * 
		 * @param propertyName
		 */
		public void removeLineSeries(final String propertyName) {
			//visible = false;
			seriesIndex = 0;
			// ?? relativeValues.clear();
			if(lineSeries!=null) lineSeries.getLineAttributes().setVisible(false);
			if(yAxisPrimary !=null) yAxisPrimary.getSeriesDefinitions().remove(sdY);
			if(sdY != null) sdY.getSeries().remove(lineSeries);
			lineSeries = null;
			sdY = null;
			
			return;
		}
		
		
		
		/** 
		 * in response to user action temporarily remove the line series from the graph
		 */
		public void hide() {
			lineSeries.setVisible(false);
			visible = false;
		}// hide
		
		/** 
		 * in response to user action add back the line series to the graph
		 */
		public void show() {
			lineSeries.setVisible(true);
			visible = true;
		}// show
		

		/**
		 * Sets the colors for a n array of LineSeries given the property to Plot
		 * for each. Try to set color from the preferences (if specified for that
		 * property) otherwise sets line color to blue.
		 * @param propertyName 
		 *
		 */
		public void setColorDefs(String propertyName) {
			// the default line color

			// if possible get color from preferences
			final Map<String, Color> colorMap = VisualizationPreferencePage.getColorMapping();
			// pick a default color
			int colorIndex = seriesIndex % colorDefault.length;
			ColorDefinition color = colorDefault[colorIndex];

			// Check for a prefix match
			for (String key : colorMap.keySet()) {
				if((propertyName.startsWith(key))&&(key.length()>=1)) {
					// might be right
					String tail = propertyName.substring(key.length(), propertyName.length());
					if((tail==null)||(tail.length()==0)) {
						final Color c = colorMap.get(key);
						color = ColorDefinitionImpl.create(c.getRed(), c.getGreen(), c.getBlue());
						break;
					}
					
					boolean hit = true;
					for (char c : tail.toCharArray()) {
						if (!Character.isDigit(c)) {
							hit = false;
							break;
						}
					}// all characters in tail
					if(hit){
						final Color c = colorMap.get(key);
						color = ColorDefinitionImpl.create(c.getRed(), c.getGreen(), c.getBlue());
						break;
					}
				}
			}
			
//			if (colorMap.containsKey(propertyName)) {
//				final Color c = colorMap.get(propertyName);
//				color = ColorDefinitionImpl.create(c.getRed(), c.getGreen(), c.getBlue());
//			}
			
			this.lineSeries.setSeriesIdentifier(propertyName);
			this.lineSeries.getLineAttributes().setColor(color);
			return;
		}// getColorDef

		/**
		 * length of the series
		 * @return number of data points
		 */
		public int getDataSize() {
			return relativeValues.size();
		}
		// Accessors
		public String getPropertyName() {
			return propertyName;
		}

		public void setPropertyName(String propertyName) {
			this.propertyName = propertyName;
		}

		public List<Double> getRelativeValues() {
			return relativeValues;
		}

		public void setRelativeValues(List<Double> relativeValues) {
			this.relativeValues = relativeValues;
		}

		public LineSeries getLineSeries() {
			return lineSeries;
		}

		public void setLineSeries(LineSeries lineSeries) {
			this.lineSeries = lineSeries;
		}

	
	}// DataSeries
	
} // TimeSeriesCanvas
