/*
 *  Draco Econometrics
 *  Copyright (C) 2006-2007 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.main.ui;

import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JButton;

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

import com.approximatrix.draco.application.ApplicationManager;
import com.approximatrix.draco.application.ChildFrame;
import com.approximatrix.draco.datamodel.Constant;
import com.approximatrix.draco.datamodel.StatTableModel;
import com.approximatrix.draco.datamodel.VariableModel;

/*
 * Created on Feb 7, 2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */

import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.util.ArrayList;

/**
 * @author jeff
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class ColumnStats extends ChildFrame implements ActionListener {

	private static final String DIALOG_NAME = " Statistics";
	
	/** The string for requesting topical help */
	private static final String HELP_KEY = "columnstats";
	
	/** The icon to be displayed for this child window */
	private static final String PATH_TO_ICON = "/com/approximatrix/draco/main/ui/images/stats.png";
	
	private javax.swing.JPanel jContentPane = null;

	private StatTableModel current_model = null;
	private String column_name = null;
	
	private JScrollPane jScrollPane = null;

	private JTable jTable = null;
	private JMenuItem to_constant_menuitem = null;
	private JButton to_constant_button = null;
	
	/**
	 * This is the default constructor
	 */
	
	public ColumnStats(StatTableModel information, String column_name) {
		super(column_name + DIALOG_NAME, 
				true, //resizable
				true, //closable
				true, //maximizable
				true);
		initialize();
		
		this.setTitle(column_name + DIALOG_NAME);
		
		// Need to store the StatTableModel in case we wish to create a constant
		this.current_model = information;
		this.column_name = column_name;
		
		VariableModel vmod = information.getVariable(information.getColumnNumber(column_name));
		this.getJTable().setModel(new StatisticsTableModel(vmod));
		
		//mean_textfield.setText(new Double(information.getColumnMean(column_name)).toString());
		//stdev_textfield.setText(new Double(information.getColumnStandardDeviation(column_name)).toString());
		//max_textfield.setText(new Double(information.getColumnMaximumValue(column_name)).toString());
		//min_textfield.setText(new Double(information.getColumnMinimumValue(column_name)).toString());
		
	}
	
	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
		this.setTitle("Column Statistics");
		this.setSize(323, 205);
		this.setContentPane(getJContentPane());
		//this.setVisible(true);
		this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
		//this.addWindowListener(new java.awt.event.WindowAdapter() { 
		//	public void windowClosing(java.awt.event.WindowEvent e) {    
		//		dispose();
		//	}
		//});
		super.setIcon(PATH_TO_ICON);
	}
	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private javax.swing.JPanel getJContentPane() {
		if(jContentPane == null) {
			jContentPane = new javax.swing.JPanel();
			jContentPane.setLayout(new java.awt.BorderLayout());
			jContentPane.add(getJScrollPane(), BorderLayout.CENTER);
		}
		return jContentPane;
	}

	/**
	 * This method initializes jScrollPane	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getJScrollPane() {
		if (jScrollPane == null) {
			jScrollPane = new JScrollPane();
			jScrollPane.setViewportView(getJTable());
		}
		return jScrollPane;
	}
	/**
	 * This method initializes jTable	
	 * 	
	 * @return javax.swing.JTable	
	 */
	private JTable getJTable() {
		if (jTable == null) {
			jTable = new JTable();
			jTable.setRowSelectionAllowed(true);
			jTable.setColumnSelectionAllowed(false);
		}
		return jTable;
	}
	
	private void toConstant() {
		int row = getJTable().getSelectedRow();
		if(row >= 0 && row < getJTable().getRowCount()) {
			String name = ((StatisticsTableModel)getJTable().getModel()).getShortName(row);
			String fullname = new String(column_name+"_"+name);
			
			Object value = ((StatisticsTableModel)getJTable().getModel()).getStatValue(row);
			
			if(Number.class.isAssignableFrom(value.getClass())) {
				boolean found = false;
				for(int i=0;i<current_model.getConstants().size();i++) {
					found = fullname.compareTo(((Constant)current_model.getConstants().get(i)).getName())==0;
					if(found) {
						((Constant)current_model.getConstants().get(i)).setValue((Number)value);
						break;
					}
				}
				if(!found)
					current_model.getConstants().add(new Constant(fullname,(Number)value));
				
				this.getMainWindow().updateConstantsDialog();
			}
				
		}
	}
	
	private class StatisticsTableModel extends AbstractTableModel {
		private static final int ROW_COUNT = 0;
		private static final int ROW_MEAN = 1;
		private static final int ROW_MEDIAN = 2;
		private static final int ROW_VARIANCE = 3;
		private static final int ROW_STDEV = 4;
		private static final int ROW_MAX = 5;
		private static final int ROW_MIN = 6;
		
		private final String[] names = {"Observations", 
				                        "Mean", 
				                        "Median", 
				                        "Variance", 
				                        "Standard Deviation",
			                            "Maximum Value", 
			                            "Minimum Value" };
		
		private final String[] short_names = {"obs",
				                              "mean",
				                              "median",
				                              "var",
				                              "std",
				                              "max",
				                              "min"	};
		
		private VariableModel model = null;
		
		public StatisticsTableModel(VariableModel variable){
			model = variable;
		}
		
		/** Returns 2 always
		 * 
		 */
		public int getColumnCount() {
			return 2;
		}
		
		/** Returns the number of statistics to display
		 * 
		 */
		public int getRowCount() {
			return names.length;
		}
		
		/** Returns the column headings
		 * 
		 */
		public String getColumnName(int col) {
			switch(col) {
				case 0:
					return "Statistic";
				case 1:
					return "Value";
				default:
					return "Error...";
			}
		}
		
		public Object getValueAt(int row, int col) {
			if(col == 0) 
				return getStatName(row);
			else
				return getStatValue(row);
		}
		
		private String getStatName(int row) {
			return names[row];
		}
		
		public String getShortName(int row) {
			if(row >=0 && row < short_names.length)
				return short_names[row];
			else
				return "err";
		}
		
		public Object getStatValue(int row) {
			
			switch(row) {
				case ROW_COUNT:
					return new Integer(model.getObservationCount());
				case ROW_MEAN:
					return model.getMean();
				case ROW_MEDIAN:
					return model.getMedian();
				case ROW_VARIANCE:
					try {
						return new Double(Math.pow(model.getColumnStandardDeviation().doubleValue(),2.0));
					} catch (NullPointerException npe) {
						return null;
					}
				case ROW_STDEV:
					return model.getColumnStandardDeviation();
				case ROW_MAX:
					return model.getMaximumValue();
				case ROW_MIN:
					return model.getMinimumValue();
				default:
					return null;
			}
		}
		
	}
	
	/** Constructs if necessary and returns an array of JMenu objects
	 * to be integrated into the MainWindow menus
	 * 
	 * @return a valid array of JMenu objects, completely constructed
	 */
	public JMenu[] getMenuItems() {
		if(menuItems == null) {
			ArrayList menus = new ArrayList();
			
			JMenu data_menu = DynamicMainMenuBar.GetGenericDataMenu();
			
			to_constant_menuitem = new JMenuItem("Selection to Constant");
			to_constant_menuitem.addActionListener(this);
			data_menu.add(to_constant_menuitem);
			
			menus.add(data_menu);
			
			menuItems = new JMenu[menus.size()];
			menus.toArray(menuItems);
		}
		return menuItems;
	}

	/** Constructs (if necessary) and returns an array of components for display
	 * on the main window toolbar.  In this class, the array contains buttons and
	 * separators.
	 * 
	 * @return an array of toolbar items
	 */
	public Component[] getToolbarButtons() {
		if(toolbarButtons == null) {
			ArrayList buttons = new ArrayList();
			
			to_constant_button = new JButton();
			to_constant_button.setToolTipText("Selection to Constant");
			to_constant_button.setIcon(ApplicationManager.GetIcon("ADD"));
			to_constant_button.addActionListener(this);
			buttons.add(to_constant_button);
			
			toolbarButtons = new Component[buttons.size()];
			buttons.toArray(toolbarButtons);
		}
		return toolbarButtons;
	}

	/** The statistics window can be renamed if you like
	 * 
	 * @return true
	 */
	public boolean isRenameable() {
		return true;
	}
	
	/** Handles menu items and toolbar clicks for the constants window
	 * 
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
		Object source = e.getSource();
		
		// Sort through the possible sources
		if(source == to_constant_menuitem || source == to_constant_button)
			this.toConstant();
		
	}

	/** Returns the help key for the Column Statistics window
	 * 
	 * @return the proper help key, defined by HELP_KEY
	 * @see #HELP_KEY
	 * @see com.approximatrix.draco.application.ChildFrame#getHelpKey()
	 */
	public String getHelpKey() {
		return HELP_KEY;
	}
	
 }  //  @jve:decl-index=0:visual-constraint="10,10"
