/*
 *  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.general.ui;

import javax.swing.JDialog;

import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JTable;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.table.*;
import javax.swing.ListCellRenderer;
import javax.swing.UIManager;


import com.approximatrix.draco.application.ChildFrame;
import com.approximatrix.draco.datamodel.IndepListModel;

import java.awt.Color;
import java.awt.Component;

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

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

	private static final String DIALOG_NAME = "Matrix Viewer";
	
	/** The string for requesting topical help */
	private static final String HELP_KEY = "matrixview";
	
	private javax.swing.JPanel jContentPane = null;
	private JScrollPane jScrollPane = null;
	private MatrixViewModel this_mv = null;
	
	private JTable matrixview_table = null;
	
	/**
	 * This is the default constructor
	 */
	public MatrixView(String[] row_names, String[] column_names, double[][] data) {
		super(DIALOG_NAME, 
				true, //resizable
				true, //closable
				true, //maximizable
				true);
		initialize();
		
		this_mv = new MatrixViewModel(column_names,data,row_names.length);
		matrixview_table.setModel(this_mv);
	}
	
	public MatrixView(double[][] data) {
		super(DIALOG_NAME, 
				true, //resizable
				true, //closable
				true, //maximizable
				true);
		initialize();
		
		this_mv = new MatrixViewModel(data);
		matrixview_table.setModel(this_mv);
		
		this.setTitle(DIALOG_NAME);
	}
	
	public MatrixView(String title, double[][] data) {
		super(title, 
				true, //resizable
				true, //closable
				true, //maximizable
				true);
		initialize();
		
		this_mv = new MatrixViewModel(data);
		matrixview_table.setModel(this_mv);
		
		this.setTitle(title);
	}
	
	public MatrixView(String title, String[] row_names, String[] column_names, double[][] data) {
		super(title, 
				true, //resizable
				true, //closable
				true, //maximizable
				true);
		initialize();
		
		this_mv = new MatrixViewModel(column_names,data,row_names.length);
		matrixview_table.setModel(this_mv);
		
		IndepListModel lm = new IndepListModel(row_names);
		matrixview_table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		JList rowHeader = new JList(lm);
		rowHeader.setBackground(jContentPane.getBackground());
		rowHeader.setFixedCellWidth(75);
		rowHeader.setFixedCellHeight(matrixview_table.getRowHeight());
        //        					 + matrixview_table.getRowMargin());
		jScrollPane.setRowHeaderView(rowHeader);
		rowHeader.setCellRenderer(new RowHeaderRenderer(matrixview_table));
		
		this.setTitle(title);
	}
	
	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(300,200);
		this.setContentPane(getJContentPane());
		this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		//this.addWindowListener(new java.awt.event.WindowAdapter() { 
		//	public void windowClosing(java.awt.event.WindowEvent e) {    
		//		close_window();
		//	}
		//});
	}
	/**
	 * 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(), java.awt.BorderLayout.CENTER);
		}
		return jContentPane;
	}
	/**
	 * This method initializes jScrollPane	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */    
	private JScrollPane getJScrollPane() {
		if (jScrollPane == null) {
			jScrollPane = new JScrollPane();
			jScrollPane.setViewportView(getMatrixview_table());
		}
		return jScrollPane;
	}
	
	/**
	 * This method initializes jTable	
	 * 	
	 * @return javax.swing.JTable	
	 */    
	private JTable getMatrixview_table() {
		if (matrixview_table == null) {
			matrixview_table = new JTable();
			matrixview_table.setCellSelectionEnabled(true);
		}
		return matrixview_table;
	}
	
	private class MatrixViewModel extends AbstractTableModel {
		
		private String[][] celldata = null;
		private String[] columnNames = null;
		
		private int numberRows;
		
		public MatrixViewModel(double[][] data) {
			numberRows = data.length;
			columnNames = new String[data[1].length];
			for(int i=0;i<data[1].length;i++) {
				columnNames[i] = new Integer(i).toString();
			}
			
			// insert the row names in the first column
			for(int i=0;i<numberRows;i++) {
				for(int j=0;j<columnNames.length;j++) {
					celldata[i][j] = new Double(data[i][j]).toString();
				}
			}
			
		}
		
		public MatrixViewModel(String[] col_names, double[][] data,int rows) {
			columnNames = col_names;
			
			celldata = new String[rows][columnNames.length];
			
			// insert the row names in the first column
			for(int i=0;i<rows;i++) {
				for(int j=0;j<col_names.length;j++) {
					celldata[i][j] = new Double(data[i][j]).toString();
				}
			}
			
			numberRows = rows;
		}
		
		public String getColumnName(int col) {
	        return columnNames[col].toString();
	    }
	    public int getRowCount() { return numberRows; }
	    public int getColumnCount() { return columnNames.length; }
	    public Object getValueAt(int row, int col) {
	        return celldata[row][col];
	    }
	    public boolean isCellEditable(int row, int col)
	        { return true; }
	    public void setValueAt(Object value, int row, int col) {
	    	//celldata[row][col] = value.toString();
	        fireTableCellUpdated(row, col);
	    }
	    
	}

	private class RowHeaderRenderer extends JLabel implements ListCellRenderer {
		
		RowHeaderRenderer(JTable table) {
			JTableHeader header = table.getTableHeader();
			setOpaque(true);
			setBorder(UIManager.getBorder("TableHeader.cellBorder"));
			setHorizontalAlignment(CENTER);
			setForeground(header.getForeground());
			setBackground(header.getBackground());
			setFont(header.getFont());
		}
		
		public Component getListCellRendererComponent( JList list, 
				Object value, int index, boolean isSelected, boolean cellHasFocus) {
			setText((value == null) ? "" : value.toString());
			return this;
		}
	}

	/** This simple window has no menu options
	 * 
	 * @return null since there are no menu items
	 * @see com.approximatrix.draco.application.ChildFrame#getMenuItems()
	 */
	public JMenu[] getMenuItems() {
		return null;
	}

	/** This simple window has no toolbar buttons
	 * 
	 * @return null since there are no toolbar buttons
	 * @see com.approximatrix.draco.application.ChildFrame#getToolbarButtons()
	 */
	public Component[] getToolbarButtons() {
		return null;
	}

	/** All matrix views are renamable
	 * 
	 * @return true
	 * @see com.approximatrix.draco.application.ChildFrame#isRenameable()
	 */
	public boolean isRenameable() {
		return true;
	}

	/** Returns the help key for the Matrix Viewer 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="62,24"
