/*
 * Created on 11.01.2004 17:36:28
 *
 * Multimediale Algorithmen und Datenstrukturen Assessments
 */
package generation;

import mauda.*;
import mauda.plugin.*;
import mauda.utils.*;
import mauda.operation.*;

import help.HelpFrame;
import help.HelpTree;
import jedas.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

import java.io.*;
import java.beans.*;
/**
 * The listener for menu- and toolbar-actions
 * 
 * @author Markus Krebs
 */
public class MenuToolBarListener implements ActionListener, ItemListener {

	private Exercise exercise;

	private Vector editTabs;

	private JFileChooser fileChooser;
	private PreviewPanel previewPanel = new PreviewPanel();

	/**
	 * Creates the listener for menu and toolbar-actions
	 * @param exercise Exercise
	 */
	public MenuToolBarListener(Exercise exercise) {
		this.exercise = exercise;
		fileChooser = new JFileChooser(new File(FileLocation.unworkedPath));
		fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
		fileChooser.addChoosableFileFilter(new XMLFilter());
		fileChooser.setMultiSelectionEnabled(false); // Mehrfachselektion AUS
		fileChooser.setAccessory(previewPanel);
		fileChooser.addPropertyChangeListener(new PropertyChangeListener() {
			public void propertyChange(PropertyChangeEvent e) {
				if(e.getPropertyName().equals(
									 JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {
					File f = (File)e.getNewValue();
					if(f==null) return;
					String s = f.getPath(), suffix = null;
					int i = s.lastIndexOf('.');

					if(i > 0 && i < s.length() - 1)
						suffix = s.substring(i+1).toLowerCase();

					if(suffix!=null&&suffix.equals("xml"))
						previewPanel.configure(f);
				}
			}
		});
	}

	protected void setEditTabs(Vector et) {
		this.editTabs = et;
	}
	/* (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
		if(!exercise.actionsAllowed()) return;
		String s = e.getActionCommand();
		//System.out.println("ActionCommand: "+s);
		if(s.startsWith("PLUGIN: ")) {
			if(!dialogDiscardActiveExercise()) return;
			String plugInName = s.substring(8);
			//System.out.println("Selected PlugIn: "+plugInName);
			exercise.switchTo(plugInName);
		} else if(s == ActionCommands.newFile) {
			newFile();
		} else if(s == ActionCommands.openFile) {
			openFile();
			//difficultyButton.setText(Difficulties.getDifficultyGUIString(exercise.getDifficulty()));
		} else if(s == ActionCommands.saveFile) {
			String status = exercise.isReadyToSave();
			if(!status.equals("OK")) { 
				JOptionPane.showMessageDialog(MAUDA.getApplicationMainFrame(), status);
			} else saveFile(exercise.getFilename());
		} else if(s == ActionCommands.saveAsFile) {
			String status = exercise.isReadyToSave();
			if(!status.equals("OK")) { 
				JOptionPane.showMessageDialog(MAUDA.getApplicationMainFrame(), status);
			} else saveAsFile();			
		} else if(s == ActionCommands.dump) {
			/*JOptionPane.showMessageDialog(
					MAUDA.getApplicationMainFrame(),
					exercise.getDSObject() + "\n" +
					"UNDOREDO:\n" +
					exercise.getUndoRedo());*/
			JOptionPane.showMessageDialog(
					MAUDA.getApplicationMainFrame(),
					exercise.getDSObject());
		} else if(s == ActionCommands.meta) {
			exercise.updateMetaDataInitTodoRating();
			boolean mod = exercise.getMetaData().inputDialog();
			if(mod) exercise.setModified(true);
		} else if(s == ActionCommands.automatic) {
			if(exercise.getMode() == ExerciseMode.FAULT) {
				JOptionPane.showMessageDialog(MAUDA.getApplicationMainFrame(), Prop.get(this, "AutomaticFaultModeNotSupported"));
				return;
			}
			if(newFile()) {
				// Bemerkung: folgendes etwas unschön
				InitTab initTab = null;
				ScrambleTab scrambleTab = null;
				AutoGenTab autoGenTab = null;
				Enumeration en = editTabs.elements();
				while(en.hasMoreElements()) {
					EditTab et = (EditTab)en.nextElement();
					if(et instanceof InitTab) initTab = (InitTab)et;
					else if(et instanceof ScrambleTab) scrambleTab = (ScrambleTab)et;
					else if(et instanceof AutoGenTab) autoGenTab = (AutoGenTab)et;
				}
				OperationQueue[] oq =
					GeneralAnalyst.fullAutomatic(exercise.getDSObject(),
						initTab.operationQueue,
						scrambleTab.operationQueue,
						autoGenTab.operationQueue,
						exercise.getDifficulty(),
						exercise.getMode());
				exercise.getOperationRecorder().setTodoPosition(oq[0].length());
				OperationQueue exeOQ = new OperationQueue();
				exeOQ.addAll(oq[0]);
				exeOQ.addAll(oq[1]); 
				exercise.commit(exeOQ);
			}
		} else if(s == ActionCommands.undo) {
			exercise.undo();
		} else if(s == ActionCommands.redo) {
			exercise.redo();
		/*
		} else if(s == ActionCommands.difficulty) {
			exercise.increaseDifficulty();
			((JButton)e.getSource()).setText(Difficulties.getDifficultyGUIString(exercise.getDifficulty()));
		*/
		} else if(s == ActionCommands.difficulty0) {
			exercise.setDifficulty(Difficulties.getID("EASY"));
		} else if(s == ActionCommands.difficulty1) {
			exercise.setDifficulty(Difficulties.getID("MEDIUM"));
		} else if(s == ActionCommands.difficulty2) {
			exercise.setDifficulty(Difficulties.getID("HARD"));			
		} else if(s == ActionCommands.subOperationEdit) {
			/*
			boolean selected = ((java.awt.CheckboxMenuItem)e.getSource()).getState();
			if(selected) exercise.setMode(Exercise.FAULTMODE);
			else exercise.setMode(Exercise.NORMALMODE);
			*/
		} else if(s == ActionCommands.normalMode) {
			exercise.setMode(ExerciseMode.NORMAL);
		} else if(s == ActionCommands.faultMode) {
			exercise.setMode(ExerciseMode.FAULT);
		} else if(s == ActionCommands.exit) {
			if(dialogDiscardActiveExercise()) System.exit(0);
		} else if(s == ActionCommands.showAbout) {
			AboutFrame.createAndShowGUI();
		} else if(s == ActionCommands.showHelp) {
			HelpTree.setView(HelpTree.GENEDITOR_VIEW);
			HelpFrame.createAndShowGUI();
		}
	}
	/* (non-Javadoc)
	 * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)
	 */
	public void itemStateChanged(ItemEvent e) {
		//System.out.println(e.getItem());
		//System.out.println(e.getSource());
		java.awt.CheckboxMenuItem cmi = (java.awt.CheckboxMenuItem)e.getSource();
		String s = cmi.getActionCommand();
		boolean selected = cmi.getState();
		if(s == ActionCommands.subOperationEdit) {
			if(selected) exercise.setInteractiveMode(Exercise.BOTHOPERATION);
			else exercise.setInteractiveMode(Exercise.OPERATION);
		} /*else if(s == ActionCommands.difficultyeasy) {
			exercise.setDifficulty(Difficulties.getDifficultyInt("EASY"));
		} else if(s == ActionCommands.difficultymedium) {
			exercise.setDifficulty(Difficulties.getDifficultyInt("MEDIUM"));
		} else if(s == ActionCommands.difficultyhard) {
			exercise.setDifficulty(Difficulties.getDifficultyInt("HARD"));
		}*/			
	}
	// NEW FILE
	protected boolean newFile() {
		if(!dialogDiscardActiveExercise()) return false;
		exercise.reset();
		Jedas.updateDisplay();
		exercise.setDefaultFilename();
		updateFilenameLabel();
		return true;
	}
	// OPEN FILE
	protected void openFile() {
		if(!dialogDiscardActiveExercise()) return;
		int state = fileChooser.showOpenDialog(null);
		if(state == JFileChooser.APPROVE_OPTION) {
			File file = fileChooser.getSelectedFile();
			if(file.isFile()) openFile(file);
		}
	}
	protected void openFile(File file) {
		String newFilename = file.getAbsolutePath();
				
		HashMap hm = exercise.load(newFilename);

		String editorState = exercise.getMetaData().getEditorState();

		if(!editorState.equals("unworked")) {
			javax.swing.JOptionPane.showMessageDialog(MAUDA.getApplicationMainFrame(), "Cant load a worked-out or evaluated exercise.");
			return;
		}
		if(hm==null) return;	// <-- Sollte nie vorkommen (falls PlugIn nicht existiert)

		exercise.reset();
		
		exercise.load(hm);
		exercise.loadConfig(hm);

		exercise.setFilename(newFilename);
		updateFilenameLabel();
		
		OperationRecorder or = exercise.getOperationRecorder();
		Vector exOps = new Vector();
		exOps.addAll((Vector)or.getInitOperations().clone());
		exOps.addAll((Vector)or.getTodoOperations().clone());
		//System.out.println("EXOPS: "+exOps);
		
		exOps = exercise.addFullLoadedMessage(exOps);

		exercise.getUndoRedo().clear();
		exercise.setDSObject(exercise.getUndoRedo().getDSObject());
		or.clear();

		exercise.commit(exOps);
	}
	// SAVE FILE
	protected void saveFile(String fname) {
		if(fname.equals(exercise.getDefaultFilename())) {
			JOptionPane.showMessageDialog(MAUDA.getApplicationMainFrame(), Prop.get(this, "DialogChooseSaveAs"));
			return;
		}
		exercise.updateMetaDataInitTodoRating();
		exercise.getMetaData().inputDialog();
		exercise.save(fname);
		exercise.setFilename(fname);
		updateFilenameLabel();			
	}
	// SAVE AS FILE
	protected void saveAsFile() {
		int state = fileChooser.showSaveDialog(null);
		if(state == JFileChooser.APPROVE_OPTION) {
			File file = fileChooser.getSelectedFile();
			if(file!=null) {
				String fname = file.getAbsolutePath();
				if(file.exists()&&!dialogExistsOverwrite(fname)) {
					JOptionPane.showMessageDialog(MAUDA.getApplicationMainFrame(), Prop.get(this, "FileNotSaved"));
					return;
				}
				if(!fname.toLowerCase().endsWith(".xml")) {
					fname = fname + ".xml";
				}
				saveFile(fname);
			}
		}
	}
	protected void updateFilenameLabel() {
		/*
		String fn = filename.replace('\\','/');
		fn = fn.substring(fn.lastIndexOf("/")+1);
		filenameLabel.setText(fn);
		*/
	}

	// Datei überschreiben? - Dialog
	private boolean dialogExistsOverwrite(String filename) {
		String s = Prop.get(this, "DialogExistsOverwrite");
		s = s.replaceAll("FILENAME", filename);
		int result = JOptionPane.showConfirmDialog(MAUDA.getApplicationMainFrame(), s, Prop.get(this, "DialogExistsOverwriteTitle"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
		if(result == JOptionPane.YES_OPTION) { return true; }
		//else if(result == JOptionPane.NO_OPTION) { return false; }
		//else if(result == JOptionPane.CANCEL_OPTION) { return false; }
		return false;
	}
	// Aktive Aufgabe verwerfen? - Dialog
	private boolean dialogDiscardActiveExercise() {
		if(!exercise.isModified()) return true;
		String s = Prop.get(this, "DialogDiscardActiveExercise");
		int result = JOptionPane.showConfirmDialog(MAUDA.getApplicationMainFrame(), s, Prop.get(this, "DialogDiscardActiveExerciseTitle"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
		if(result == JOptionPane.YES_OPTION) { return true; }
		//else if(result == JOptionPane.NO_OPTION) { return false; }
		//else if(result == JOptionPane.CANCEL_OPTION) { return false; }
		return false;		
	}

}
