import java.awt.*;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import java.awt.event.*;
import sun.tools.*;

/**
* Extra handler handles all the request from the extra menu
* extends Handler object so it can be loaded in JPE object
*/
public class ExtraHandler extends Handler {

	JPEClassloader loader;

	// Strings for the pulldown
	private String CompileString="Compile";
	private String FontUpString="Font Up";
	private String FontDownString="Font Down";
	private String SetRevoString="Revo";
	private String Set5mxString="5mx";
	private String SetPsion7String="Psion 7";
	private String SetNetbookString="Netbook";
	private String FontArialString="Arial";
	private String FontTimesString="Times";
	private String FontCourierString="Courier";
	private String RunAppString="Run as App";
	private String RunAppParamString="Run as App with param";
	private String AboutString="About";

	/**
	* create the extra handler
	*/
	public ExtraHandler(JPE jpe) {
		super(jpe);
		name="Extra";
	}


	/**
	*  called by superclass to create its menu
	*/
	public Menu createMenu() {
		Menu m = new Menu(name);
		m.add(new MenuItem(CompileString,new MenuShortcut('J')));

		Menu submenu3 = new Menu("Run");
		submenu3.add(new MenuItem(RunAppString,new MenuShortcut('R')));
		submenu3.add(new MenuItem(RunAppParamString,new MenuShortcut('R',true)));
		submenu3.addActionListener(this);
		m.add(submenu3);

		Menu submenu = new Menu("Font");
		submenu.add(new MenuItem(FontUpString,new MenuShortcut('M')));
		submenu.add(new MenuItem(FontDownString,new MenuShortcut('M',true)));
		submenu.add(FontArialString);
		submenu.add(FontCourierString);
		submenu.add(FontTimesString);
		submenu.addActionListener(this);
		m.add(submenu);

		// create the machine selector
		Menu submenu2 = new Menu("Machine");
		submenu2.add(SetRevoString);
		submenu2.add(Set5mxString);
		submenu2.add(SetPsion7String);
		submenu2.add(SetNetbookString);
		submenu2.addActionListener(this);
		m.add(submenu2);

		m.add(new MenuItem(AboutString,new MenuShortcut('I')));

		m.addActionListener(this);        
		return(m);
	}

	/**
	*  AWT callback (implemented in Handler) for menu events
	*/
    public void actionPerformed(ActionEvent evt)	{
		String cmd = evt.getActionCommand();
		if (cmd.equals(CompileString)) {
			doCompile();
		} else if (cmd.equals(FontUpString)) {
			doFontUp();
		} else if (cmd.equals(FontDownString)) {
			doFontDown();
		} else if (cmd.equals(SetNetbookString)) {
			doNetbookSetup();
		} else if (cmd.equals(SetPsion7String)) {
			doNetbookSetup();
		} else if (cmd.equals(Set5mxString)) {
			do5mxSetup();
		} else if (cmd.equals(SetRevoString)) {
			doRevoSetup();
		} else if (cmd.equals(FontTimesString)) {
			setNewFont("Times New Roman");
		} else if (cmd.equals(FontArialString)) {
			setNewFont("Arial");
		} else if (cmd.equals(FontCourierString)) {
			setNewFont("Courier");
		} else if (cmd.equals(AboutString)) {
			doAbout();
		} else if (cmd.equals(RunAppString)) {
			doRunApp();
		} else if (cmd.equals(RunAppParamString)) {
			doRunAppParam();
		}
	}


	public void doAbout() {
		jpe.say("developers release 0.92 / 12 mar 2000");
	}

	public void doRunApp() {
		handleRunApp("");
	}

	/**
	* do find uses the askInterface
	*/
	public void doRunAppParam() {
		jpe.setAskMode(this,"runparam","Start with param line  : ");
	}

	
	public void handleRunApp(String params) {
		TextHandler txth=(TextHandler)jpe.getTextHandler();	
		OpenFile file=txth.getEditFile();
		String filename=file.getName();
		if (filename.indexOf(".java")==-1) {
			jpe.say("Not a java file, can only run java applications");
			return;
		}
		filename=filename.substring(0,filename.length()-4)+"class";
		JPEProcess pr=new JPEProcess(jpe,filename,params);
	}

	/**
	* switch to netbook setup
	*/
	public void doNetbookSetup() {
		TextHandler txth=(TextHandler)jpe.getTextHandler();	
		txth.setWindowSize(640,480);
		jpe.say("Switched to Netbook setup");
		jpe.putProperty("setup","machine","netbook");
	}

