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

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;

import org.pietschy.wizard.InvalidStateException;
import org.pietschy.wizard.PanelWizardStep;

import com.approximatrix.draco.application.plugin.VariableSelectionColumn;
import com.approximatrix.draco.editor.wizard.PluginWizardData;

public class VariableSelectionStep extends PanelWizardStep implements ActionListener {
	
	private JPanel addPanel = null;
	private JTextField columnName = null;
	private JButton addButton = null;
	
	private JPanel selectionPanel = null;
	private JButton removeButton = null;
	private JTable vsTable = null;
	
	private ArrayList<VariableSelectionColumn> vColumns = null;
	
	private PluginWizardData pwd = null;
	
	public VariableSelectionStep(PluginWizardData pwd) {
		super("Variable Selection","Enter variable selection columns to appear in the plugin window.");
		
		this.pwd = pwd;
		
		this.setLayout(new BorderLayout());
		
		vColumns = new ArrayList<VariableSelectionColumn>();
		
		this.setLayout(new BorderLayout());
		this.add(getAddPanel(),BorderLayout.SOUTH);
		this.add(getSelectionPanel(),BorderLayout.CENTER);
		
		this.setComplete(true);
	}

	private JPanel getAddPanel() {
		if(addPanel == null) {
			addPanel = new JPanel();
			addPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), 
					"Add a Variable Selection Column"));
			
			addPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
			
			JLabel label = new JLabel("Label:");
			
			addPanel.add(label);
			
			columnName = new JTextField();
			columnName.setEditable(true);
			columnName.setPreferredSize(new Dimension(175,label.getPreferredSize().height+columnName.getInsets().bottom+columnName.getInsets().top));
			addPanel.add(columnName);
			
			addButton = new JButton("Add");
			addButton.addActionListener(this);
			addPanel.add(addButton);
			
		}
		return addPanel;
	}
	
	private JPanel getSelectionPanel() {
		if(selectionPanel == null) {
			selectionPanel = new JPanel();
			
			vsTable = new JTable();
			vsTable.setModel(new VariableSelectionColumnTableModel(vColumns));
			vsTable.setRowSelectionAllowed(true);
			vsTable.setColumnSelectionAllowed(false);
			vsTable.setCellSelectionEnabled(true);
			
			JScrollPane sPane = new JScrollPane(vsTable);
			selectionPanel.setLayout(new BorderLayout());
			selectionPanel.add(sPane);
			
			JPanel bPanel = new JPanel();
			bPanel.setLayout(new FlowLayout());
			removeButton = new JButton("Remove");
			removeButton.addActionListener(this);
			bPanel.add(removeButton);
			selectionPanel.add(bPanel,BorderLayout.EAST);
			selectionPanel.setPreferredSize(new Dimension(250,150));
		}
		return selectionPanel;
	}

	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == addButton) {
			if(columnName.getText() != null && columnName.getText().length() > 0) {
				vColumns.add(new VariableSelectionColumn(columnName.getText()));
				columnName.setText("");
			}
		} else if(e.getSource() == removeButton) {
			int row_index = vsTable.getSelectedRow();
			if(row_index >= 0 && row_index < vColumns.size()) {
				vColumns.remove(row_index);
			}
		}
		
		((VariableSelectionColumnTableModel)vsTable.getModel()).fireTableDataChanged();
	}
	
	private class VariableSelectionColumnTableModel extends AbstractTableModel {

		private ArrayList<VariableSelectionColumn> vColumns = null;
		
		public VariableSelectionColumnTableModel(ArrayList<VariableSelectionColumn> vColumns) {
			this.vColumns = vColumns;
		}
		
		public int getColumnCount() {
			return 3;
		}

		public int getRowCount() {
			return vColumns.size();
		}
		
		@Override
		public String getColumnName(int column) {
			switch(column) {
			case 0:
				return "Label";
			case 1:
				return "Exclusive?";
			case 2:
				return "Select Many?";
			default:
				throw new IllegalArgumentException("Column exceeds model bounds");	
			}
		}

		@Override
		public boolean isCellEditable(int rowIndex, int columnIndex) {
			return true;
		}

		public Class<?> getColumnClass(int columnIndex) {
			if(columnIndex == 0)
				return String.class;
			else
				return Boolean.class;
		}
		
		@Override
		public void setValueAt(Object value, int row, int col) {
			VariableSelectionColumn v = vColumns.get(row);
			
			if(value == null)
				return;
			
			try {
				switch(col) {
				case 0:
					String label = value.toString();
					if(label.length() > 0)
						v.setTitle(label);
					break;
				case 1:
					v.setExclusive(((Boolean)value).booleanValue());
					break;
				case 2:
					v.setSelectMany(((Boolean)value).booleanValue());
					break;
				default:
					throw new IllegalArgumentException("Column exceeds model bounds");	
				}
			} catch(ClassCastException cce) {
				throw new IllegalArgumentException("Bad type for row.");
			}
		}

		public Object getValueAt(int row, int col) {
			
			VariableSelectionColumn v = vColumns.get(row);
	
			Object ret = null;
			switch(col) {
			case 0:
				ret = v.getTitle();
				break;
			case 1:
				ret = new Boolean(v.isExclusive());
				break;
			case 2:
				ret = new Boolean(v.isSelectMany());
				break;
			default:
				throw new IllegalArgumentException("Address exceeds model bounds");
			}
			return ret;
		}
		
	}

	@Override
	public void applyState() throws InvalidStateException {
		this.pwd.setVColumns(this.vColumns);
	}
	
}
