import java.awt.*;
import java.io.*;
import java.util.*;
import java.awt.event.*;

/**
* OpenFileHandler handles all the request from the opened menu
* extends Handler object so it can be loaded in JPE object
*/
public class OpenFileHandler extends Handler {

	// Strings for the pulldown
	private String NextFileString="Next File";
	private String PrevFileString="Prev File";
	private String LastFileString="Last File";

	// hashtable with the opened files
	private Hashtable openfiles=new Hashtable();

	String lastFileName = null;

	// pointer to its menu (why ?)
	private Menu menu;

	/**
	* create the opened file handler
	*/
	public OpenFileHandler(JPE jpe) {
		super(jpe);
		name="Opened";
	}

	/**
	* reopen all the files defined by the properties (config.xml)
	*/
	public void openFiles() {
		Vector vec=jpe.getProperties("openfile");
		if (vec!=null) {
			Enumeration e=vec.elements();
			while (e.hasMoreElements()) {
				Hashtable onenode=(Hashtable)e.nextElement();
				String filename=(String)onenode.get("filename");
				if (filename.indexOf("JPE:")==0) {
					filename=jpe.getMyPath()+"\\"+filename.substring(4);
				}
				OpenFile file=new OpenFile(filename);
				String lockstate=(String)onenode.get("locked");
				if (lockstate.equals("true")) {
					file.setLocked();
					jpe.setLockState(true);
				}
				String editpos=(String)onenode.get("editpos");
				//System.out.println(file.getName()+" "+editpos);
				addFile(file);
			}
		}
	}

	/**
	*  called by superclass to create its menu
	*/
	public Menu createMenu() {
		Menu m = new Menu(name);
		m.add(new MenuItem(NextFileString,new MenuShortcut('N',true)));
		m.add(new MenuItem(PrevFileString,new MenuShortcut('P',true)));
		m.add(new MenuItem(LastFileString,new MenuShortcut('L',true)));
		m.addSeparator();
		m.addActionListener(this);        
		this.menu=m;
		return(m);
	}


	/**
	*  AWT callback (implemented in Handler) for menu events
	*/
    public void actionPerformed(ActionEvent evt)	{
		String cmd = evt.getActionCommand();
		if (cmd.equals(NextFileString)) {
			doNextFile();
		} else if (cmd.equals(PrevFileString)) {
			doPrevFile();
		} else if (cmd.equals(LastFileString)) {
			doLastFile();
		} else {
			switchOpenFile(cmd);
		}
	}

	/**
	* switch to the first opened file (called on close)
	* will open the readme if no files are left
	*/
	public boolean switchOpenFile() {
		// get the 'first' in the hashtable
		Enumeration e=openfiles.keys();
		if (e.hasMoreElements()) {
			// one found switch to it
			String filename=(String)e.nextElement();
			return(switchOpenFile(filename));
		} else {
			// what no open files anymore ? lets open the readme then
			OpenFile file=new OpenFile(jpe.getMyPath()+"\\readme.txt");
			file.setLocked();
			// since the file was closed open it first
			addFile(file);
			// use the readme file
			TextHandler txth=jpe.getTextHandler();
			txth.useFile(file);
		}	
		return(false);
	}

	/**
	* switch to a opened file, will return false if it was not
	* opened
	*/
	public boolean switchOpenFile(String filename) {
		if (filename.indexOf("JPE:")==0) {
			filename=jpe.getMyPath()+"\\"+filename.substring(4);
		}

		// Remember the last used file name.
		lastFileName = currentFileName();

		// get the requested file from our list
		OpenFile file=(OpenFile)openfiles.get(filename);
		if (file!=null) {
			// file found so make it active and return true
			TextHandler txth=jpe.getTextHandler();
			txth.useFile(file);
			return(true);
		} else {
			// file was not opened return false
			return(false);
		}
	}

	/**
	* return the requested openfile
	*/
	public OpenFile getOpenFile(String filename) {
		// get the requested file from our list
		OpenFile file=(OpenFile)openfiles.get(filename);
		// return it
		return(file);
	}


	/**
	* add a openfile to our opened list, will also result in it
	* being added to the opened menu
	*/
	public void addFile(OpenFile file) {
		// put the given openfile in the list by its name
		openfiles.put(file.getName(),file);
		// get the size of our list (so we can create a hotkey)
		int i=openfiles.size();
		// add the file to the menu pulldown
		// removed doesn't work on epoc menu.add(new MenuItem(file.getName(),new MenuShortcut('0'+i)));
		menu.add(file.getName());
		// update the properties (in config.xml)
		updateProperties();
	}