	/**
	* switch to 5mx
	*/
	public void do5mxSetup() {
		TextHandler txth=(TextHandler)jpe.getTextHandler();	
		txth.setWindowSize(640,240);
		jpe.say("Switched to 5mx setup");
		jpe.putProperty("setup","machine","5mx");
	}

	/**
	* switch to revo
	*/
	public void doRevoSetup() {
		TextHandler txth=(TextHandler)jpe.getTextHandler();	
		txth.setWindowSize(480,160);
		jpe.say("Switched to Revo setup");
		jpe.putProperty("setup","machine","revo");
	}

	/**
	* shift our fontsize up by 1
	*/
	public void doFontUp() {
		TextHandler txth=(TextHandler)jpe.getTextHandler();	
		int size=txth.doFontUp();
		jpe.say("Font size now "+size);
		jpe.putProperty("setup","fontsize",""+size);
	}

	/**
	* shift our fontsize down by 1
	*/
	public void doFontDown() {
		TextHandler txth=(TextHandler)jpe.getTextHandler();	
		int size=txth.doFontDown();
		jpe.say("Font size now "+size);
		jpe.putProperty("setup","fontsize",""+size);
	}

	/**
	* change font
	*/
	public void setNewFont(String name) {
		TextHandler txth=(TextHandler)jpe.getTextHandler();	
		txth.setNewFont(name);
		jpe.say("Font now "+name);
		jpe.putProperty("setup","fontname",name);
	}


	/**
	* perform a compile on the selected file
	*/
	public void doCompile() {
		// lets see if we can find the compiler
		try {
			Class cl=Class.forName("sun.tools.javac.Main");
		} catch(Exception e) {
			e.printStackTrace();
			jpe.say("Can't find the compiler, installed new class files ??");
			return;
		}

		// get the text handler
		TextHandler txth=(TextHandler)jpe.getTextHandler();	
		if (txth!=null) {

			// get the selected file		
			OpenFile file=txth.getEditFile();
			if (file!=null) {

				// signal user we are saving the file before we compile		
				jpe.say("Saving : "+file.getName());
				// save the selected file		
				file.saveFile();
	
				// create params for the compiler 		
				String[] argv = new String[1];
				argv[0]=file.getName();
	
				if (file.getName().indexOf(".java")==-1) {
					jpe.say("You can only compile *.java files");
					return;
				}

				// signal the user we start compiler	
				jpe.say("Compiling "+file.getName());
				try {
					// clear the logs before the compile		
					LogHandler logger=(LogHandler)jpe.getHandler("Log");
					if (logger!=null) logger.clearLogs();
	
					// call the compiler		
					sun.tools.javac.Main.main(argv);
				} catch(Exception e) {
					// ignore this to catch Exit(0)
					//e.printStackTrace();
				}

				// check the compile log for errors
				int epos=checkCompileError();
				file.setErrorPos(epos);
				if (epos==-1) {
					file.setCompiled();
					jpe.setCompileState(true);
				}
			}
		}
	}

	/**
	* check if we had compile errors (simple version for now)
	*/
	public int checkCompileError() {
		// get the log handler
		LogHandler lh=(LogHandler)jpe.getHandler("Log");
		if (lh!=null) {
				// get the text from the log handler
				String errorbody=lh.getErrorText();
				// simple check to see if we have a error
				if (errorbody.indexOf("error")==-1) {		
					// signal we don't have a error			
					jpe.say("Compile Done ( oke )");
					return(-1);
				} else if (errorbody.indexOf("javac")!=-1) {
					System.out.println("ERR="+errorbody);
					jpe.say("Compiler not found : check readme how to install it !!");
					return(-1);
				} else {
					// signal we have errors		
					jpe.say("Compile Done ( Errors Found !! , crtl-g to jump to error )");
					// very simple parser to find the error
					int e1=errorbody.indexOf(':',5);
					if (e1!=-1) {
						int e2=errorbody.indexOf(':',e1+1);
						try {
							String tmp=errorbody.substring(e1+1,e2);
							System.out.println(tmp);
							int e3=Integer.parseInt(tmp);
							return(e3);
						} catch(Exception e) {}
					}
				}
		}
		return(-1);
	}

	/**
	* Handler the ask callback and finish the command started that
	* started with the setAskMode.
	*/
	public void askCallback(String command,String result) {
		if (command.equals("runparam")) {
			handleRunApp(result);
		} 
	}


}
