/*
 * MiningMart Version 1.0
 * 
 * Copyright (C) 2006 Martin Scholz, Timm Euler, 
 *                    Daniel Hakenjos, Katharina Morik
 *
 * Contact: miningmart@ls8.cs.uni-dortmund.de
 *
 * A list of contributing developers (other than the copyright 
 * holders) can be found at
 * http://mmart.cs.uni-dortmund.de/downloads/download.html
 * 
 * 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 2
 * 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, see the file MM_HOME/LICENSE; if not, write
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
 * Floor, Boston, MA 02110-1301, USA.
 */
package edu.udo.cs.miningmart.gui.concepteditor;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumnModel;

import org.musoft.limo.application.Application;
import org.musoft.limo.application.Resource;
import org.musoft.limo.drawing.ModelDrawingView;

import edu.udo.cs.miningmart.exception.DbConnectionClosed;
import edu.udo.cs.miningmart.exception.M4Exception;
import edu.udo.cs.miningmart.gui.application.MiningMartApplication;
import edu.udo.cs.miningmart.m4.Column;
import edu.udo.cs.miningmart.m4.Columnset;
import edu.udo.cs.miningmart.m4.Concept;
import edu.udo.cs.miningmart.m4.M4Interface;
import edu.udo.cs.miningmart.m4.utils.Print;

/**
 * This is a <code>JPanel</code> to display the <code>Columnset</code>s of a <code>Condept</code>.
 * 
 * @author Daniel Hakenjos
 * @version $Id: ColumnsetPanel.java,v 1.5 2006/04/11 14:10:17 euler Exp $
 */
public class ColumnsetPanel extends ConceptPanel implements ActionListener{

	private MiningMartApplication app;
	
	private Concept concept;
	
	private Vector columnset;
	
	private JTable columntable,columnsettable;

	private JButton deletecolset,deletecolumn,showstats,showdata, closeButton;

	public ColumnsetPanel(MiningMartApplication app, Concept concept){
		super();
		this.app=app;
		this.concept=concept;
		
		initColumnset();
		initComponents();
	}
	
	/**
	 * Inits the Columnsets
	 */
	private void initColumnset(){
		Object[] sets=new Object[0];

		try {
			sets=concept.getColumnSets().toArray();
		} catch (M4Exception error) {
			M4Interface.print.doPrint(Print.ERROR,error.getMessage(),error);
			return;
		}
		
		columnset=new Vector();
		for(int i=0;i<sets.length;i++){
			columnset.add((Columnset) sets[i]);
		}

	}
	
