////////////////////////////////////////////////////////////////
// BarChartDemo.java
//
// Copyright (C) 1998, 1999 by ObjectPlanet AS
// All rights reserved. 
// Confidential, unpublished property of ObjectPlanet AS	
////////////////////////////////////////////////////////////////

package com.objectplanet.chart.demo;

import com.objectplanet.chart.*;

import java.awt.*;
import java.awt.event.*;
import java.applet.*;


/**
 * This application demonstrates the bar chart component.
 *
 * @author Bjorn J. Kvande.
 */
public class BarChartDemo extends Applet {

	private static final String LEFT = "Left";
	private static final String RIGHT = "Right";
	private static final String TOP = "Top";
	private static final String BOTTOM = "Bottom";
	private static final String VERTICAL = "Vertical";
	private static final String HORIZONTAL = "Horizontal";
	
	// The bar chart
	private BarChart chart;

	// the selected bar
	private ChartSample selectedBar;
	
	// the parent application frame
	private Frame parentFrame;
	
	// the number of decimals in the range and sample values
	private int sampleDecimalCount;
	private int rangeDecimalCount;

	// The control panel gui components
	private TextField titleField;
	private TextField valueField;
	private TextField upperRangeField;
	private TextField lowerRangeField;
	private TextField rangeDecimalField;
	private TextField decimalField;
	private TextField barLabelField;
	private Checkbox titleCheck;
	private Checkbox multiColorCheck;
	private Checkbox legendCheck;
	private Checkbox valueLinesCheck;
	private Checkbox look3dCheck;
	private Checkbox valueLabelsCheck;
	private Checkbox barLabelsCheck;
	private Checkbox frameCheck;
	private Choice barAlignmentChoice;
	private Choice legendPositionChoice;
	private Choice colorChoice;
	private Button printButton;


// construction


	/**
	 * Called when the applet is created.
	 */
	public void init() {
		setBackground(Color.lightGray);
		setLayout(new BorderLayout(10,10));
		
		// create the chart
		chart = new BarChart(5, 1000);
		double[] values = new double[] {100, 300, 500, 700, 900};
		String[] labels = new String[] {"1995", "1996", "1997", "1998", "1999"};

		chart.setTitle("Bar Graph");
		chart.setSampleValues(values);
		chart.setSampleLabels(labels);

		// create the control panel components
		titleField = new TextField(chart.getTitle());
		titleCheck = new Checkbox();
		upperRangeField = new TextField(chart.getRange()+"");
		lowerRangeField = new TextField(chart.getLowerRange()+"");
		rangeDecimalField = new TextField("0");
		decimalField = new TextField("0");
		valueField = new TextField();
		barLabelField = new TextField();
		multiColorCheck = new Checkbox();
		legendCheck = new Checkbox();
		valueLinesCheck = new Checkbox();
		look3dCheck = new Checkbox();
		valueLabelsCheck = new Checkbox();
		barLabelsCheck = new Checkbox();
		frameCheck = new Checkbox();

		legendPositionChoice = new Choice();
		legendPositionChoice.add(RIGHT);
		legendPositionChoice.add(LEFT);
		legendPositionChoice.add(TOP);
		legendPositionChoice.add(BOTTOM);
		legendPositionChoice.select(RIGHT);

		barAlignmentChoice = new Choice();
		barAlignmentChoice.add(VERTICAL);
		barAlignmentChoice.add(HORIZONTAL);
		
		colorChoice = new Choice();
		colorChoice.add("black");
		colorChoice.add("blue");
		colorChoice.add("cyan");
		colorChoice.add("darkGray");
		colorChoice.add("gray");
		colorChoice.add("green");
		colorChoice.add("lightGray");
		colorChoice.add("magenta");
		colorChoice.add("orange");
		colorChoice.add("pink");
		colorChoice.add("red");
		colorChoice.add("white");
		colorChoice.add("yellow");
		colorChoice.select("red");
		
		printButton = new Button("Print");

		Panel controlPanel = new Panel();
		controlPanel.setLayout(new GridLayout(0,2,5,0));
		controlPanel.add(new Label("Title on", Label.RIGHT));
		controlPanel.add(titleCheck);
		controlPanel.add(new Label("Title", Label.RIGHT));
		controlPanel.add(titleField);
		controlPanel.add(new Label("Upper range", Label.RIGHT));
		controlPanel.add(upperRangeField);
		controlPanel.add(new Label("Lower range", Label.RIGHT));
		controlPanel.add(lowerRangeField);
		controlPanel.add(new Label("Range decimals", Label.RIGHT));
		controlPanel.add(rangeDecimalField);
		controlPanel.add(new Label("Bar value", Label.RIGHT));
		controlPanel.add(valueField);
		controlPanel.add(new Label("Bar labels", Label.RIGHT));
		controlPanel.add(barLabelsCheck);
		controlPanel.add(new Label("Bar label", Label.RIGHT));
		controlPanel.add(barLabelField);
		controlPanel.add(new Label("Value decimals", Label.RIGHT));
		controlPanel.add(decimalField);
		controlPanel.add(new Label("Bar color", Label.RIGHT));
		controlPanel.add(colorChoice);
		controlPanel.add(new Label("Bar alignment", Label.RIGHT));
		controlPanel.add(barAlignmentChoice);
		controlPanel.add(new Label("Legend on", Label.RIGHT));
		controlPanel.add(legendCheck);
		controlPanel.add(new Label("Legend position", Label.RIGHT));
		controlPanel.add(legendPositionChoice);
		controlPanel.add(new Label("Multicolor", Label.RIGHT));
		controlPanel.add(multiColorCheck);
		controlPanel.add(new Label("Value lines", Label.RIGHT));
		controlPanel.add(valueLinesCheck);
		controlPanel.add(new Label("Value labels", Label.RIGHT));
		controlPanel.add(valueLabelsCheck);
		controlPanel.add(new Label("Frame", Label.RIGHT));
		controlPanel.add(frameCheck);
		controlPanel.add(new Label("3D look", Label.RIGHT));
		controlPanel.add(look3dCheck);
		controlPanel.add(new Panel());
		controlPanel.add(printButton);

		EventHandler eventHandler = new EventHandler();
		titleField.addActionListener(eventHandler);
		upperRangeField.addActionListener(eventHandler);
		lowerRangeField.addActionListener(eventHandler);
		rangeDecimalField.addActionListener(eventHandler);
		decimalField.addActionListener(eventHandler);
		valueField.addActionListener(eventHandler);
		barLabelField.addActionListener(eventHandler);
		chart.addItemListener(eventHandler);
		titleCheck.addItemListener(eventHandler);
		multiColorCheck.addItemListener(eventHandler);
		legendCheck.addItemListener(eventHandler);
		valueLinesCheck.addItemListener(eventHandler);
		look3dCheck.addItemListener(eventHandler);
		valueLabelsCheck.addItemListener(eventHandler);
		barLabelsCheck.addItemListener(eventHandler);
		colorChoice.addItemListener(eventHandler);
		printButton.addActionListener(eventHandler);
		legendPositionChoice.addItemListener(eventHandler);
		barAlignmentChoice.addItemListener(eventHandler);
		frameCheck.addItemListener(eventHandler);

		Panel p = new NonFlickerPanel(new BorderLayout());
		p.add("Center", chart);
		add("Center", p);
		add("East", controlPanel);
	}
	
	
	/**
	 * Sets the parent frame, used for printing.
	 * @param frame The application parent frame.
	 */
	public void setParentFrame(Frame frame) {
		this.parentFrame = frame;
	}


// event handling


