package vgp.tutor.updatePanel;

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

import jv.object.PsPanel;
import jv.object.PsUpdateIf;

/**
 * Tutorial info panel for combined use of Java1.1 Events and JavaView
 * Update Mechanism.</p>
 * 
 * In the Java 1.1 event mechanism each widget may have registered
 * listeners which are informed whenever the state of a widget chances.
 * Java distinguishes between different types of events such as ActionEvent
 * or ItemEvent, and listeners may register for a single or multiple events.
 * Each listener must implement an interface corresponding to a specific
 * event. This tutorial panel is both, an ActionListener and an ItemListener,
 * and is able to register itself in widgets.</p>
 * 
 * The JavaView update mechnism forces panels to have a single parent. The
 * parent registers itself using the method 'setParent' of the panel.
 * Whenever the panel changes and its methods 'actionPerformed()' or
 * 'itemStateChanged()' are called, it modifies the instance variables of the
 * parent directly but must invoke the update method of its parent such that
 * the parent initiate further recomputations of itself and its dependents.</p>
 * 
 * The strong coupling of a panel and its parent also allows the parent to
 * inform the panel whenever the parent has changed. This is accomplished through
 * the update method of the panel. This method should only be called from the
 * parent and its superclasses and, usually, not from inside the panel.
 * 
 * @see			jv.object.PsObject
 * @see			jv.object.PsUpdateIf
 * @author		Konrad Polthier
 * @version		15.08.99, 1.10 revised (kp) Converted to AWT1.1 event model.<br>
 *					15.08.99, 1.00 created (kp)
 */
public class MyClass_IP extends PsPanel implements ActionListener, ItemListener, TextListener {
	protected	MyClass		m_myParent;
	/** Button instance variables have prefix m_b followed by name. */
	protected	Button		m_bReset;
	/** Checkbox and choice instance variables have prefix m_c followed by name. */
	protected	Checkbox		m_cState;
	/** List instance variables have prefix m_l followed by name. */
	protected	List			m_lSelect;
	/** Label instance variables have prefix m_l followed by name. */
	protected	Label			m_lCurr;
	/** Text field instance variables have prefix m_t followed by name. */
	protected	TextField	m_tText;

	/**
	 * Create and layout the widgets of the panel.
	 */
	public MyClass_IP() {
		addTitle("");
		m_bReset = new Button ("Reset");
		m_bReset.addActionListener(this);
		add(m_bReset);
		
		m_cState = new Checkbox("State");
		m_cState.addItemListener(this);
		add(m_cState);

		m_lSelect = new List(5, false);
		m_lSelect.addItemListener(this);
		add(m_lSelect);
		
		m_lCurr = new Label("");
		add(m_lCurr);

		m_tText=new TextField(7);
		m_tText.addTextListener(this);
		add(m_tText);

		if (getClass() == MyClass_IP.class)
			init();
	}
	/**
	 * Set values of variables. Method is also used to reset the panel.
	 */
	public void init() {
		super.init();
	}
	/**
	 * Set parent of panel which supplies the data inspected by the panel.
	 */
	public void setParent(PsUpdateIf parent) {
		super.setParent(parent);
		m_myParent = (MyClass)parent;
	}
	/**
	 * 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 (event == m_myParent) {
			setTitle("Info of "+m_myParent.getName());
			// Update the checkbox with data from base class.
			m_cState.setState(m_myParent.getState());

			// Update the list with data from base class.
			// Clear list, add list elements, and select an entry.
			m_lSelect.removeAll();
			String [] topics = m_myParent.getTopics();
			for (int i=0; i<topics.length; i++) {
				m_lSelect.add(topics[i]);
			}
			m_lSelect.select(m_myParent.getSelectedTopic());
			
			// Update the label with the name of the currently selected topic.
			m_lCurr.setText(topics[m_myParent.getSelectedTopic()]);

			// Update the text field with data from base class.
			m_tText.setText(m_myParent.getText());
			return true;
		}
		return super.update(event);
	}
	/**
	 * Handle action events invoked from buttons, menu items, text fields.
	 */
	public void actionPerformed(ActionEvent event) {
		if (m_myParent==null)
			return;
		Object source = event.getSource();
		if (source == m_bReset) {
			m_myParent.init();
			m_myParent.update(m_myParent);
		} else if (source == m_tText) {
			// User has pressed <enter> inside text field.
			try {
				m_myParent.setSelectedTopic(Integer.parseInt(m_tText.getText()));
				m_myParent.update(null);
			} catch (NumberFormatException e) {}
		}
	}
	/**
	 * Handle item state events invoked from choices, checkboxes, list items.
	 */
	public void itemStateChanged(ItemEvent event) {
		if (m_myParent==null)
			return;
		Object source = event.getSource();
		if (source == m_cState) {
			m_myParent.setState(m_cState.getState());
			m_myParent.update(null);
		} else if (source == m_lSelect) {
			int index = m_lSelect.getSelectedIndex();
			if (index != -1) {
				m_myParent.setSelectedTopic(index);
				m_lCurr.setText(m_lSelect.getSelectedItem());
				m_myParent.setText(String.valueOf(m_myParent.getSelectedTopic()));
				m_tText.setText(m_myParent.getText());
			}
			m_myParent.update(null);
		}
	}
	/**
	 * Handle any chances in text field. After any keystroke an event is sent,
	 * therefore, catching these events frees the user from pressing <enter>.
	 */
	public void textValueChanged(TextEvent event) {
		if (m_myParent==null)
			return;
		Object source = event.getSource();
		if (source == m_tText) {
			// User has typed inside text field, or the text field has been
			// modified by a call m_text.setText("Something")
			try {
				m_myParent.setSelectedTopic(Integer.parseInt(m_tText.getText()));
				m_lSelect.select(m_myParent.getSelectedTopic());
				m_lCurr.setText(m_lSelect.getSelectedItem());
				m_myParent.update(null);
			} catch (NumberFormatException e) {}
		}
	}
}