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

import com.approximatrix.draco.datamodel.Constant;
import com.approximatrix.draco.datamodel.StatTableModel;

import java.awt.BorderLayout;

import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JComboBox;
import javax.swing.Box;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import javax.swing.JLabel;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import java.util.ArrayList;

public class EquationPanel extends JPanel {

	private StatTableModel model = null;
	private JTextArea eqn_textarea = null;
	private JPanel jPanel = null;
	private JComboBox dependent_combobox = null;
	private JLabel jLabel = null;
	private JPanel jPanel1 = null;
	private JPanel jPanel2 = null;
	private JPanel jPanel3 = null;
	private JComboBox variables_combobox = null;
	private JButton add_var_button = null;
	private JComboBox constants_combobox = null;
	private JButton add_const_button = null;
	
	
	/**
	 * This is the default constructor
	 */
	public EquationPanel(StatTableModel data, String dependent) {
		this(data);
		for(int i=0;i<model.getColumnCount();i++) {
			if(model.getColumnName(i).compareTo(dependent) == 0) 
				getDependent_combobox().setSelectedIndex(i);
		}
		getDependent_combobox().setEnabled(false);
	}
	
	/**
	 * This is the default constructor
	 */
	public EquationPanel(StatTableModel data) {
		super();
		
		model = data;
		
		if(model == null) return;
		
		initialize();		
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setLayout(new BorderLayout());
		this.setSize(550, 200);
		
		JScrollPane textPane = new JScrollPane(getEqn_textarea());
		textPane.setBorder(javax.swing.BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.LOWERED));
		
