package org.greenstone.gatherer.feedback;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import javax.swing.text.*;
import java.io.*;
import java.awt.image.*;
import java.util.Locale;
import java.util.ResourceBundle;
import java.text.MessageFormat;
import javax.swing.border.*;
import java.text.*;

import org.greenstone.gatherer.util.JarTools;

/**
 * This is the special class listener. 
 * <p>This class will record all the action did to any of the
 * component inside the window that were open by the application. 
 * <br> This listener will start listening since the beginning of the application 
 * until the user quits from the application. It will record :
 * <br>1. All the information about the window and its components where the action occured.
 * <br>2. All the information about all windows and its components that were open when the action occured.
 * <br>Note : point 1 and 2 only start when user wants to send feedback.
 * <br>3. The action's command the user did.
 * <br>4. The date of when the action occured.
 * <br><br>The history of the action will be stored in history.log file, which then will be compressed
 * to a zip file called MyZipFile.zip.</p>
 * <p>The listener this class implements are only the listener interface that a javax.swing.* component
 * could have as stated in API.Some of the listener however is not implemented here as it is considered the event
 * listened by those listener are not essential to be recorded as they not making any major changes
 * to the application.</p> 
 * <p>This listener will only record maximum last 60 instructions user did to the application.</p>
 * <p>In this class also we can add some stuff globally through out all the window open by
 * the application.
 * <br>This is the class will add a menu called Feedback through out all the window of type JFrame or JDialog
 * open by the application.This menu will allow user to either sending feedback or viewing the history
 * of all the action user did so far.
 * @author Veronica Liesaputra
 */