	class EventHandler implements ItemListener, ActionListener {
		public void itemStateChanged(ItemEvent e) {
			Object source = e.getSource();

			// check the checkboxes
			if (source instanceof Checkbox) {
				Checkbox box = (Checkbox) source;
				boolean state = box.getState();
				if (source == titleCheck) {
					chart.setTitleOn(state);
				} else if (source == multiColorCheck) {
					chart.setMultiColorOn(state);
				} else if (source == legendCheck) {
					chart.setLegendOn(state);
				} else if (source == valueLinesCheck) {
					chart.setValueLinesOn(state);
				} else if (source == look3dCheck) {
					chart.set3DModeOn(state);
				} else if (source == valueLabelsCheck) {
					chart.setValueLabelsOn(state);
				} else if (source == barLabelsCheck) {
					chart.setBarLabelsOn(state);
				} else if (source == frameCheck) {
					chart.setFrameOn(state);
				}
			}

			// we changed the legend position
			if (source == legendPositionChoice) {
				Choice c = (Choice) source;
				String position = c.getSelectedItem();
				if (position.equals(LEFT)) {
					chart.setLegendPosition(BarChart.LEFT);
				} else if (position.equals(RIGHT)) {
					chart.setLegendPosition(BarChart.RIGHT);
				} else if (position.equals(TOP)) {
					chart.setLegendPosition(BarChart.TOP);
				} else if (position.equals(BOTTOM)) {
					chart.setLegendPosition(BarChart.BOTTOM);
				}
			}

			// we changed the bar alignment
			if (source == barAlignmentChoice) {
				Choice c = (Choice) source;
				String alignment = c.getSelectedItem();
				if (alignment.equals(VERTICAL)) {
					chart.setBarAlignment(BarChart.VERTICAL);
				} else if (alignment.equals(HORIZONTAL)) {
					chart.setBarAlignment(BarChart.HORIZONTAL);
				}
			}
			
			// we selected a color
			if (source == colorChoice) {
				String color = ((Choice)source).getSelectedItem();
				Color col = null;
				if (color.equals("black")) { col = Color.black; } 
				else if (color.equals("blue")) { col = Color.blue; }
				else if (color.equals("cyan")) { col = Color.cyan; }
				else if (color.equals("darkGray")) { col = Color.darkGray; }
				else if (color.equals("gray")) { col = Color.gray; }
				else if (color.equals("green")) { col = Color.green; }
				else if (color.equals("lightGray")) { col = Color.lightGray; }
				else if (color.equals("magenta")) { col = Color.magenta; }
				else if (color.equals("orange")) { col = Color.orange; }
				else if (color.equals("pink")) { col = Color.pink; }
				else if (color.equals("red")) { col = Color.red; }
				else if (color.equals("white")) { col = Color.white; }
				else if (color.equals("yellow")) { col = Color.yellow;	}
				if (chart.isMultiColorOn()) {
					if (selectedBar != null) {
						chart.setSampleColor(selectedBar.getIndex(), col);
					}
				} else {
					chart.setSampleColor(0, col);
				}
			}


			// we selected a bar in the chart
			if (source == chart) {
				switch (e.getStateChange()) {
					case ItemEvent.SELECTED:
						ChartSample sample = (ChartSample) e.getItem();
						String value = ChartSample.formatNumber(sample.getFloatValue(), sampleDecimalCount);
						String label = sample.getLabel();
						valueField.setText(value);
						barLabelField.setText(label);
						selectedBar = sample;
						break;
					case ItemEvent.DESELECTED:
						selectedBar = null;
						break;
				}
			}
		}

