package vgp.tutor.ode;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import jv.object.PsDebug;
import jv.object.PsPanel;
import jv.object.PsUpdateIf;
import jv.project.PjProject_IP;

/**
 * Info panel of ode demonstration with text field to edit differential equation.
 * 
 * @author		Konrad Polthier
 * @version		23.04.01, 1.10 revised (kp) Drawing of vector field.<br>
 *					00.00.99, 1.00 created (kp)
 */
public class PjExprOde_IP extends PjProject_IP implements ActionListener, ItemListener {
	protected	PjExprOde				m_pjExpr;

	protected	int						m_order;
	protected	TextField				m_tOrder;
	protected	Label						m_lEquation;
	protected	TextField				m_tEquation;
	protected	int						m_textLength = 10;

	protected	Checkbox					m_cShowInitialPoint;
	protected	Checkbox					m_cShowVectorField;
	protected	Button					m_bReset;
	protected	Panel						m_pBounds;

	public PjExprOde_IP() {
		super();
		if (getClass() == PjExprOde_IP.class)
			init();
	}
	public void init() {
		super.init();
		addTitle("");

		// draw a separator
		addLine(1);

		Panel m_pEquation = new Panel();
		m_pEquation.setLayout(new GridLayout(2, 2));
		add(m_pEquation);
		{
			m_lEquation = new Label("y'(x) = ");
			m_pEquation.add(m_lEquation);

			m_tEquation = new TextField(m_textLength);
			m_tEquation.addActionListener(this);
			m_pEquation.add(m_tEquation);

			m_pEquation.add(new Label("Order "));

			m_tOrder = new TextField(m_textLength);
			m_tOrder.addActionListener(this);
			m_pEquation.add(m_tOrder);
		}

		// draw a separator
		addLine(1);

		m_pBounds = new Panel();
		m_pBounds.setLayout(new GridLayout(4, 1));
		add(m_pBounds);

		// draw a separator
		addLine(1);

		PsPanel m_pShow = new PsPanel();
		m_pShow.addTitle("Show");
		{
			Panel pChoices = new Panel();
			pChoices.setLayout(new GridLayout(1, 2));
			
			m_cShowInitialPoint = new Checkbox("Initial Point");
			m_cShowInitialPoint.addItemListener(this);
			pChoices.add(m_cShowInitialPoint);

			m_cShowVectorField = new Checkbox("Vectors (if order=1)");
			m_cShowVectorField.addItemListener(this);
			pChoices.add(m_cShowVectorField);
			
			m_pShow.add(pChoices);
		}
		add(m_pShow);

		// buttons at bottom
		Panel m_pBottomButtons = new Panel();
		m_pBottomButtons.setLayout(new FlowLayout(FlowLayout.CENTER));
		add(m_pBottomButtons);
		m_bReset = new Button("Reset");
		m_bReset.addActionListener(this);
		m_pBottomButtons.add(m_bReset);
	}
	/**
	 * Set parent of panel which supplies the data inspected by the panel.
	 */
	public void setParent(PsUpdateIf parent) {
		super.setParent(parent);
		m_pjExpr = (PjExprOde)parent;
		m_pBounds.add(m_pjExpr.m_h.getInfoPanel());
		m_pBounds.add(m_pjExpr.m_length.getInfoPanel());
		m_pBounds.add(m_pjExpr.m_xStart.getInfoPanel());
		m_pBounds.add(m_pjExpr.m_pYStart);
	}
	/**
	 * Update the panel whenever the parent has changed somewhere else.
	 * Method is invoked from the parent or its superclasses.
	 */
	public boolean update(Object event) {
		if (PsDebug.NOTIFY) PsDebug.notify("isShowing = "+isShowing());
		if (m_pjExpr == event) {
			setTitle("Solving ODE: "+m_pjExpr.getName());
			PsPanel.setText(m_tEquation, m_pjExpr.m_equation);
			if (m_order != m_pjExpr.m_order)
				setOrder(m_pjExpr.m_order);
			PsPanel.setEnabled(m_cShowVectorField, m_order==1);
			PsPanel.setState(m_cShowInitialPoint, m_pjExpr.m_bShowInitialPoint);
			PsPanel.setState(m_cShowVectorField, m_pjExpr.m_bShowVectorField);
			return true;
		}
		return super.update(event);
	}
	/**
	 * Handle action events invoked from buttons, menu items, text fields.
	 */
	public void actionPerformed(ActionEvent event) {
		if (m_pjExpr==null)
			return;
		Object source = event.getSource();
		if (source == m_bReset) {
			m_pjExpr.init();
			update(m_pjExpr);
			m_pjExpr.solve();
		} else if (source == m_tEquation) {
			if (PsDebug.NOTIFY) PsDebug.notify("equation changed");
			m_pjExpr.setEquation(m_tEquation.getText());
			m_pjExpr.solve();
		} else if (source == m_tOrder) {
			if (PsDebug.NOTIFY) PsDebug.notify("order changed");
			try {
				int order = Integer.parseInt(m_tOrder.getText());
				if (setOrder(order) == false)
					return;
				m_pjExpr.setOrder(order);
				update(m_pjExpr);
				m_pjExpr.solve();
			} catch (NumberFormatException e) {
				if (PsDebug.WARNING) PsDebug.warning("wrong format = "+m_tOrder.getText());
			}
		}
	}
	public void itemStateChanged(ItemEvent event) {
		if (m_project==null)
			return;
		Object source = event.getSource();
		if (source == m_cShowVectorField) {
			m_pjExpr.showVectorField(m_cShowVectorField.getState());
			return;
		} else if (source == m_cShowInitialPoint) {
			m_pjExpr.showInitialPoint(m_cShowInitialPoint.getState());
			return;
		}
	}
	/** Set order of ODE, internal use only. */
	private boolean setOrder(int order) {
		if (order<1 || order>4) {
			PsPanel.setText(m_tOrder, String.valueOf(m_order));
			return false;
		}
		m_order = order;
		PsPanel.setText(m_tOrder, String.valueOf(m_order));
		switch (order) {
		case 1:
			m_lEquation.setText("y'(x) = f(x,y) = ");
			break;
		case 2:
			m_lEquation.setText("y''(x) = f(x,y,dy) = ");
			break;
		case 3:
			m_lEquation.setText("y'''(x) = f(x,y,dy,d2y) = ");
			break;
		case 4:
			m_lEquation.setText("y''''(x) = f(x,y,dy,d2y,d3y) = ");
			break;
		default:
		}
		return true;
	}
}