public class ActionRecorderDialog
    implements ActionListener,TreeModelListener,ItemListener,ListDataListener,ChangeListener,
	       ListSelectionListener,MenuListener,TableColumnModelListener,TreeSelectionListener
{
    /**
     * This hold the title of the window where the action occured.
     */
    private String myframe;

    /**
     * This hold the title of the window where user called send feedback.
     */
    private String feedbackframe;

    /**
     * This hold the instance of ComponentInformation to get all the information inside a window.
     */
    private ComponentInformation compInfo;
    
    /**
     * This will hold a record of the action that user just did at the moment.
     */
    private History log;

    /**
     * This will reference to the window where the action occured.
     */
    private Window point;
   
    /**
     * This hold the vector of all the History instances of all the record of action user did
     * so far.
     * This vector will hold the history of all the 30 actions user just did.
     * There are 2 situation for this vector :
     * <br>1. Before user choose to send feedback.
     * <br>Here, If we want to add another record to the vector when the vector size already 30 then,
     * all the 30 records inside the vector will be saved in the temp_history.log file. The vector will
     * be cleared and then added with the new record.
     * <br>If the user quits the application, then whats in the vector will be saved to history.log file.
     * <br>2. After user choose to send feedback.
     * <br>When user choose to send feedback,then what happen is what ever inside the vector at the moment
     * will be saved to history.log file and then vector will be cleared and it will add the new instruction.
     * <br> If we want to add another record to the vector when the vector size already 30 then,
     * all the 30 records inside the vector will be saved in the temp_feedbackhist.log file. The vector will
     * be cleared and then added with the new record.
     * <br> If the user finished with the feedback then it will cleared all the vector and load the vector
     * inside the history.log to it and add the new record to the vector.
     * <br> If the user quits the application, then whats in the vector will not be saved.
     */
    private static Vector vector;

    /**
     * This is the flag to tell whether or not the image for the window where the action occured is
     * finished being added properly to the appropriate record.
     * If savefinish = true then it means that the thread of adding image to the record stop, otherwise
     * it means its not yet finished so don't stop the thread.
     */
    private static boolean savefinish = true;

    /**
     * This is the thread that contains all the code that the application should be when the user exiting
     * the application.
     */
    private Thread writeThread;

    /**
     * This is the thread that contains all the code to add the image of the window where the action
     * occured to the proper record.
     * This thread will stop if savefinish = true.
     */
    private Thread saveThread;

    /**
     * This is the runtime of this application.
     */
    private Runtime run;

    /**
     * This variable will hold the resource of the words that is stored in feedback.properties file.
     * The calling using messages.getString(someString) will caused someString to be translated
     * into some other string that is hold in that file.usually it will caused it to be translated
     * to the language that the user use or choose to have as stated in Locale.
     */
    private static ResourceBundle messages;

    /**
     * This is an instance of ScreenShot that will allow this application to take screen shot of the whole
     * screen or just the screen shot of the window where the actions occured.
     */
    private ScreenShot sh;

    /**
     * This HashMap stored the pair of model and its component.
     * This will allow this listener to know which component the model where the actions occured belongs to.
     */
    private HashMap modelHash;

    /**
     * This is the flag variable to sign that the user start the Reporting Feedback sequence.
     * If start_rec = false means that the user did not start reporting feedback sequence.
     * Otherwise, it means the user start reporting feedback sequence, here there will be changes in the
     * content of the vector used to save all the records.This also will change the appearance of the
     * window that are currently open by the application. it will make toolbar value = true, rec = true and
     * stop_rec = false.
     */
    private boolean start_rec = false;

    /**
     * This is the flag variable to sign that the user are now recording the Reporting Feedback sequence.
     * If rec = true, it means its recording, otherwise its false.It also will decide
     * the GUI appearance of the window that are currently open by the application.
     */
    private boolean rec = false;

    /**
     * This is the flag variable to sign that user are finished the Reporting Feedback sequence.
     * If stop_rec = false, then it means user stop the Reporting Feedback sequence.So here, there will
     * be changes in the vector's content. If rec = true then it will also delete the added toolbar on the currently open
     * window by the application and its also will delete all the history and file taken when user doing the
     * Reporting Feedback sequence.
     */
    private boolean stop_rec = true;

    /**
     * This is the thread do task to take history of the actions.
     */
    private Thread saveallThread;

    /**
     * This is the flag to say whether or not the send feedback button been pushed by user.
     */
    private boolean start_fd = false;

    /**
     * This is a blocker to say that user cannot do anything while we taking history.
     */
    private MouseListener mouse_blocker_listener = new MouseAdapter() {};

    /**
     * This is the feedback interface window.
     */
    private FeedbackInterface frame;

    /**
     * This is an instance of CompListener that will add listener to all the components inside it.
     */
    private CompListener compList;

    /**
     * This is the accelerator key (shortcuts key) for taking screenshot.
     */
    private KeyStroke shKey;

    /**
     * This is the accelerator key (shortcuts key) for reporting feedback.
     */
    private KeyStroke fdKey;

    /**
     * This is the accelerator key (shortcuts key) for viewing history.
     */
    private KeyStroke histKey;

    /**
     * This is the accelerator key (shortcuts key) for sending feedback straight away.
     */
    private KeyStroke sndfdKey;

    /**
     * This is the window that is active at the moment.
     */
    private Window activeWindow;

    /**
     * This is the modal window where user wants to take the screeshot or sending feedback.
     */
    private Window modalWindow;

    /**
     * This constructor will seeting up the data member to its appropriate value.
     * It will get the vector that are stored in the history.log file and also it will
     * setup the writeThread.
     * @param currentLocale is the locale user choose all the text to be displayed as.
     */
    public ActionRecorderDialog (Locale currentLocale)
    {
	messages = ResourceBundle.getBundle("feedback",currentLocale);
	setup_UIManager();

	fdKey = KeyStroke.getKeyStroke("F2");
	histKey = KeyStroke.getKeyStroke("F3");
	shKey = KeyStroke.getKeyStroke("F5");
	sndfdKey = KeyStroke.getKeyStroke("F12");
	/*shKey = KeyStroke.getKeyStroke(KeyEvent.VK_SLASH,InputEvent.CTRL_MASK|
	  InputEvent.SHIFT_MASK);*/

	final ZipFile zip;
	zip = new ZipFile();
	zip.unZipFile();
	vector = getPrev_log("history.log");
	sh = new ScreenShot();
	modelHash = new HashMap();
	compInfo = new ComponentInformation(this,currentLocale,modelHash);
        compList = new CompListener(this,modelHash);
	EventQueue eq;
	eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
	eq.push(new MyEventQueue());
	run = Runtime.getRuntime();
	Runnable writeRun;
	writeRun = new Runnable()
	    {
		public void run()
		{
		    try
			{
			    if (stop_rec == true)
				{
				    File f;
				    f = new File("history.log");
				    FileOutputStream fos;
				    fos = new FileOutputStream("history.log");
				    ObjectOutputStream oos;
				    oos = new ObjectOutputStream(fos);
				    oos.writeObject(vector);
				    vector.removeAllElements();
				    vector = getPrev_log("temp_history.log");
				    oos.writeObject(vector);
				    oos.close();
				    f = new File("temp_history.log");
				    f.delete();
				}

			    File f2;
			    f2 = new File("feedbackhist.log");
			    f2.delete();
			    f2 = new File("temp_feedbackhist.log");
			    f2.delete();

			    zip.sendZipFile();
			    writeThread = null;
			}
		    catch (IOException exp) {}
		}
	    };

	writeThread = new Thread(writeRun);
	run.addShutdownHook(writeThread);
    }

    /** change the locale for the resource bundle*/
    public void setLocale(Locale loc) {
	messages = ResourceBundle.getBundle("feedback",loc);
    }
    /**
     * This method will setup some of the GUI appearance that window should have when the user
     * choose to start the Reporting Feedback sequence.
     */
    public void setup_UIManager ()
    {
	// why do you do all this???
	//UIManager.put("TabbedPane.selected",(new Color(224,240,224)));
	//UIManager.put("Button.select",(new Color(224,240,224)));
	//UIManager.put("ScrollBar.background",(new Color(176,208,176)));
	//UIManager.put("ScrollBar.highlight",(new Color(224,240,224)));
	//UIManager.put("ScrollBar.thumb",(new Color(224,240,224)));
	//UIManager.put("ScrollBar.track",(new Color(224,240,224)));
	//UIManager.put("Tree.textBackground",new Color(224,240,224));
	//UIManager.put("Label.font",new Font("Dialog",Font.PLAIN,12));
	//UIManager.put("ComboBox.font",new Font("Dialog",Font.PLAIN,12));
	//UIManager.put("TextArea.font",new Font("Dialog",Font.PLAIN,12));
    }

    /**
     * This method will get the information about all the components inside the window that are
     * open by the application when the action occured and save it to vector.
     * @param comp its the component where the user did the action.
     * @param command its the action's command the user did.
     */
    private void saving (final Component comp,final String command)
    {
	if ((command.equals(messages.getString("SendFeedback"))) ||
	    ((command.equals("FastSend")) && (stop_rec == false)))
	    {
		start_fd = true;
	    }

	Runnable saveall;
	saveall = new Runnable ()
	    {
		public void run ()
		{
		    try
			{
			    Runnable savework;
			    savework = new Runnable ()
				{
				    public void run ()
				    {
					Date curr_date;
					curr_date = new Date();
					log = new History(curr_date,command);

					if ((start_fd == true)&&(command.equals(messages.getString("WindowOpened"))))
					    {
						start_rec = true;
						rec = true;
						start_fd = false;
					    }

					getFrame(comp,command);
					saveState(command);
					saveLog();

					if ((point != null) && (rec == true))
					    {
						if (command.equals(messages.getString("WindowClosed")))
						    {
							if (point instanceof JDialog)
							    if (((JDialog)point).isModal() == true)
								if (point == modalWindow)
								    frame.setComment(false);
						    }
					    }
				    }
				};

			    SwingUtilities.invokeAndWait(savework);
			}
		    catch (Exception ex) {ex.printStackTrace();}
		}
	    };

	saveallThread = new Thread(saveall);
	saveallThread.start();
    }

    /**
     * This method will get the screen shot of the window where the actions occured and
     * add the image also its dimension to the passed record.
     * It will caused the saveThread to start so it can allows other stuff to be run concurrently
     * and this thread will be stopped when the screen shot of the window alreadyfinished taken.
     * @param hst is the record where the image and its dimension should be stored to.
     */
    public void saveImage (final History hst)
    {
	Runnable saveRun;
	saveRun = new Runnable()
	    {
		History hist = hst;
		public void run()
		{
		    String img,width,height;
		    Rectangle rect;
		    int w, h,dimwidth,dimheight;
		 
		    if (point != null)
			{
			    dimwidth = sh.getWidth();
			    dimheight = sh.getHeight();

			    w = point.getWidth();
			    h = point.getHeight();

			    try
				{
				    rect = new Rectangle(point.getLocationOnScreen(),
							 new Dimension(w,h));
			    
				    if (w >= dimwidth)
					w = dimwidth - 50;
				    
				    width = "" +  w;
				    
				    if (h >= dimheight)
					h = dimheight - 50;
				    
				    height = "" + h;
				}
			    catch (IllegalComponentStateException exp)
				{
				    rect = null;
				    width = null;
				    height = null;
				}
			}
		    else
			{
			    rect = null;
			    width = null;
			    height = null;
			}
		    
		    if (rect != null)
			{
			    img = sh.getImage(rect);
			    if (savefinish == true)
				{
				    hist.setImage(img,height,width);
				}
			}
		}
	    };
	
	Thread saveThread;
	saveThread = new Thread(saveRun);
	saveThread.start();
    }

    /**
     * This method will setup the savefinish value.
     * (Precondition: (save != null))
     * @param save the value savefinish should have.
     */
    public static void setSavefinish (boolean save)
    {
	savefinish = save;
    }


    /**
     * This method will make the JMenu that is should be added to all the
     * window opened by the application.
     * <br>If rec = false then the JMenu will give user option to start the Reporting Feedback sequence
     * or Sending feedback or to view the history of actions they have done so far.
     * <br>If rec = true then the JMenu will only give user option to view the history of actions
     * they have done so far or sending feedback or taking screenshot.
     * @return JMenu that should be added to all window open.
     */
    public JMenu makeMenu ()
    {
	JMenu menu;
	JMenuItem item,item2,item3;
	ImageIcon icon,icon2,icon3;

	icon3 = JarTools.getImage("fastsend.gif");
	item3 = new JMenuItem(messages.getString("SendFeedback"), 
			      new ImageIcon(icon3.getImage().getScaledInstance
					    (20,20,Image.SCALE_SMOOTH)));
	item3.setActionCommand("FastSend");
	item3.addActionListener(this);
	item3.setMnemonic(KeyEvent.VK_N);
	item3.setAccelerator(sndfdKey);
	item3.setToolTipText("Send feedback now");

	item = null;

	if (rec == false)
	    {
		icon = JarTools.getImage("feedback.gif");
		item = new JMenuItem("Report Feedback",
				     new ImageIcon(icon.getImage().getScaledInstance
						   (20,20,Image.SCALE_SMOOTH)));
		item.setActionCommand(messages.getString("SendFeedback"));
		item.addActionListener(this);
		item.setMnemonic(KeyEvent.VK_F);
		item.setAccelerator(fdKey);
		item.setToolTipText("Report feedback");
	    }
	else
	    {
		icon = JarTools.getImage("camera.gif");
		item = new JMenuItem(messages.getString("ScreenShot"),
				     new ImageIcon(icon.getImage().getScaledInstance
						   (20,20,Image.SCALE_SMOOTH)));
		item.setActionCommand("ScreenShot");
		item.setMnemonic(KeyEvent.VK_S);
		item.addActionListener(this);
		item.setAccelerator(shKey);
		item.setToolTipText("Take screenshot of the whole screen.");
	    }

	icon2 = JarTools.getImage("history.gif");
	item2 = new JMenuItem(messages.getString("LookHistory"),
			      new ImageIcon(icon2.getImage().getScaledInstance
					    (20,20,Image.SCALE_SMOOTH)));
	item2.setActionCommand(messages.getString("LookHistory"));
	item2.addActionListener(this);
	item2.setMnemonic(KeyEvent.VK_H);
	item2.setAccelerator(histKey);
	item2.setToolTipText(messages.getString("LookHistoryButton"));

	menu = new JMenu (messages.getString("Feedback"));
	menu.setMnemonic(KeyEvent.VK_D);


	if (item != null)
	    menu.add(item);

	menu.add(item3);

	menu.add(item2);

	if (rec == true)
	    menu.setBackground(new Color(176,209,217));
	else
	    menu.setBackground(new Color(204,204,204));

	return menu;
    }

    public void refreshLocationAndSize(Window window) {

	window.setLocation(window.getX(),window.getY());
	
	Toolkit kit;
	kit = Toolkit.getDefaultToolkit();
	Dimension screenSize;
	screenSize = kit.getScreenSize();
	int screenHeight;
	screenHeight = screenSize.height;
	int screenWidth;
	screenWidth = screenSize.width;
	
	if ((window.getSize().width > screenWidth) &&
	    (window.getSize().height > screenHeight)) {
	    window.setSize(window.getPreferredSize());
	}
    }


    /**
     * This method will setup the GUI that this window should have at the moment.
     * If start_rec is true then JMenu don't have the option to start Reporting Feedback sequence in it.
     * If stop_rec is true and rec is true then JMenu there should be an option to start Reporting Feedback sequence in it.
     * The JMenu will only be affected window of type JDialog and JFrame only.
     * (Precondition: (window != null))
     * @param window its the window that we want to set the GUI
     */
    public void setUI (Window window)
    {	
	if (start_rec == true) {
	    if (window instanceof JFrame) {
		JFrame a;
		a = (JFrame) window;
		
		JMenuBar menuBar;
		menuBar = a.getJMenuBar();
		
		if (menuBar != null) {
		    
		    JMenu temp_menu;
		    temp_menu = menuBar.getMenu(menuBar.getMenuCount() - 1);
		    temp_menu.setBackground(new Color(176,209,217));
		    temp_menu.remove(0);
		    
		    JMenuItem item;
		    ImageIcon icon;
		    icon = JarTools.getImage("camera.gif");
		    item = new JMenuItem(messages.getString("ScreenShot"),
					 new ImageIcon(icon.getImage().getScaledInstance
						       (20,20,Image.SCALE_SMOOTH)));
		    item.setActionCommand("ScreenShot");
		    item.setMnemonic(KeyEvent.VK_S);
		    item.addActionListener(this);
		    item.setAccelerator(shKey);
		    item.setToolTipText("Take screenshot of this window");
		    
		    temp_menu.insert(item,0);
		}
		
		refreshLocationAndSize(a);
		a.validate();
		a.repaint();
	    }
	    else if (window instanceof JDialog) {
		
		JDialog a;
		a = (JDialog) window;
		JMenuBar menuBar;
		menuBar = a.getJMenuBar();
		
		if (menuBar != null) {
		    
		    JMenu temp_menu;
		    temp_menu = menuBar.getMenu(menuBar.getMenuCount() - 1);
		    temp_menu.setBackground(new Color(176,209,217));
		    temp_menu.remove(0);
		    
		    JMenuItem item;
		    ImageIcon icon;
		    icon = JarTools.getImage("camera.gif");
		    item = new JMenuItem(messages.getString("ScreenShot"),
					 new ImageIcon(icon.getImage().getScaledInstance
						       (20,20,Image.SCALE_SMOOTH)));
		    item.setActionCommand("ScreenShot");
		    item.setMnemonic(KeyEvent.VK_S);
		    item.addActionListener(this);
		    item.setAccelerator(shKey);
		    item.setToolTipText("Take screenshot of this window");
		    
		    temp_menu.insert(item,0);
		}
		refreshLocationAndSize(a);
		a.validate();
		a.repaint();	
	    }
	    else if (window instanceof JWindow) {
		JWindow a;
		a = (JWindow) window;
		
		((JComponent) a.getContentPane()).unregisterKeyboardAction(fdKey);
		
		((JComponent) a.getContentPane()).registerKeyboardAction(this, "ScreenShot", shKey,JComponent.WHEN_IN_FOCUSED_WINDOW);
	    }
	    else
		return;
	}
	else {
	    
	    if ((stop_rec == true) && (rec == true)) {
		
		if (window instanceof JFrame) {
		    JFrame a;
		    a = (JFrame) window;
		    
		    JMenuBar menuBar;
		    menuBar = a.getJMenuBar();
		    
		    if (menuBar != null) {
			
			JMenu temp_menu;
			temp_menu = menuBar.getMenu(menuBar.getMenuCount() - 1);
			temp_menu.setBackground(new Color(204,204,204));
			temp_menu.remove(0);
			
			ImageIcon icon;
			JMenuItem item;
			
			icon = JarTools.getImage("feedback.gif");
			item = new JMenuItem("Report Feedback", new ImageIcon(icon.getImage().getScaledInstance(20,20,Image.SCALE_SMOOTH)));
			item.setActionCommand(messages.getString("SendFeedback"));
			item.addActionListener(this);
			item.setMnemonic(KeyEvent.VK_F);
			item.setAccelerator(fdKey);
			item.setToolTipText(messages.getString("SendFeedbackButton"));
			
			temp_menu.insert(item,0);
		    }
		    a.setSize(a.getPreferredSize());
		    a.validate();
		    a.repaint();
		}
		else if (window instanceof JDialog) {
		    JDialog a;
		    a = (JDialog) window;
		    
		    JMenuBar menuBar;
		    menuBar = a.getJMenuBar();
		    
		    if (menuBar != null) {
			
			JMenu temp_menu;
			temp_menu = menuBar.getMenu(menuBar.getMenuCount() - 1);
			temp_menu.setBackground(new Color(204,204,204));
			temp_menu.remove(0);
			
			ImageIcon icon;
			JMenuItem item;
			
			icon = JarTools.getImage("feedback.gif");
			item = new JMenuItem("Report Feedback", new ImageIcon(icon.getImage().getScaledInstance(20,20,Image.SCALE_SMOOTH)));
			item.setActionCommand(messages.getString("SendFeedback"));
			item.addActionListener(this);
			item.setMnemonic(KeyEvent.VK_F);
			item.setAccelerator(fdKey);
			item.setToolTipText(messages.getString("SendFeedbackButton"));
			
			temp_menu.insert(item,0);
		    }
		    a.setSize(a.getPreferredSize());
		    a.validate();
		    a.repaint();
		}
		else if (window instanceof JWindow) {
		    JWindow a;
		    a = (JWindow) window;
		    
		    ((JComponent) a.getContentPane()).registerKeyboardAction(this, messages.getString("SendFeedback"), fdKey, JComponent.WHEN_IN_FOCUSED_WINDOW);
		    
		    ((JComponent) a.getContentPane()).unregisterKeyboardAction(shKey);
		    
		}
		else
		    return;
	    }
	    else
		return;
	}
    }
    
    /**
     * This will make an Window[] convert to ArrayList that contain list of Window.
     * (Precondition: (windows != null))
     * @param windows the array that we want to convert to ArrayList
     * @return        the array list that contains all object in array windows.
     */
    public ArrayList addToArrayList (Window[] windows,ArrayList arr)
    {
	int i;

	for (i = 0 ; i < windows.length ; i++)
	    {
		arr.add(windows[i]);
	    }
	
	return arr;
    }

    /**
     * This method will get all the information of the window that are currently open when the action
     * occured and these windows are not the window where the action occured.
     * It will add these windows information to the current record and it will also setting up the 
     * GUI for each of these windows.
     * @param command the action's command user did.
     */
    public void saveState(String command)
    {
	Window[] frame_windows;
	ArrayList windows;
	Frame[] frames;
	int i,j;

	if (log == null)
	    return;
	
	windows = new ArrayList();

	frames = Frame.getFrames();
	for (i = 0 ; i<frames.length;i++) 
	    {
		frame_windows = frames[i].getOwnedWindows();
		windows = addToArrayList(frame_windows,windows);
		
		for (j = 0;j < frame_windows.length ; j++)
		    {
			Window window;
			window = frame_windows[j];

			if (window == point)
			    {
				Container cont;
				cont = window.getParent();

				if ((cont != null) && (cont instanceof Window) &&
				    (windows.contains(cont) == false)&&(cont != point))
				    {
					if (cont instanceof ReportDetails.View) {}
					else if (cont instanceof Movie) {}
					else
					    {
						setUI((Window) cont);
						
						/*if (rec == true)
						    {
							log.addComponent(compInfo.getInside((Window) cont),
									 messages.getString("CurrentlyOpenWindow"));
						    }
						    else*/
						    compList.getInside((Window) cont);
						
						windows.add(cont);
					    }
				    }	
				else
				    {}
			    }
			else
			    {
				if (window instanceof ReportDetails.View) {}
				else if (window instanceof Movie) {}
				else
				    {
					if ((window != null) && (window != point))
					    {
						setUI(window);
						
						if (rec == true)
						    {
							log.addComponent(compInfo.getInside((Window) window),
									 messages.getString("CurrentlyOpenWindow"));
						    }
						else
						    compList.getInside((Window) window);
						
						Container cont;
						cont = window.getParent();
						
						if ((cont != null) && (cont instanceof Window) &&
						    (cont != point) && (windows.contains(cont) == false))
						    {
							if (cont instanceof ReportDetails.View) {}
							else if (cont instanceof Movie) {}
							else
							    {
								setUI((Window)cont);
								
								/*if (rec == true)
								    {
									log.addComponent(compInfo.getInside((Window) cont),
											 messages.getString("CurrentlyOpenWindow"));
								    }
								    else*/
								    compList.getInside((Window) cont);

								windows.add(cont);
							    }
						    }
						else {}
					    }
				    }
			    }
		    }
	    }
    }

    /**
     * This method will get all the information about the window where the actions occured and it also will setting up
     * how hthe GUI should look like in this window and it will also take the image of this window.
     * @param comp is the component where the actions happened.
     * @param command is the command of user's action
     */
    public void getFrame (Component comp,String command)
    {
	boolean cls;
	
	cls = false;
	point = null;
	
	Container frame; 
	myframe = null;
	
	if (comp == null)
	    return;
	else if (comp instanceof Window)
	    frame = (Container) comp;
	else
	    frame = SwingUtilities.getWindowAncestor(comp);
	
	if (frame instanceof Window)
	    {
		JMenu menu;
		point = (Window) frame;

		point.addMouseListener(mouse_blocker_listener);
		point.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

		
		if ((frame instanceof ReportDetails.View)||
		    (frame instanceof Movie))
		    {
			log = null;
			return;
		    }
		
		if (command.equals(messages.getString("WindowClosed")))
		    {
			cls = true;
			if (frame instanceof FeedbackInterface)
			    {
				stop_rec = true;
			    }
			else
			    {}
		    }
		
		if  (command.equals(messages.getString("WindowOpened")))
		    {
			menu = makeMenu();
		    }
		else
		    {
			menu = null;
		    }
		
		if (frame instanceof JFrame)
		    {
			JFrame a;
			a = (JFrame) frame;
			
			myframe = a.getTitle();
			
			if (menu != null)
			    {
				JMenuBar menuBar;
				menuBar = a.getJMenuBar();
				
				if (menuBar == null)
				    {
					menuBar = new JMenuBar();
					menuBar.add(menu);
					a.setJMenuBar(menuBar);
				    }
				else
				    menuBar.add(menu);
			    }
			
			if ((menu != null))
			    {
				refreshLocationAndSize(a);
				a.validate();
				a.repaint();
			    }
		    }
		else if (frame instanceof JDialog)
		    {   
			JDialog a;
			a = (JDialog) frame;
			
			myframe = a.getTitle();
			
			if (menu != null)
			    {
				JMenuBar menuBar;
				menuBar = a.getJMenuBar();
				
				if (menuBar == null)
				    {
					menuBar = new JMenuBar();
					menuBar.add(menu);
					a.setJMenuBar(menuBar);
				    }
				else
				    menuBar.add(menu);
			    }
		    
			if ((menu != null))
			    {
				refreshLocationAndSize(a);
				a.validate();
				a.repaint();
			    }
		    }
		else if (frame instanceof JWindow)
		    {
			JWindow a;
			a = (JWindow) frame;
			
			if (menu != null)
			    {
				((JComponent) a.getContentPane()).registerKeyboardAction(this,
											 messages.getString("LookHistory"),
											 histKey,
											 JComponent.WHEN_IN_FOCUSED_WINDOW);
				
				if (rec == false)
				    {
					((JComponent) a.getContentPane()).registerKeyboardAction(this,
												 messages.getString("SendFeedback"),
												 fdKey,
												 JComponent.WHEN_IN_FOCUSED_WINDOW);
					
					((JComponent) a.getContentPane()).unregisterKeyboardAction(shKey);
				    }
				else
				    {
					((JComponent) a.getContentPane()).unregisterKeyboardAction(fdKey);
					
					((JComponent) a.getContentPane()).registerKeyboardAction(this,
												 "ScreenShot",
												shKey,
												 JComponent.WHEN_IN_FOCUSED_WINDOW);
				    }
			    }

			if (cls == true)
			    {
				((JComponent) a.getContentPane()).unregisterKeyboardAction(fdKey);
				
				((JComponent) a.getContentPane()).unregisterKeyboardAction(shKey);
			    }
		    }
		
		/*if ((command.equals(messages.getString("WindowClosed")))||
		  (log == null))
		  {}
		  else
		  saveImage(log);*/

		/*if (rec == true)
		    log.addComponent(compInfo.getInside(point),command);
		    else*/
		    compList.getInside(point);

		if (myframe == null)
		    myframe = " ";
		
		log.setTitle(myframe);
		
		return;
	    }
	else
	    return;
    }

    /**
     * This method will add the current record to the vector.
     */
    public void saveLog()
    {
	if (start_rec == true)
	    {
		save_HistLog("history.log");
		vector.removeAllElements();
		System.gc();
		start_rec = false;
		stop_rec = false;
		rec = true;
	    }
	
	if (log != null)
	    vector.add(0,log);

	if (vector.size() > 30)
	    {
		if (rec == false)
		    {
			save_tempHistLog("history.log");
		    }
		else
		    save_tempHistLog("feedbackhist.log");
		vector.removeAllElements();
		//vector.removeElementAt(vector.size() - 1);
		System.gc();
	    }

	if ((rec == true) && (stop_rec == true))
	    {
		save_HistLog("feedbackhist.log");
		vector.removeAllElements();
		System.gc();
		vector = getPrev_log("history.log");
		File f2;
		f2 = new File("feedbackhist.log");
		f2.delete();
		f2 = new File("temp_feedbackhist.log");
		f2.delete();
		start_rec = false;
		stop_rec = true;
		rec = false;
	    }

	if (point != null)
	    {
		point.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
		point.removeMouseListener(mouse_blocker_listener);
	    }
    }

    /**
     * This method will save whatever in the vector at the moment to a file
     * with the specified filename.
     * Then it will also save the vector inside the file with the name "temp_"
     * concatenated with the specified filename into it.
     * (Precondition : (filename != null))
     * @param filename its the name of the file where the vector should be saved.
     */
    public void save_HistLog(String filename)
    {
	 try 
	     {
		 File f;
		 f = new File(filename);
		 FileOutputStream fos;
		 fos = new FileOutputStream(f);
		 ObjectOutputStream oos;
		 oos = new ObjectOutputStream(fos);
		 oos.writeObject(vector);
		 vector.removeAllElements();
		 System.gc();
		 vector = getPrev_log("temp_"+ filename);
		 oos.writeObject(vector);
		 oos.close();
		 f = new File("temp_" + filename);
		 f.delete();
		 writeThread = null;
	     }
	 catch (IOException exp) {}
    }
   
    /**
     * This method will save whatever in the vector at the moment to a file with a 
     * name "temp_" concatenated with the specified filename into it.
     * (Precondition : (filename != null))
     * @param filename its part of the name of the file where the vector should be saved.
     */
    public void save_tempHistLog(String filename)
    {
	try
	    {
		File f;
		f = new File("temp_"+ filename);
		FileOutputStream fos;
		fos = new FileOutputStream(f);
		ObjectOutputStream oos;
		oos = new ObjectOutputStream(fos);
		oos.writeObject(vector);
		oos.close();
	    }
	catch (IOException exp) {}
    }

    /**
     * This method will get vector that is stored in a file with the specified filename and
     * it will also save the second vector in that file to a file with a name
     * temp_history.log.
     * If file with the specified filename does not exist then it will return a new vector.
     * (Precondition : (filename != null))
     * @param filename is the name of the file where we want to get the vector.
     * @return         the first vector saved in the file with the specified filename.
     */
    public Vector getPrev_log(String filename)
    {
	Vector stack;
	ObjectInputStream ois;
	stack = null;
	try
	    {
		File f;
		f = new File(filename);
		if (f.exists() == true)
		    {
			FileInputStream fis;
			fis = new FileInputStream(f);
			ois = new ObjectInputStream(fis);
			stack = (Vector) ois.readObject();

			Vector stack2;
			stack2 = null;

			try
			    {
				stack2 = (Vector) ois.readObject();
			    }
			catch (EOFException e) {stack2 = null;}
			
			if (stack2 != null)
			    {
				File f2;
				f2 = new File("temp_history.log");
				FileOutputStream fos;
				fos = new FileOutputStream(f2);
				ObjectOutputStream oos;
				oos = new ObjectOutputStream(fos);
				oos.writeObject(stack2);
				oos.close();
				stack2.removeAllElements();
				stack2 = null;
				System.gc();
			    }

			ois.close();
			return stack;
		    }
		else
		    stack = new Vector(); 
	    }
	catch (IOException exp) {exp.printStackTrace();}
	catch (ClassNotFoundException exp2) {System.out.println("class exp");}
	
	return stack;
    }
 
    /**
     * This method will make sure that there is something running at the moment.
     */
    private static void ensureEventThread()
    {
	if (SwingUtilities.isEventDispatchThread())
	    {
		return;
	    }
	throw new RuntimeException("something running");
    }
    
    /**
     * This method will called the Conformation window to show up.
     * @param err_array this is the array containing all the information taken when user doing the Feedback form.
     * @param imgFile this is the array conataining the String representation of the images taken when user doing the 
     *                Feedback form.
     */
    /*public void getVector(String[] err_array,String[] imgFile)
    {
	Conformation rd;
	rd = new Conformation(vector,err_array,imgFile,messages);
	return;
	}*/

    /**
     * This method will get the vector that hold the history.
     * @return the vector that hold the history stored so far.
     */
    public Vector getVector()
    {
	return vector;
    }

    /**
     * This class will catch the window opened and window closed event.
     * If an application open or close a window it will be listened by this class so the information
     * about that window and all the other open window can be took.
     */
    class MyEventQueue extends EventQueue
    { 
	/**
	 * This method  will catch the window opened and window closed event.
	 * If an application open or close a window it will be listened by this class so the information
	 * about that window and all the other open window can be took.
	 * @param evt its the event.
	 */
	protected void dispatchEvent(AWTEvent evt) 
	{
	    super.dispatchEvent(evt);
	    int id;
	    id = evt.getID();
	
	    if ((id == WindowEvent.WINDOW_OPENED)||(id == WindowEvent.WINDOW_CLOSED))
		{   
		    String command;
		    command = " ";
		    
		    if (id == WindowEvent.WINDOW_OPENED) command = messages.getString("WindowOpened");
		    else if (id == WindowEvent.WINDOW_CLOSED) command = messages.getString("WindowClosed");
		   
		    WindowEvent e;
		    e = (WindowEvent) evt;
		    Window comp;
		    comp =  e.getWindow();
		 
		    if ((comp instanceof ReportDetails.View)||
			(comp instanceof Movie))
			return;

		    saving(comp,command);
		}
	}
    }

    /**
     * This method will take the screenshot of the whole screen.
     * @param p the window where user select to take screenshot.
     * @return  the screenshot image.
     */
    //public byte[] recreateEvent (final Window p)
    public BufferedImage recreateEvent (final Window p)
    {
	setup_UIManager();
	Rectangle rect;
	int w, h;
	
	if (p != null)
	    {
		w = p.getWidth();
		h = p.getHeight();
		
		try
		    {
			rect = new Rectangle(p.getLocationOnScreen(),
				 	     new Dimension(w,h));
		    }
		catch (IllegalComponentStateException exp)
		    {
			rect = null;
		    }
	    }
	else
	    {
		rect = null;
	    }
	
	if (rect != null)
	    {
		//byte[] img;
		BufferedImage img;
		img = sh.captureScreen();
		
		return img;
	    }
	else
	    return null;
    }

    /**
     * This method will listen to any action event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the ActionEvent.
     */
    public void actionPerformed(ActionEvent e)
    {
	String command;
	command = e.getActionCommand();
	Component comp;
	comp = (Component)e.getSource();
	
	saving(comp,command);

	if (myframe == null)
	    myframe = " ";
	
	if("FastSend".equals(e.getActionCommand()))
	    {
		point.addMouseListener(mouse_blocker_listener);
		point.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

		BufferedImage img;
		boolean modal;
			
		modal = false;

		img = recreateEvent(point);
		
		if (stop_rec == true)
		    {
			feedbackframe = myframe;
			
			JDialog.setDefaultLookAndFeelDecorated(true);
			stop_rec = false;
			frame = null;
			frame = new FeedbackInterface(sh,feedbackframe,messages,this);
			if ((img != null) && (savefinish == true))
			    {
				int x,y,w,h,iw,ih;
				double wrat,hrat;
				Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
				
				iw = (int) (dim.getWidth() - 60);
				ih = (int) (dim.getHeight() * 0.75) - 50;
				
				wrat = iw/((double)dim.getWidth());
				hrat = ih/((double)dim.getHeight());
				
				w = (int) (point.getWidth() * wrat);
				h = (int) (point.getHeight() * hrat);
				x = (int) (point.getLocationOnScreen().x * wrat);
				y = (int) (point.getLocationOnScreen().y * hrat);

				//frame.addScreenPanel(feedbackframe,sh.getBuffImage(),img);
				frame.addScreenPanel(feedbackframe,img,x,y,w,h);
			    }
			frame.setVisible(false);
		    }
		else
		    {
			if ((img != null) &&(savefinish == true))
			    {
				int x,y,w,h,iw,ih;
				double wrat,hrat;
				Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
				
				iw = (int) (dim.getWidth() - 60);
				ih = (int) (dim.getHeight() * 0.75) - 50;
				
				wrat = iw/((double)dim.getWidth());
				hrat = ih/((double)dim.getHeight());
				
				w = (int) (point.getWidth() * wrat);
				h = (int) (point.getHeight() * hrat);
				x = (int) (point.getLocationOnScreen().x * wrat);
				y = (int) (point.getLocationOnScreen().y * hrat);
				
				//frame.addScreenPanel(feedbackframe,sh.getBuffImage(),img);
				if (point instanceof JDialog)
				    modal = ((JDialog) point).isModal();
				
				feedbackframe = myframe;
				frame.addScreenPanel(feedbackframe,img,x,y,w,h);
			    }
		    }
		
		ActionEvent evt;
		evt = new ActionEvent(frame.send_button,ActionEvent.ACTION_PERFORMED,messages.getString("Send"));
		
		frame.actionPerformed(evt);

		point.removeMouseListener(mouse_blocker_listener);
		point.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));		 
	    }

	if(messages.getString("SendFeedback").equals(e.getActionCommand()))
	    {
		setup_UIManager();
		//byte[] img;
		BufferedImage img;
		boolean modal;

		point.addMouseListener(mouse_blocker_listener);
		point.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

		modal = false;
		
		img = recreateEvent(point);
		feedbackframe = myframe;
		if (point instanceof JDialog)
		    modal = ((JDialog)point).isModal();
			
		JDialog.setDefaultLookAndFeelDecorated(true);
		stop_rec = false;
		frame = null;
		frame = new FeedbackInterface(sh,feedbackframe,messages,this);
		if ((img != null) && (savefinish == true))
		    {
			int x,y,w,h,iw,ih;
			double wrat,hrat;
			Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();

			iw = (int) (dim.getWidth() - 60);
			ih = (int) (dim.getHeight() * 0.75) - 50;
			
			wrat = iw/((double)dim.getWidth());
			hrat = ih/((double)dim.getHeight());
			
			w = (int) (point.getWidth() * wrat);
			h = (int) (point.getHeight() * hrat);
			x = (int) (point.getLocationOnScreen().x * wrat);
			y = (int) (point.getLocationOnScreen().y * hrat);
		
			//frame.addScreenPanel(feedbackframe,sh.getBuffImage(),img);
			frame.addScreenPanel(feedbackframe,img,x,y,w,h);
			frame.setComment(modal);
			
			if (modal == true)
			    {
				modalWindow = point;
			    }
		    }

		point.removeMouseListener(mouse_blocker_listener);
		point.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));	
	    }
	
	if ("ScreenShot".equals(e.getActionCommand()))
	    {
		point.addMouseListener(mouse_blocker_listener);
		point.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

		//byte[] img;
		BufferedImage img;
		boolean modal;
		modal = false;
		img = recreateEvent(point);
		
		if ((img != null) &&(savefinish == true))
		    {
			int x,y,w,h,iw,ih;
			double wrat,hrat;
			Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();

			iw = (int) (dim.getWidth() - 60);
			ih = (int) (dim.getHeight() * 0.75) - 50;
			
			wrat = iw/((double)dim.getWidth());
			hrat = ih/((double)dim.getHeight());
			
			w = (int) (point.getWidth() * wrat);
			h = (int) (point.getHeight() * hrat);
			x = (int) (point.getLocationOnScreen().x * wrat);
			y = (int) (point.getLocationOnScreen().y * hrat);

			//frame.addScreenPanel(feedbackframe,sh.getBuffImage(),img);
			if (point instanceof JDialog)
			    modal = ((JDialog) point).isModal();

			feedbackframe = myframe;
			frame.addScreenPanel(feedbackframe,img,x,y,w,h);
			frame.setComment(modal);

			if (modal == true)
			    modalWindow = point;
		    }

		point.removeMouseListener(mouse_blocker_listener);
		point.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));	
	    }

	if (messages.getString("LookHistory").equals(e.getActionCommand()))
	    {
		point.addMouseListener(mouse_blocker_listener);
		point.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

		setup_UIManager();
		ReportDetails rd;
		rd = new ReportDetails(vector,null,null,messages,rec);

		point.removeMouseListener(mouse_blocker_listener);
		point.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));	
	    }
    }
   

    /**
     * This method will listen to any Change event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the ChangeEvent.
     */
    public void stateChanged(ChangeEvent e)
    {
	String command;
	command = messages.getString("ChangeState");
	Object obj;
	obj = e.getSource();
	
	Component comp;

	if (obj instanceof Component)
	    {
		comp = (Component)e.getSource();
	    }
	else
	    {
		if (modelHash.containsKey(obj) == true)
		    {
			comp = (Component) modelHash.get(obj);
		    }
		else
		    {
			comp = null;
			System.out.println("weird" + obj.toString());
		    }
	    }
	
	saving(comp,command);
    }

    /**
     * This method will listen to any tree selection event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the TreeSelectionEvent.
     */
    public void valueChanged(TreeSelectionEvent e)
    {
	MutableTreeNode node;
        node = (MutableTreeNode)
	    (e.getPath().getLastPathComponent());
	
	if (node == null) return;

	Object obj;
	obj = e.getSource();
	
	Component comp;

	if (obj instanceof Component)
	    {
		comp = (Component)e.getSource();
	    }
	else
	    {
		if (modelHash.containsKey(obj) == true)
		    {
			comp = (Component) modelHash.get(obj);
		    }
		else
		    {
			comp = null;
			System.out.println("weird" + obj.toString());
		    }
	    }
	
	String command;
	command = messages.getString("Node") + " ";
	if (node instanceof DefaultMutableTreeNode)
	    command = command + ((DefaultMutableTreeNode)node).getUserObject() + " ";
	command = command + messages.getString("ValueChanged");
	
	saving(comp,command);
    }

    /**
     * This method will listen to any tree nodes change in the tree model event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the TreeModelEvent.
     */
    public void treeNodesChanged(TreeModelEvent e)
    {
	MutableTreeNode node;
        node = (MutableTreeNode)
                 (e.getTreePath().getLastPathComponent());

	try {
            int index;
	    index = e.getChildIndices()[0];
            node = (MutableTreeNode)(node.getChildAt(index));
        } catch (NullPointerException exc) {}

	Object obj;
	obj = e.getSource();
	
	Component comp;

	if (obj instanceof Component)
	    {
		comp = (Component)e.getSource();
	    }
	else
	    {
		if (modelHash.containsKey(obj) == true)
		    {
			comp = (Component) modelHash.get(obj);
		    }
		else
		    {
			comp = null;
			System.out.println("weird" + obj.toString());
		    }
	    }

	String command;
	command = messages.getString("Node");

	if (node instanceof DefaultMutableTreeNode)
	    command = command + " "  + ((DefaultMutableTreeNode)node).getUserObject();

	command = command + " " + messages.getString("Change");
	
	saving(comp,command);
    }

    /**
     * This method will listen to any tree nodes inserted in the tree model event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the TreeModelEvent.
     */
    public void treeNodesInserted(TreeModelEvent e)
    {
	MutableTreeNode node;
        node = (MutableTreeNode)
                 (e.getTreePath().getLastPathComponent());

	try {
            int index;
	    index = e.getChildIndices()[0];
            node = (MutableTreeNode)(node.getChildAt(index));
        } catch (NullPointerException exc) {}
	
	Object obj;
	obj = e.getSource();
	
	Component comp;

	if (obj instanceof Component)
	    {
		comp = (Component)e.getSource();
	    }
	else
	    {
		if (modelHash.containsKey(obj) == true)
		    {
			comp = (Component) modelHash.get(obj);
		    }
		else
		    {
			comp = null;
			System.out.println("weird" + obj.toString());
		    }
	    }
	
	String command;
	command = messages.getString("Node");
	if (node instanceof DefaultMutableTreeNode)
	    command = command + " "  + ((DefaultMutableTreeNode)node).getUserObject();

	command = command + " " + messages.getString("Inserted");
	
	saving(comp,command);
    }
    
    /**
     * This method will listen to any tree nodes removed in the tree model event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the TreeModelEvent.
     */
    public void treeNodesRemoved(TreeModelEvent e)
    {
	MutableTreeNode node;
        node = (MutableTreeNode)
                 (e.getTreePath().getLastPathComponent());

	try {
            int index;
	    index = e.getChildIndices()[0];
            node = (MutableTreeNode)(node.getChildAt(index));
        } catch (NullPointerException exc) {}

	Object obj;
	obj = e.getSource();
	
	Component comp;

	if (obj instanceof Component)
	    {
		comp = (Component)e.getSource();
	    }
	else
	    {
		if (modelHash.containsKey(obj) == true)
		    {
			comp = (Component) modelHash.get(obj);
		    }
		else
		    {
			comp = null;
			System.out.println("weird" + obj.toString());
		    }
	    }

	String command;
	command = messages.getString("Node");
	if (node instanceof DefaultMutableTreeNode)
	    command = command + " "  + ((DefaultMutableTreeNode)node).getUserObject();
	command = command + " " + messages.getString("Removed");
	
	saving(comp,command);
    }
 
    /**
     * This method will listen to any tree structure change in the tree model event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the TreeModelEvent.
     */
    public void treeStructureChanged(TreeModelEvent e)
    {
	Object obj;
	obj = e.getSource();
	
	Component comp;

	if (obj instanceof Component)
	    {
		comp = (Component)e.getSource();
	    }
	else
	    {
		if (modelHash.containsKey(obj) == true)
		    {
			comp = (Component) modelHash.get(obj);
		    }
		else
		    {
			comp = null;
			System.out.println("weird" + obj.toString());
		    }
	    }
	
	String command;
	command = messages.getString("TreeStructuredChanged");
	
	saving(comp,command);
    }

    /**
     * This method will listen to any item state change in the item  event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the ItemEvent.
     */
    public void itemStateChanged(ItemEvent e)
    {
	Component comp;
	comp = (Component) e.getSource();
	String command;
	command = ((String) e.getItem()) + " " + 
	    messages.getString("ItemStateChanged");

	saving(comp,command);
    } 

    /**
     * This method will listen to any contents change in the list data event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the ListDataEvent.
     */
    public void contentsChanged (ListDataEvent e)
    {
	Object obj;
	obj = e.getSource();
	
	Component comp;

	if (obj instanceof Component)
	    {
		comp = (Component)e.getSource();
	    }
	else
	    {
		if (modelHash.containsKey(obj) == true)
		    {
			comp = (Component) modelHash.get(obj);
		    }
		else
		    {
			comp = null;
			System.out.println("weird" + obj.toString());
		    }
	    }
	
	String command;
	command = messages.getString("ListChanged");

	saving(comp,command);
    } 

    /**
     * This method will listen to any interval added in the list data event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the ListDataEvent.
     */
    public void intervalAdded (ListDataEvent e)
    {
	Object obj;
	obj = e.getSource();
	
	Component comp;

	if (obj instanceof Component)
	    {
		comp = (Component)e.getSource();
	    }
	else
	    {
		if (modelHash.containsKey(obj) == true)
		    {
			comp = (Component) modelHash.get(obj);
		    }
		else
		    {
			comp = null;
			System.out.println("weird" + obj.toString());
		    }
	    }
	
	String command;
	command = messages.getString("ListContentsAdded");

	saving(comp,command);
    } 

    /**
     * This method will listen to any interval removed in the list data event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the ListDataEvent.
     */
    public void intervalRemoved (ListDataEvent e)
    {
	Object obj;
	obj = e.getSource();
	
	Component comp;

	if (obj instanceof Component)
	    {
		comp = (Component)e.getSource();
	    }
	else
	    {
		if (modelHash.containsKey(obj) == true)
		    {
			comp = (Component) modelHash.get(obj);
		    }
		else
		    {
			comp = null;
			System.out.println("weird" + obj.toString());
		    }
	    }

	String command;
	command = messages.getString("ListContentRemoved");

	saving(comp,command);
    }

    /**
     * This method will listen to any value changed in the list data event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the ListDataEvent.
     */
    public void valueChanged (ListSelectionEvent e)
    {
	Object obj;
	obj = e.getSource();
	
	Component comp;

	if (obj instanceof Component)
	    {
		comp = (Component)e.getSource();
	    }
	else
	    {
		if (modelHash.containsKey(obj) == true)
		    {
			comp = (Component) modelHash.get(obj);
		    }
		else
		    {
			comp = null;
			System.out.println("weird" + obj.toString());
		    }
	    }

	String command;
	command = messages.getString("ListValueChanged");

	saving(comp,command);
    }

    /**
     * This method will listen to any menu canceled in the menu event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the MenuEvent.
     */
    public void menuCanceled (MenuEvent e)
    {
	Component comp;
	comp = (Component) e.getSource();
	String command;
	command = messages.getString("MenuCanceled");

	saving(comp,command);
    }

    /**
     * This method will listen to any menu deselected in the menu event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the MenuEvent.
     */
    public void menuDeselected (MenuEvent e)
     {
	Component comp;
	comp = (Component) e.getSource();
	String command;
	command = messages.getString("MenuDeselected");

	saving(comp,command);
    }

    /**
     * This method will listen to any menu selected in the menu event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the MenuEvent.
     */
    public void menuSelected(MenuEvent e)
    {
	Component comp;
	comp = (Component) e.getSource();
	String command;
	command = messages.getString("MenuSelected");

	saving(comp,command);
    }

    /**
     * This method will listen to any column added in the table column model event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the TableColumnModelEvent.
     */
    public void columnAdded (TableColumnModelEvent e)
    {
	Object obj;
	obj = e.getSource();
	
	Component comp;

	if (obj instanceof Component)
	    {
		comp = (Component)e.getSource();
	    }
	else
	    {
		if (modelHash.containsKey(obj) == true)
		    {
			comp = (Component) modelHash.get(obj);
		    }
		else
		    {
			comp = null;
			System.out.println("weird" + obj.toString());
		    }
	    }

	String command;
	command = messages.getString("ColumnIndex") + " "  + e.getToIndex() 
	    + messages.getString("AddedToTable");

	saving(comp,command);
    }

    public void columnMarginChanged(ChangeEvent e) {}

    /**
     * This method will listen to any column moved in the table column model event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the TableColumnModelEvent.
     */
    public void columnMoved(TableColumnModelEvent e)
    {
	Object obj;
	obj = e.getSource();
	
	Component comp;

	if (obj instanceof Component)
	    {
		comp = (Component)e.getSource();
	    }
	else
	    {
		if (modelHash.containsKey(obj) == true)
		    {
			comp = (Component) modelHash.get(obj);
		    }
		else
		    {
			comp = null;
			System.out.println("weird" + obj.toString());
		    }
	    }

	String command;
	command = messages.getString("ColumnIndexFrom") + " " + 
	    e.getFromIndex() + " " + 
	    messages.getString("MovedToColumnIndex") + " "  + e.getToIndex() +
	    " " + messages.getString("InTheTable");

	saving(comp,command);
    }

    /**
     * This method will listen to any column removed in the table column model event that occured.
     * It will allow this special listener class to record all the information inside all the
     * window open when the action occured.
     * @param e the TableColumnModelEvent.
     */
    public void columnRemoved(TableColumnModelEvent e)
    {
	Object obj;
	obj = e.getSource();
	
	Component comp;

	if (obj instanceof Component)
	    {
		comp = (Component)e.getSource();
	    }
	else
	    {
		if (modelHash.containsKey(obj) == true)
		    {
			comp = (Component) modelHash.get(obj);
		    }
		else
		    {
			comp = null;
			System.out.println("weird" + obj.toString());
		    }
	    }

	String command;
	command = messages.getString("ColumnIndex") + " "  + e.getFromIndex() +
	    " " + messages.getString("RemovedFromTheTable");

	saving(comp,command);
    }

    public void columnSelectionChanged(ListSelectionEvent e) {}
}