		this.add(textPane, java.awt.BorderLayout.CENTER);
		this.add(getJPanel(), java.awt.BorderLayout.WEST);
		this.add(getJPanel1(), java.awt.BorderLayout.EAST);
	}

	/**
	 * This method initializes eqn_textarea	
	 * 	
	 * @return javax.swing.JTextArea	
	 */
	private JTextArea getEqn_textarea() {
		if (eqn_textarea == null) {
			eqn_textarea = new JTextArea();
			//eqn_textarea.setBorder(javax.swing.BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.LOWERED));
		}
		return eqn_textarea;
	}

	/**
	 * This method initializes jPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanel() {
		if (jPanel == null) {
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.ipadx = 5;
			jLabel = new JLabel();
			jLabel.setText("=");
			jLabel.setFont(new java.awt.Font("Dialog", java.awt.Font.BOLD, 14));
			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
			gridBagConstraints1.ipadx = 5;
			gridBagConstraints1.weightx = 1.0;
			jPanel = new JPanel();
			jPanel.setLayout(new GridBagLayout());
			jPanel.add(getDependent_combobox(), gridBagConstraints1);
			jPanel.add(jLabel, gridBagConstraints);
		}
		return jPanel;
	}

	/**
	 * This method initializes dependent_combobox	
	 * 	
	 * @return javax.swing.JComboBox	
	 */
	private JComboBox getDependent_combobox() {
		if (dependent_combobox == null) {
			if(model.getColumnCount() > 0)
				dependent_combobox = new JComboBox(model.getColumnNames());
			else
				dependent_combobox = new JComboBox();
			dependent_combobox.setPreferredSize(new java.awt.Dimension(125,25));
		}
		return dependent_combobox;
	}

	/**
	 * This method initializes jPanel1	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanel1() {
		if (jPanel1 == null) {
			jPanel1 = new JPanel();
			jPanel1.setLayout(new BoxLayout(getJPanel1(), BoxLayout.Y_AXIS));
			jPanel1.add(getJPanel2(), null);
			jPanel1.add(getJPanel3(), null);
			jPanel1.add(Box.createVerticalGlue());
		}
		return jPanel1;
	}

	/**
	 * This method initializes jPanel2	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanel2() {
		if (jPanel2 == null) {
			jPanel2 = new JPanel();
			jPanel2.setLayout(new BoxLayout(jPanel2, BoxLayout.Y_AXIS));
			jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.LOWERED), "Variables", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
			jPanel2.add(getVariables_combobox(), null);
			jPanel2.add(getAdd_var_button(), null);
		}
		return jPanel2;
	}

	/**
	 * This method initializes jPanel3	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanel3() {
		if (jPanel3 == null) {
			jPanel3 = new JPanel();
			jPanel3.setLayout(new BoxLayout(jPanel3, BoxLayout.Y_AXIS));
			jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.LOWERED), "Constants", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
			jPanel3.add(getConstants_combobox(), null);
			jPanel3.add(getAdd_const_button(), null);
		}
		return jPanel3;
	}

	/**
	 * This method initializes variables_combobox	
	 * 	
	 * @return javax.swing.JComboBox	
	 */
	private JComboBox getVariables_combobox() {
		if (variables_combobox == null) {
			if(model.getColumnCount() > 0)
				variables_combobox = new JComboBox(model.getColumnNames());
			else
				variables_combobox = new JComboBox();
			
			variables_combobox.setPreferredSize(new java.awt.Dimension(125,25));
			variables_combobox.setMaximumSize(variables_combobox.getPreferredSize());
			variables_combobox.setMinimumSize(variables_combobox.getPreferredSize());
		}
		return variables_combobox;
	}

	/**
	 * This method initializes add_var_button	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getAdd_var_button() {
		if (add_var_button == null) {
			add_var_button = new JButton();
			add_var_button.setText("Add");
			add_var_button.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					String text = (String)getVariables_combobox().getSelectedItem();
					if(text != null) {
						StringBuffer eqn = new StringBuffer(eqn_textarea.getText());
                        eqn.insert(eqn_textarea.getCaretPosition(),text);
                        eqn_textarea.setText(eqn.toString());
					}
				}
			});
		}
		return add_var_button;
	}

	/**
	 * This method initializes constants_combobox	
	 * 	
	 * @return javax.swing.JComboBox	
	 */
	private JComboBox getConstants_combobox() {
		if (constants_combobox == null) {
			
			ArrayList constants = model.getConstants();
			if(constants.size()==0) 
				constants_combobox = new JComboBox();
			else {
				String[] names = new String[constants.size()];
				for(int i=0;i<names.length;i++) {
					Constant this_one = (Constant)constants.get(i);
					names[i] = this_one.getName();
				}
				constants_combobox = new JComboBox(names);
			}
			
			constants_combobox.setPreferredSize(new java.awt.Dimension(125,25));
			constants_combobox.setMaximumSize(constants_combobox.getPreferredSize());
			constants_combobox.setMinimumSize(constants_combobox.getPreferredSize());
		}
		return constants_combobox;
	}

	/**
	 * This method initializes add_const_button	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getAdd_const_button() {
		if (add_const_button == null) {
			add_const_button = new JButton();
			add_const_button.setText("Add");
			add_const_button.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					String text = (String)getConstants_combobox().getSelectedItem();
					if(text != null) {
						StringBuffer eqn = new StringBuffer(eqn_textarea.getText());
                        eqn.insert(eqn_textarea.getCaretPosition(),text);
                        eqn_textarea.setText(eqn.toString());
					}
				}
			});
		}
		return add_const_button;
	}

	/** Returns the equation in the text area
	 * 
	 * @return the equation as a String
	 */
	public String getEquation() {
		return getEqn_textarea().getText();
	}
	
	/** Allows the equation in the text area to be set
	 * 
	 * @param text the text of the equation
	 */
	public void setEquation(String text) {
		getEqn_textarea().setText(text);
	}
	
	/** Sets whether the equation text may be changed or not
	 * 
	 * @param allow true to allow changes, false otherwise
	 */
	public void setAllowChanges(boolean allow) {
		getEqn_textarea().setEditable(allow);
		getDependent_combobox().setEditable(false);
		getDependent_combobox().setEnabled(false);
	}
	
	/** Returns the selected dependent variable
	 * 
	 * @return a String containing the name of the selected depdendent variable
	 */
	public String getDependent() {
		return (String)getDependent_combobox().getSelectedItem();
	}
	
	/** Sets the depednent variable combobox
	 * 
	 * @param dep the dependent variable to set
	 */
	public void setDependent(String dep) {
		getDependent_combobox().setSelectedItem(dep);
		try {
			if(!dep.equals(getDependent())) {
				getDependent_combobox().addItem(dep);
				getDependent_combobox().setSelectedItem(dep);
			}
		} catch(Exception e) {
			getDependent_combobox().addItem(dep);
			getDependent_combobox().setSelectedItem(dep);
		}
	}
	
	/** Sets whether the dependent variable combobox can be changed
	 * 
	 * @param value true to allow editting, false otherwise
	 */
	public void setDependentEnabled(boolean value) {
		getDependent_combobox().setEnabled(value);
	}
	
}  //  @jve:decl-index=0:visual-constraint="10,10"