	/**
	 * Inits the Components.
	 */
	private void initComponents(){
		setLayout(new BorderLayout(5,5));
		setBorder(BorderFactory.createEmptyBorder(5,5,5,5));

		//Info
		JPanel infopanel=new JPanel();
		infopanel.setLayout(new GridLayout(2,1,5,5));
		infopanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
		add(infopanel,BorderLayout.NORTH);	

		JLabel label=new JLabel();
		label.setText(Resource.getString("COLUMNSETS"));
		Font font=new Font("SansSerif",Font.PLAIN,15);
		label.setFont(font);
		label.setHorizontalAlignment(SwingConstants.CENTER);	
		infopanel.add(label);

		label=new JLabel();
		label.setText(concept.getName());
		font=new Font("SansSerif",Font.PLAIN,13);
		label.setFont(font);
		label.setHorizontalAlignment(SwingConstants.CENTER);	
		label.setForeground(Color.BLUE);
		infopanel.add(label);

		//Button		
		
		deletecolset=new JButton(Resource.getString("DELETE_COLUMNSET"));
		deletecolset.addActionListener(this);
		deletecolset.setEnabled(false);
		
		deletecolumn=new JButton(Resource.getString("DELETE_COLUMN"));
		deletecolumn.addActionListener(this);
		deletecolumn.setEnabled(false);
		
		showstats=new JButton(Resource.getString("SHOW_STATISTICS"));
		showstats.addActionListener(this);
		showstats.setEnabled(false);
		
		showdata=new JButton(Resource.getString("SHOW_DATA"));
		showdata.addActionListener(this);
		showdata.setEnabled(false);

		closeButton=new JButton(Resource.getString("CLOSE"));
		closeButton.addActionListener(this);

		JPanel southpanel=new JPanel();
		southpanel.setLayout(new GridLayout(3,1,5,5));

		JPanel buttonPanel=new JPanel();
		buttonPanel.setLayout(new BoxLayout(buttonPanel,BoxLayout.X_AXIS));
		buttonPanel.add(Box.createHorizontalGlue());
		
		buttonPanel.add(deletecolset);
		buttonPanel.add(Box.createRigidArea(new Dimension(5, 0)));		
		buttonPanel.add(deletecolumn);
		southpanel.add(buttonPanel);
		
		buttonPanel=new JPanel();
		buttonPanel.setLayout(new BoxLayout(buttonPanel,BoxLayout.X_AXIS));
		buttonPanel.add(Box.createHorizontalGlue());

		buttonPanel.add(showstats);
		buttonPanel.add(Box.createRigidArea(new Dimension(5, 0)));		
		buttonPanel.add(showdata);
		southpanel.add(buttonPanel);

		buttonPanel=new JPanel();
		buttonPanel.setLayout(new BoxLayout(buttonPanel,BoxLayout.X_AXIS));
		buttonPanel.add(Box.createHorizontalGlue());

		buttonPanel.add(closeButton);
		southpanel.add(buttonPanel);

		add(southpanel,BorderLayout.SOUTH);

		//tables
		columnsettable=new JTable();
		columnsettable.setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		columnsettable.getTableHeader().setReorderingAllowed(false);
		columnsettable.setRowHeight(columnsettable.getRowHeight() + 2);
		columnsettable.setModel(new ColumnsetTableModel());
		ListSelectionModel rowSM = columnsettable.getSelectionModel();
		rowSM.addListSelectionListener(new ListSelectionListener(){
			public void valueChanged(ListSelectionEvent e) {
				//Ignore extra messages.
				if (e.getValueIsAdjusting()) return;
				
				((ColumnTableModel) columntable.getModel()).fireTableDataChanged();
				

				if (columnsettable.getSelectedRow()==-1){
					if (app.getViewMode()==Application.EDITOR){
						deletecolset.setEnabled(false);
					}
					showstats.setEnabled(false);
					showdata.setEnabled(false);
				}else{
					if (app.getViewMode()==Application.EDITOR){
						deletecolset.setEnabled(true);
					}
					showstats.setEnabled(true);
					showdata.setEnabled(true);
				}
			}
		});
		for(int i=0;i<4;i++){
			columnsettable.getColumnModel().getColumn(i).setMinWidth(150);
		}
		columnsettable.getColumnModel().getColumn(4).setMinWidth(300);
		columnsettable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		

		columntable=new JTable();
		columntable.setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		columntable.getTableHeader().setReorderingAllowed(false);
		columntable.setRowHeight(columntable.getRowHeight() + 2);
		columntable.setModel(new ColumnTableModel());
		
		TableColumnModel cmodel=columntable.getColumnModel();
		cmodel.getColumn(cmodel.getColumnCount()-1).setMinWidth(500);
		cmodel.getColumn(cmodel.getColumnCount()-1).setMaxWidth(Integer.MAX_VALUE);
		columntable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

		rowSM = columntable.getSelectionModel();
		rowSM.addListSelectionListener(new ListSelectionListener(){
			public void valueChanged(ListSelectionEvent e) {
				//Ignore extra messages.
				if (e.getValueIsAdjusting()) return;
				
				if (app.getViewMode()!=Application.EDITOR){
					return;
				}

				if (columntable.getSelectedRow()==-1){
					deletecolumn.setEnabled(false);
				}else{
					deletecolumn.setEnabled(true);
				}
			}
		});
		
		//splitpane
		JSplitPane splitpane=new JSplitPane(JSplitPane.VERTICAL_SPLIT,new JScrollPane(columnsettable),new JScrollPane(columntable));
		splitpane.setOneTouchExpandable(true);
		splitpane.setResizeWeight(0.5);
		splitpane.setDividerLocation(splitpane.getSize().width - splitpane.getInsets().bottom 
												- splitpane.getDividerSize() - 150);
		
		add(splitpane,BorderLayout.CENTER);
		
		if (columnsettable.getModel().getRowCount()==1){
			columnsettable.getSelectionModel().setSelectionInterval(0,0);
		}
		
	}

	public String toString(){
		return Resource.getString("COLUMNSETS");
	}

	private void deleteColumnset(){
		int[] rows=columnsettable.getSelectedRows();

		try {
			Columnset colset;		
			for(int i=rows.length-1;i>=0;i--){
				if (rows[i]==-1)
					continue;

				colset=(Columnset) columnset.remove(rows[i]);
				concept.removeColumnset(colset);
				colset.deleteSoon();
			}
			
			((ColumnsetTableModel) columnsettable.getModel()).fireTableDataChanged();
			((ColumnTableModel) columntable.getModel()).fireTableDataChanged();

			app.getModel().setDirty(true);
			((ModelDrawingView) app.getDrawingView()).repaint();
		} catch (M4Exception error) {
			M4Interface.print.doPrint(Print.ERROR,error.getMessage(),error);
		}
		
	}
	
