package vgp.tutor.model;

import java.awt.event.*;

import jv.loader.PjImportModel;
import jv.object.PsConfig;
import jv.object.PsDebug;
import jv.project.PgGeometry;
import jv.project.PgGeometryIf;
import jv.project.PjProject;

/**
 * Tutorial on usage of importing models from file.
 * Three methods to load a geometry from file are presented:
 * <OL>
 * <LI>The first loading takes place inside the start method of the project
 * where a geometry from a given file is loaded, without any user
 * interaction. Of course, the code may be inserted into any other
 * method than the start() method. This is a batch version.</LI>
 * 
 * <LI>The second loading may be invoked by opening the control panel of
 * JavaView and import a model from the menu <pre>File -> Import -> ...</pre>
 * This adds the loaded geometry to this project, and this project overwrites
 * the methods addGeometry() and selectGeometry() to show how the project
 * might react on newly loaded geometries. Here just a message is printed.</LI>
 * 
 * <LI>The third loading may be invoked by including a separate panel of the
 * project PjImportModel into the info panel of this project. In this case
 * the import project should exist as instance, and this project should be
 * its ActionListener to be able to receive events invoked by the import project
 * when its info panel has received user interaction.</LI>
 * </OL>
 * 
 * @see			jv.viewer.PvViewer
 * @author		Konrad Polthier
 * @version		15.01.00, 1.00 revised (kp) <br>
 *					15.01.00, 1.00 created (kp)
 */
public class PjModel extends PjProject 
	implements ActionListener
{
	protected	PgGeometry		m_geom;
	/**
	 * Import project to load geometries from file via info panel.
	 * It is an instance variable to allow display of its info panel
	 * inside the info panel of this project.
	 */
	protected	PjImportModel	m_import;
	/** Default name of geometry for usage in start() method. */
	protected	String			m_defModelName = "models/primitive/Cube.byu";

	public PjModel() {
		super("Model from File/URL");
		m_import = new PjImportModel();
		m_import.setTypeOfInfoPanel(PjImportModel.SMALL_INFO_PANEL);
		m_import.addActionListener(this); //prepare to catch events whenever user tries to load a geometry
		if (getClass() == PjModel.class) {
			init();
		}
	}
	public void init() {
	}
	/**
	 * Start method is invoke when project is selected in the viewer. Here
	 * the loading of geometry from file is demonstrated as a batch version
	 * using another instance of PjImportModel.
	 */
	public void start() {
		if (PsDebug.NOTIFY) PsDebug.notify("computing torus as element set");
		String fileName = PsConfig.getCodeBase()+m_defModelName;
		if (m_import.load(fileName)) {
			m_geom = (PgGeometry)m_import.getGeometry().clone();
			addGeometry(m_geom);
			selectGeometry(m_geom);
		} else
			PsDebug.message("PjModel.start(): failed loading geometry from file = "+fileName);
		super.start();
	}

	public void actionPerformed(ActionEvent event) {
		if (event.getSource() == m_import) {
			PsDebug.message("PjModel.actionPerformed(ActionEvent): user interaction in info panel of import project.");
			if (m_import.getConfirm() == PjImportModel.CONFIRM_CLICKED) {
				// The user has clicked directly inside the list field without pressing
				// ok or cancel. Temporarily we add the imported geometry, and
				// remove the previously selected geometry m_geom but keep
				// a reference in m_geom as backup.
				removeGeometries();
				if (m_import.getGeometry() != null) {
					addGeometry(m_import.getGeometry());
				}
			} else if (m_import.getConfirm() == PjImportModel.CONFIRM_CANCEL) {
				// The user has cancelled the dialog, so we restore the original geometry
				if (m_import.getGeometry() != null)
					removeGeometries();
				// Restore the previously backuped geometry, which was removed in addGeometry()
				if (m_geom != null) {
					addGeometry(m_geom);
				}
			} else if (m_import.getConfirm() == PjImportModel.CONFIRM_OK) {
				// The user has accepted the dialog, so we replace the original geometry
				if (getNumGeometries() != 0)
					removeGeometries();
				if (m_import.getGeometry() != null) {
					m_geom = (PgGeometry)m_import.getGeometry().clone();
					addGeometry(m_geom);
					selectGeometry(m_geom);
				}
			}
		}
	}
	
	/**
	 * Overwrite method of superclass to be able to react when new geometry
	 * is loaded from file by menu import.
	 * This method is invoked when the import menu is pressed.
	 */
	public boolean addGeometry(PgGeometryIf geom) {
		PsDebug.message("PjModel.addGeometry(): new geometry added.");
		return super.addGeometry(geom);
	}
	/**
	 * Overwrite method of superclass to be able to react when new geometry
	 * is loaded from file by menu import.
	 * This method is invoked when the imported geometry is accepted.
	 */
	public void selectGeometry(PgGeometryIf geom) {
		PsDebug.message("PjModel.selectGeometry(): new geometry selected.");
		super.selectGeometry(geom);
	}
	/**
	 * Overwrite method of superclass to be able to react when new geometry
	 * is loaded from file by menu import.
	 * This method is invoked when the imported geometry is cancelled.
	 */
	public void removeGeometry(PgGeometryIf geom) {
		PsDebug.message("PjModel.removeGeometry(): geometry removed.");
		super.removeGeometry(geom);
	}
}