	/**
	* remove given file from the opened list, also results in removing
	* it from the opened menu.
	*/
	public void removeFile(OpenFile file) {
		// remove openfile from the list
		openfiles.remove(file.getName());
		// empty the opened menu (bad way needs to be changed)
		menu.removeAll();
		menu.add(new MenuItem(NextFileString,new MenuShortcut('N',true)));
		menu.add(new MenuItem(PrevFileString,new MenuShortcut('P',true)));
		menu.add(new MenuItem(LastFileString,new MenuShortcut('L',true)));
		menu.addSeparator();
		// enum all openfiles to create a new menu list
		Enumeration e=openfiles.elements();
		int i=1;
		while (e.hasMoreElements()) {
			OpenFile nfile=(OpenFile)e.nextElement();
			// add the file to the menu pulldown
			// temp remove they don't work under epoc menu.add(new MenuItem(nfile.getName(),new MenuShortcut('0'+i)));
			menu.add(nfile.getName());
			i++;
		}
		// update the properties (in config.xml)
		updateProperties();
	}

	/**
	* is the given name loaded as allready ?
	*/
	public boolean isLoaded(String name) {
		OpenFile file=(OpenFile)openfiles.get(name);
		if (file!=null) return(true);
		return(false);
	}

	/**
	* create new file propertie vector and store the new list
	* into the propertie system (that auto saves it to config.xml).
	* so the config.xml is uptodate again
	*/
	public void updateProperties() {
		// setup the n new vector
		Vector results=new Vector();
		// enum all the openfiles
		Enumeration e=openfiles.keys();
		while (e.hasMoreElements()) {
			// create a new node for a file 
			Hashtable onenode=new Hashtable();
			// store the type
			onenode.put("nodename","openfile");
			// get file name
			String filename=(String)e.nextElement();
			// store filename
			onenode.put("filename",filename);
			OpenFile file=(OpenFile)openfiles.get(filename);
			onenode.put("locked",""+file.isLocked());
			onenode.put("editpos",""+file.getCaretPosition());
			// add the config node to the vector
			results.addElement(onenode);
		}
		//  store/replace the current vector with our new one
		jpe.putProperties("openfile",results);
	}

	/**
	* all files saved ?
	*/
	public boolean allFilesSaved() {
		Enumeration e=openfiles.elements();
		while (e.hasMoreElements()) {
			OpenFile file=(OpenFile)e.nextElement();
			if (file.isDirty()) {
				return(false);
			}
		}
		return(true);
	}


	/**
	* Switches (toggles) to the last used open file.
	*/
	public void doLastFile() {
		if ( lastFileName != null && isLoaded(lastFileName) ) {
			String nextFileName = lastFileName;
			lastFileName = currentFileName();
			switchOpenFile( nextFileName );
		}
	}


	/**
	* Select previous open file.
	*/
	public void doPrevFile() {
		String curFileName = currentFileName();
		String prevFileName = null;
		String endFileName = null;		
		boolean foundIt = false;

		// Browse the list of open files and locate the current one.	
		Enumeration e=openfiles.keys();
		while (e.hasMoreElements()) {
			String fileName = (String) e.nextElement();
			if ( fileName == curFileName ) {
				foundIt = true;
			}
			if ( foundIt == false ) {
				prevFileName = fileName;
			}
			endFileName = fileName;
		}

		// Now switch to the previous open file.
		if ( prevFileName != null ) {
			switchOpenFile( prevFileName );
		} else if ( endFileName != null ) {
			switchOpenFile( endFileName );
		}
	}


	/**
	* Select next open file.
	*/
	public void doNextFile() {
		String curFileName = currentFileName();
		
		// Browse the list of open files and locate the current one.	
		Enumeration e=openfiles.keys();
		while (e.hasMoreElements()) {
			String fileName = (String) e.nextElement();
			if ( fileName == curFileName ) {
				break;
			}
		}

		// Now switch to the next open file.
		if ( e.hasMoreElements() ) {
			switchOpenFile((String) e.nextElement() );
		} else {
			switchOpenFile();
		}
	}

	/**
	* Returns the currently selected file's pathname.
	*/
	private String currentFileName() {
		TextHandler txth=(TextHandler)jpe.getTextHandler();
		if ( txth.getEditFile() != null ) {
			return(txth.getEditFile().getName());
		} else {
			return(null);
		}
	}

}
