/*
 *  Draco Econometrics
 *  Copyright (C) 2008-2009 Approximatrix, LLC
 *  http://www.approximatrix.com
 *  
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.approximatrix.draco.application.plugin.ui;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;

import com.approximatrix.draco.application.ChildFrame;
import com.approximatrix.draco.application.plugin.Plugin;
import com.approximatrix.draco.application.plugin.PluginData;
import com.approximatrix.draco.application.plugin.PluginType;
import com.approximatrix.draco.datamodel.StatTableModel;
import com.approximatrix.draco.general.ui.GeneralWorker;
import com.approximatrix.draco.general.ui.InfoWindow;
import com.approximatrix.draco.main.ui.MainWindow;

public class PluginWindow extends ChildFrame implements ActionListener, PluginDataProvidingWindow {

	/** The string for requesting topical help */
	private static final String HELP_KEY = "plugins";
	
	private static final String REGRESSION_PERF_MENU = "Regression";
	private static final String ANALYSIS_PERF_MENU = "Analysis";
	private static final String OPTION_PERF_ITEM = "Options...";
	private static final String REGRESSION_PERF_ITEM = "Compute Regression...";
	private static final String ANALYSIS_PERF_ITEM = "Compute Analysis...";
	
	private static final int WIDTH = 350;
	private static final int HEIGHT = 200;
	
	private Plugin master = null;
	
	private JMenu[] menus = null;
	
	private JMenuItem runItem = null;
	private JMenuItem optItem = null;	
	private JTable selectionTable = null;
	
	public PluginWindow(Plugin plugin, StatTableModel stm) {
		super(plugin.getName(),true,true,true,true);
		master = plugin;
		initialize(stm);
	}
	
	private void initialize(StatTableModel statmodel) {
		JScrollPane spane = new JScrollPane();
		SelectionTableModel stm = new SelectionTableModel(master.getSelectionColumns(),statmodel);
		selectionTable = new JTable(stm);
		spane.setViewportView(selectionTable);
		this.getContentPane().add(spane);
		
		this.addInternalFrameListener(new InternalFrameAdapter() {

			@Override
			public void internalFrameClosing(InternalFrameEvent e) {
				master.dispose();
				super.internalFrameClosing(e);
			}
			
		});
		
		this.setSize(WIDTH, HEIGHT);
	}

	@Override
	public String getHelpKey() {
		return HELP_KEY;
	}

	@Override
	public JMenu[] getMenuItems() {
		if(menus == null) {
			menus = new JMenu[1];
		
			menus[0] = new JMenu(getProcessMenuName());

            optItem = new JMenuItem(OPTION_PERF_ITEM);
            optItem.addActionListener(this);
            menus[0].add(optItem);
            
            if(master == null || master.getOptions().size() == 0)
            	optItem.setEnabled(false);
            
			runItem = new JMenuItem(getProcessItemName());
			runItem.addActionListener(this);
			menus[0].add(runItem);
		}
		return menus;
	}

	@Override
	public Component[] getToolbarButtons() {
		return null;
	}

	@Override
	public boolean isRenameable() {
		return true;
	}

	private String getProcessMenuName() {
		if(master.getType() == PluginType.regression)
			return REGRESSION_PERF_MENU;
		else if(master.getType() == PluginType.analysis)
			return ANALYSIS_PERF_MENU;
		else
			return "Perform";
	}
	
	private String getProcessItemName() {
		if(master.getType() == PluginType.regression)
			return REGRESSION_PERF_ITEM;
		else if(master.getType() == PluginType.analysis)
			return ANALYSIS_PERF_ITEM;
		else
			return "Perform";
	}

	public void actionPerformed(ActionEvent e) {
	    if(e.getSource() == runItem)
    		runPlugin();
        else if(e.getSource() == optItem)
            new PluginOptionDialog(this, master.getOptions());
	}
	
	private void runPlugin() {
		new GeneralWorker(this.getMainWindow(),
				"Executing "+master.getName(),"Computing...",
				
				new GeneralWorker.WorkRoutine() {
					public void doWork() {
						try {
							master.execute();
							final String results = master.getResults();

							SwingUtilities.invokeLater(new Runnable() {
								public void run() {
									PluginWindow.this.getMainWindow().openWindow(new InfoWindow(master.getName()+" Results",results,false,true));
								}
							});
							
							SwingUtilities.invokeLater(new Runnable() {
								public void run() {
									PluginWindow.this.selectionTable.setEnabled(false);
								}
							});
						} catch(Exception e) {
							final Exception tpe = e;
							SwingUtilities.invokeLater(new Runnable() {
								public void run() {
									new PluginErrorDialog(PluginWindow.this.getMainWindow(),master.getName()+" Error",tpe).setVisible(true);
								}
							});
						}
					}
				});
	}
	
	public Plugin getPlugin() {
		return master;
	}
	
	/* (non-Javadoc)
	 * @see com.approximatrix.draco.application.plugin.ui.PluginDataProvidingWindow#getPluginData()
	 */
	public PluginData getPluginData() {
	    return getPlugin();
	}
	
	public MainWindow getMainWindow() {
		return super.getMainWindow();
	}

}