	private void deleteColumn(){
		int[] rows=columntable.getSelectedRows();

		try {
			int row=columnsettable.getSelectedRow();
			if (row==-1)
				return;

			Columnset colset=(Columnset) columnset.get(row);		
			if (colset==null)
				return;
			
			Column col;
			for(int i=rows.length-1;i>=0;i--){
				if (rows[i]==-1)
					continue;

				col=colset.getColumn(rows[i]);
				colset.removeColumn(col);
				col.deleteSoon();
			}
			
			((ColumnTableModel) columntable.getModel()).fireTableDataChanged();

			app.getModel().setDirty(true);
			((ModelDrawingView) app.getDrawingView()).repaint();
		} catch (M4Exception error) {
			M4Interface.print.doPrint(Print.ERROR,error.getMessage(),error);
		}
	}
	
	private void showStatistics(){
		int row=columnsettable.getSelectedRow();
		if (row==-1)
			return;
			
		Columnset colset=(Columnset) columnset.get(row);
		if (colset==null)
			return;
		
		try {
			if (colset.getStatisticsAll()==0){
				JOptionPane.showMessageDialog(
					this.app,
					Resource.getString("INFO_NO_DATA_MSG"),
					Resource.getString("INFO_NO_DATA_TITLE"),
					JOptionPane.INFORMATION_MESSAGE);
				
			}else{
				StatisticsDialog dialog=new StatisticsDialog(app,colset);
			}
		} catch (M4Exception error) {
			M4Interface.print.doPrint(Print.ERROR,error.getMessage(),error);
		}
	}
	
	private void showData(){
		int row=columnsettable.getSelectedRow();
		if (row==-1)
			return;
			
		Columnset colset=(Columnset) columnset.get(row);
		if (colset==null)
			return;
		
		try {
			if (colset.getStatisticsAll()==0){
				JOptionPane.showMessageDialog(
					this.app,
					Resource.getString("INFO_NO_DATA_MSG"),
					Resource.getString("INFO_NO_DATA_TITLE"),
					JOptionPane.INFORMATION_MESSAGE);
				
			}else{
				DataDialog dialog=new DataDialog(app,colset);
			}
		} catch (M4Exception error) {
			M4Interface.print.doPrint(Print.ERROR,error.getMessage(),error);
		}
		
		
	}


	/* (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent event) {
		if (!(event.getSource() instanceof JButton))
			return;
		JButton source=(JButton) event.getSource();
		
		if (source.getText().equals(closeButton.getText())){
			//Removes the tab
			app.removeComponentFromTab(this);
		}
		if (source.getText().equals(deletecolset.getText())){
			deleteColumnset();
		}
		if (source.getText().equals(deletecolumn.getText())){
			deleteColumn();
		}
		if (source.getText().equals(showstats.getText())){
			showStatistics();
		}
		if (source.getText().equals(showdata.getText())){
			showData();
		}
	}
	
	
	// Table Models	
	
	private class ColumnsetTableModel extends AbstractTableModel{
		
		/* (non-Javadoc)
		 * @see javax.swing.table.TableModel#getColumnClass(int)
		 */
		public Class getColumnClass(int columnIndex) {
			return String.class;
		}
		
		/* (non-Javadoc)
		 * @see javax.swing.table.TableModel#getColumnName(int)
		 */
		public String getColumnName(int column) {
			switch (column){
				case 0: 	return Resource.getString("COLUMN_NAME");
				case 1:   	return Resource.getString("COLUMN_SCHEMA");
				case 2:    	return Resource.getString("COLUMN_TYPE");
				case 3: 	return Resource.getString("COLUMN_BRANCH");
				case 4:		return Resource.getString("COLUMN_SQL");
				default: 	return Resource.getString("COLUMN_NAME");
			}
		}

		/* (non-Javadoc)
		 * @see javax.swing.table.TableModel#isCellEditable(int, int)
		 */
		public boolean isCellEditable(int rowIndex, int columnIndex) {
			return false;
		}

		/* (non-Javadoc)
		 * @see javax.swing.table.TableModel#getColumnCount()
		 */
		public int getColumnCount() {
			return 5;
		}

		/* (non-Javadoc)
		 * @see javax.swing.table.TableModel#getRowCount()
		 */
		public int getRowCount() {
			return columnset.size();
		}

