
package lj_cust;

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.reflect.InvocationTargetException;
import java.rmi.RemoteException;
import java.io.Serializable;
import java.util.Vector;

import wt.util.WTContext;
import wt.method.RemoteMethodServer;
import wt.method.RemoteAccess;

import wt.fc.QueryResult;
import wt.fc.PersistenceHelper;
import wt.fc.PersistenceManager;
import wt.part.WTPart;
import wt.part.WTPartMaster;
import wt.query.QuerySpec;
import wt.query.SearchCondition;

public class AppLightFwdLJ extends Applet {

	// Class name of our inner class that runs in the server
	private static final String SERVER_CLASS = AppLightFwdLJ.class.getName() + "$Server";

	private Button action;
	private RunnerEventListener rel;
	private Label partNames;
	private TextField text;
	private Label queryCount;
	private TextField countVal;
	private TextArea feedback;

	public void init() {
		WTContext.init(this);
		action = new Button ("Get Parts");
		this.add(action);

		rel = new RunnerEventListener();
		action.addActionListener(rel);
		partNames = new Label( " with names like ... " );
		this.add(partNames);
		text = new TextField("", 25);
		this.add(text);
		queryCount = new Label( "Number of parts to return" );
		this.add(queryCount);
		countVal = new TextField( "99", 4);
		this.add(countVal);
		feedback = new TextArea("",10, 40);
		this.add(feedback);
	}

	public void start() {
		WTContext.getContext(this).start(this);
		super.start();
	}

	public void stop() {
		WTContext.getContext(this).stop(this);
		super.stop();
	}

	public void destroy() {
		WTContext.getContext(this).destroy(this);
		super.destroy();
	}

	// Applet event listener
	class RunnerEventListener implements ActionListener {
		public void actionPerformed (ActionEvent event) {
			Object o = event.getSource();
			if (o == action) {
				String name = text.getText();
				String count = countVal.getText();
				if (!name.equals(""))
					doSomeWork(name,count);
				else
					text.setText("must enter a part name search key" );
			}
		}
	}

	// Food for thought:
	// here we should disable appropriate GUI components and
	// spin off a seperate thread to do the actual work so
	// we don’t hang the AWT-Thread ( the GUI thread )

	public void doSomeWork(String name, String count) {
		Vector results = null;
		String like = "% [ ]"+name.toUpperCase()+"% [ ]";

		feedback.setText("");
		try
		{
			Integer cnt = null;
			try {
				cnt = new Integer(count);
			}
			catch (Exception e) {
				// some parse exception, just get default count
				try {
					cnt = new Integer(5); // this will work
				}

				catch (Exception e2){}
			}

			// construct arguments for call
			Class [] argTypes = { String.class, Integer.TYPE };
			Object [] args = { like, cnt };

			// Run to server and do some work there.
			// Build Server inner class name as a string so we don’t
			// load the class here.
			results = (Vector) RemoteMethodServer.getDefault().invoke("doSomeWork", SERVER_CLASS, null, argTypes, args);

			// display results in text area
			for (int i=0;i < results.size(); i++) {
				PartMasterInfo pmi = (PartMasterInfo)results.elementAt(i);
				feedback.append("> "+pmi.getName()+" # "+pmi.getNumber()+"\n");
			}
		}
		catch (RemoteException e)
		{
			// Put localized Exceptions into a Dialog popup
			feedback.append(e.toString());
		}
		catch (InvocationTargetException e)
		{
			// Localize in a dialog
			feedback.append(e.toString());
		}
	}

	// "Public" static inner class.
	// Yes 2 public classes in the same file, this is the only exception

	public static class Server implements RemoteAccess {

		public static Vector doSomeWork (String name, int count)
		{
			int i=0;
			Vector parts = new Vector(count);
			WTPartMaster wtpm;

			try {
				// Use feedback mechanism to send progress updates
				// to the user and of course be sure to Localize it
				QuerySpec queryspec = new QuerySpec(WTPartMaster.class);
				queryspec.appendSearchCondition(
				new SearchCondition(WTPartMaster.class,WTPartMaster.NAME,SearchCondition.LIKE,name) );

				QueryResult queryresult = PersistenceHelper.manager.find(queryspec);

				// create a vector of PartMasterInfo object to return to the client
				while (queryresult.hasMoreElements()) {
					wtpm = (WTPartMaster)queryresult.nextElement();
					parts.addElement(new PartMasterInfo(wtpm.getName(), wtpm.getNumber()));
					if (++i >= count)
					break;
				}
			}
			catch (Exception e) {
				// Localize
				parts.addElement(new PartMasterInfo(e.toString(),"-1"));
				e.printStackTrace();
			}
			return parts;
		}
	}

	// simple support (inner) class which contains the information we are
	// interested in returning to the client for display purposes

	public static class PartMasterInfo implements Serializable {
		String name;
		String partNumber;

		public PartMasterInfo( String name, String number ) {
			this.name = name;
			partNumber = number;
		}

		public String getName() { return name; }
		public String getNumber() { return partNumber; }
	}
}