		// called when something changes in the text fields
		public void actionPerformed(ActionEvent e) {
			Object source = e.getSource();
			String s = e.getActionCommand();

			// change the chart title
			if (source == titleField) {
				chart.setTitle(s);
			}

			// change the upper range
			if (source == upperRangeField) {
				long value = chart.getRange();
				try {
					double range = (new Double(s)).doubleValue();
					chart.setRange(range);
				} catch (NumberFormatException ex) {
					chart.setRange(value);
				}
			}

			// change the lower range
			if (source == lowerRangeField) {
				try {
					double range = (new Double(s)).doubleValue();
					chart.setLowerRange(range);
				} catch (NumberFormatException ex) {}
			}

			// change the value of a sample
			if (source == valueField && selectedBar != null) {
				double value = selectedBar.getFloatValue();
				int index = selectedBar.getIndex();
				try {
					double new_value = (new Double(s)).doubleValue();
					chart.setSampleValue(index, new_value);
				} catch (NumberFormatException ex) {
					chart.setSampleValue(index, value);
				}
				chart.repaint();
			}
			
			// change the sample label
			if (source == barLabelField && selectedBar != null) {
				chart.setSampleLabel(selectedBar.getIndex(), s);
			}
			
			// print the chart
			if (source == printButton) {
				Toolkit t = parentFrame.getToolkit();
				PrintJob job = t.getPrintJob(parentFrame, "ChartPrinting", null);
				if (job != null) {
					Graphics g = job.getGraphics();
					if (g != null) {
						chart.print(g);
						g.dispose();
					}
					job.end();
				} else {
					System.out.println("No print job");
				}
			}

			// a value was typed for the number of value decimals
			if (source == decimalField) {
				try {
					int count = Integer.parseInt(s);
					chart.setSampleDecimalCount(count);
					sampleDecimalCount = count;
					if (selectedBar != null) {
						s = ChartSample.formatNumber(selectedBar.getFloatValue(), sampleDecimalCount);
						valueField.setText(s);
					} else {
						valueField.setText("");
					}
				} catch (NumberFormatException ex) {}
			}

			// a value was typed for the number of range decimals
			if (source == rangeDecimalField) {
				try {
					int count = Integer.parseInt(s);
					chart.setRangeDecimalCount(count);
					rangeDecimalCount = count;
					String upper = ChartSample.formatNumber(chart.getFloatRange(), rangeDecimalCount);
					String lower = ChartSample.formatNumber(chart.getFloatLowerRange(), rangeDecimalCount);
					upperRangeField.setText(upper);
					lowerRangeField.setText(lower);
				} catch (NumberFormatException ex) {}
			}
		}
	}


// entry point


	/** Used to test the bar chart.*/
	public static void main(String[] argv) {
		Frame f = new Frame();
		f.setBackground(Color.lightGray);

		BarChartDemo demo = new BarChartDemo();
		demo.setParentFrame(f);
		demo.init();
		f.add("Center", demo);
		f.setSize(620,460);
		f.show();
	}
}