		/* (non-Javadoc)
		 * @see javax.swing.table.TableModel#getValueAt(int, int)
		 */
		public Object getValueAt(int rowIndex, int columnIndex) {
			switch (columnIndex){
				case 0: 	return ((Columnset) columnset.get(rowIndex)).getName();
				case 1:   	return ((Columnset) columnset.get(rowIndex)).getSchema();
				case 2:{    	
					String type=((Columnset) columnset.get(rowIndex)).getType();
					if (type.equals(Columnset.CS_TYPE_TABLE)){
						return Resource.getString("TABLE");
					}
					return Resource.getString("VIEW");
				}
				case 3: 	return ((Columnset) columnset.get(rowIndex)).getMultiStepBranch();
				case 4:		return ((Columnset) columnset.get(rowIndex)).getSQLDefinition();
				default: 	return ((Columnset) columnset.get(rowIndex)).getName();
			}
		}

	}
	
	private class ColumnTableModel extends AbstractTableModel{
		
    	/* (non-Javadoc)
		 * @see javax.swing.table.TableModel#getColumnClass(int)
		 */
		public Class getColumnClass(int columnIndex) {
			return String.class;
		}

		/* (non-Javadoc)
		 * @see javax.swing.table.TableModel#getColumnName(int)
		 */
		public String getColumnName(int column) {
			switch (column){
				case 0:		return Resource.getString("COLUMN_NAME");
				case 1:		return Resource.getString("COLUMN_TYPE");
				case 2:		return Resource.getString("COLUMN_SQL");
				default: 	return Resource.getString("COLUMN_NAME");
			}
		}

		/* (non-Javadoc)
		 * @see javax.swing.table.TableModel#isCellEditable(int, int)
		 */
		public boolean isCellEditable(int rowIndex, int columnIndex) {
			return false;
		}

		/* (non-Javadoc)
		 * @see javax.swing.table.TableModel#getColumnCount()
		 */
		public int getColumnCount() {
			return 3;
		}

		/* (non-Javadoc)
		 * @see javax.swing.table.TableModel#getRowCount()
		 */
		public int getRowCount() {
			int row=columnsettable.getSelectedRow();
			if (row==-1)
				return 0;
		 	
		 	try {
				return ((Columnset) columnset.get(row)).getColumns().size();
			} catch (M4Exception error) {
				M4Interface.print.doPrint(Print.ERROR,error.getMessage(),error);
			}
			return 0;
		}

		/* (non-Javadoc)
		 * @see javax.swing.table.TableModel#getValueAt(int, int)
		 */
		public Object getValueAt(int rowIndex, int columnIndex) {
			try{
				int colindex=columnsettable.getSelectedRow();
				if (colindex==-1)
					return new String("");

				Column col=((Columnset) columnset.get(colindex)).getColumn(rowIndex);
				if (col==null)
					return new String("");
				
				switch (columnIndex){
					case 0:		return col.getName();
					case 1:		return col.getColumnDataTypeName();
					case 2:		return col.getSQLDefinition();
					default: 	return col.getName();
				}
	
			} catch (DbConnectionClosed error) {
				M4Interface.print.doPrint(Print.ERROR,error.getMessage(),error);
			} catch (M4Exception error) {
				M4Interface.print.doPrint(Print.ERROR,error.getMessage(),error);
			}
			return new String("");
		}

}


	/* (non-Javadoc)
	 * @see edu.udo.cs.miningmart.gui.concepteditor.ConceptPanel#getConcept()
	 */
	public Concept getConcept() {
		return this.concept;
	}

}
/*
 * Historie
 * --------
 *
 * $Log: ColumnsetPanel.java,v $
 * Revision 1.5  2006/04/11 14:10:17  euler
 * Updated license text.
 *
 * Revision 1.4  2006/04/06 16:31:16  euler
 * Prepended license remark.
 *
 * Revision 1.3  2006/01/10 07:48:17  hakenjos
 * The data- and statistics-dialog of a Columnset is shown, if the Columnset has at least one tuple.
 *
 * Revision 1.2  2006/01/03 10:52:27  hakenjos
 * Adjusted the width of the SQL-Column in the Columntable.
 *
 * Revision 1.1  2006/01/03 09:54:25  hakenjos
 * Initial version!
 *
 */

/*
Revision 1.6  2005/12/15 09:15:55  hakenjos
*** empty log message ***

Revision 1.5  2005/11/24 10:52:55  hakenjos
Only one ConceptPanel in the Application visible.

Revision 1.4  2005/11/24 09:50:28  hakenjos
Names etc. replaced with resource-access

Revision 1.3  2005/11/17 10:57:26  hakenjos
*** empty log message ***

Revision 1.2  2005/11/10 10:48:44  hakenjos
*** empty log message ***

*/
