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

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.JPanel;
import javax.swing.JDialog;
import java.io.File;
import java.util.ArrayList;


import com.approximatrix.draco.application.ChildFrame;
import com.approximatrix.draco.datamodel.StatTableModel;
import com.approximatrix.draco.general.ui.InfoWindow;
import com.approximatrix.draco.io.ImportExport;

import javax.swing.JButton;
import java.awt.FlowLayout;
import javax.swing.BoxLayout;
import javax.swing.JFileChooser;
import javax.swing.JMenu;
import javax.swing.JTextField;
import javax.swing.JLabel;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import javax.swing.JInternalFrame;
import java.awt.GridLayout;
import javax.swing.JCheckBox;

public class ImportData extends ChildFrame {

	private static final String DIALOG_NAME = "Import Data";
	
	/** The string for requesting topical help */
	private static final String HELP_KEY = "importdata";
	
	private JPanel jContentPane = null;

	private JPanel jButtonPanel = null;

	private JButton jImportButton = null;

	private JButton jCancelButton = null;

	private JPanel jMainPanel = null;

	private JPanel jFilePanel = null;

	private JButton jBrowseButton = null;

	private JButton jViewButton = null;

	private JPanel jOptionsPanel = null;

	private JTextField jFileTextField = null;

	private JLabel jFileLabel = null;

	private JLabel jLabel = null;

	private JLabel jLabel1 = null;

	private JLabel jDateColumnLabel = null;

	private JTextField jSkipTextField = null;

	private JTextField jHeaderTextField = null;

	private JTextField jDateTextField = null;

	private JPanel jSeparatorPanel = null;
	private JPanel jSeparatorCharacterPanel = null;
	private JCheckBox jSpaceCheckBox = null;
	private JCheckBox jTabsCheckBox = null;
	private JCheckBox jCommaCheckBox = null;
	private JCheckBox jSCCheckBox = null;
	private JCheckBox jCombineCheckBox = null;

	public ImportData(boolean time_series) {
		this();
		
		if(! time_series) {
			jDateColumnLabel.setVisible(false);
			getJDateTextField().setVisible(false);
		}
	}
	
	/**
	 * This is the default constructor
	 */
	public ImportData() {
		super(DIALOG_NAME, 
				true, //resizable
				true, //closable
				true, //maximizable
				true);

		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(373, 277);
		this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
		this.setTitle(DIALOG_NAME);
		this.setContentPane(getJContentPane());
		this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		//this.addWindowListener(new java.awt.event.WindowAdapter() {
		//	public void windowClosing(java.awt.event.WindowEvent e) {
		//		closeDialog();
		//	}
		//});
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			BorderLayout borderLayout = new BorderLayout();
			borderLayout.setHgap(3);
			borderLayout.setVgap(3);
			jContentPane = new JPanel();
			jContentPane.setLayout(borderLayout);
			jContentPane.add(getJMainPanel(), java.awt.BorderLayout.CENTER);
			jContentPane.add(getJButtonPanel(), java.awt.BorderLayout.SOUTH);
		}
		return jContentPane;
	}

	/**
	 * This method initializes jButtonPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJButtonPanel() {
		if (jButtonPanel == null) {
			FlowLayout flowLayout = new FlowLayout();
			flowLayout.setAlignment(java.awt.FlowLayout.RIGHT);
			jButtonPanel = new JPanel();
			jButtonPanel.setLayout(flowLayout);
			jButtonPanel.add(getJImportButton(), null);
			jButtonPanel.add(getJCancelButton(), null);
		}
		return jButtonPanel;
	}

	/**
	 * This method initializes jImportButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJImportButton() {
		if (jImportButton == null) {
			jImportButton = new JButton();
			jImportButton.setText("Import");
			jImportButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					importFile();
					dispose();
				}
			});
		}
		return jImportButton;
	}

	/**
	 * This method initializes jCancelButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJCancelButton() {
		if (jCancelButton == null) {
			jCancelButton = new JButton();
			jCancelButton.setText("Cancel");
			jCancelButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					dispose();
				}
			});
		}
		return jCancelButton;
	}

	/**
	 * This method initializes jMainPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJMainPanel() {
		if (jMainPanel == null) {
			jMainPanel = new JPanel();
			jMainPanel.setLayout(new BoxLayout(getJMainPanel(), BoxLayout.Y_AXIS));
			jMainPanel.add(getJFilePanel(), null);
			jMainPanel.add(getJOptionsPanel(), null);
			jMainPanel.add(getJSeparatorPanel(), null);
		}
		return jMainPanel;
	}

	/**
	 * This method initializes jFilePanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJFilePanel() {
		if (jFilePanel == null) {
			jFileLabel = new JLabel();
			jFileLabel.setText("File: ");
			jFilePanel = new JPanel();
			jFilePanel.setLayout(new BoxLayout(getJFilePanel(), BoxLayout.X_AXIS));
			jFilePanel.add(jFileLabel, null);
			jFilePanel.add(getJFileTextField(), null);
			jFilePanel.add(getJBrowseButton(), null);
			jFilePanel.add(getJViewButton(), null);
		}
		return jFilePanel;
	}

	/**
	 * This method initializes jButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJBrowseButton() {
		if (jBrowseButton == null) {
			jBrowseButton = new JButton();
			jBrowseButton.setText("Browse...");
			jBrowseButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					JFileChooser chooser = new JFileChooser();
					chooser.setDialogTitle("Select File to Import...");
					chooser.setSelectedFile(new File(getJFileTextField().getText()));
				    if (chooser.showOpenDialog(chooser) == JFileChooser.APPROVE_OPTION) {
				    	getJFileTextField().setText(chooser.getSelectedFile().toString());
				    }
				}
			});
		}
		return jBrowseButton;
	}

	/**
	 * This method initializes jViewButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJViewButton() {
		if (jViewButton == null) {
			jViewButton = new JButton();
			jViewButton.setText("View...");
			jViewButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					ImportData.this.getMainWindow().openWindow(
							new InfoWindow(new File(getJFileTextField().getText()),true));
				}
			});
		}
		return jViewButton;
	}

	/**
	 * This method initializes jOptionsPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJOptionsPanel() {
		if (jOptionsPanel == null) {
			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
			gridBagConstraints4.fill = java.awt.GridBagConstraints.HORIZONTAL;
			gridBagConstraints4.gridy = 2;
			gridBagConstraints4.weightx = 1.0;
			gridBagConstraints4.gridx = 1;
			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
			gridBagConstraints3.fill = java.awt.GridBagConstraints.HORIZONTAL;
			gridBagConstraints3.gridy = 1;
			gridBagConstraints3.weightx = 1.0;
			gridBagConstraints3.gridx = 1;
			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
			gridBagConstraints2.fill = java.awt.GridBagConstraints.HORIZONTAL;
			gridBagConstraints2.gridy = 0;
			gridBagConstraints2.weightx = 1.0;
			gridBagConstraints2.gridx = 1;
			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
			gridBagConstraints11.gridx = 0;
			gridBagConstraints11.anchor = java.awt.GridBagConstraints.WEST;
			gridBagConstraints11.gridy = 2;
			jDateColumnLabel = new JLabel();
			jDateColumnLabel.setText("Column Containing Date Information: ");
			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.gridx = 0;
			gridBagConstraints1.anchor = java.awt.GridBagConstraints.WEST;
			gridBagConstraints1.gridy = 1;
			jLabel1 = new JLabel();
			jLabel1.setText("Row Containing Headers (0=None):");
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.gridx = 0;
			gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
			gridBagConstraints.gridy = 0;
			jLabel = new JLabel();
			jLabel.setText("Number of Header Lines to Skip:");
			jOptionsPanel = new JPanel();
			jOptionsPanel.setLayout(new GridBagLayout());
			jOptionsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.LOWERED), "File Layout", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
			jOptionsPanel.add(jLabel, gridBagConstraints);
			jOptionsPanel.add(jLabel1, gridBagConstraints1);
			jOptionsPanel.add(jDateColumnLabel, gridBagConstraints11);
			jOptionsPanel.add(getJSkipTextField(), gridBagConstraints2);
			jOptionsPanel.add(getJHeaderTextField(), gridBagConstraints3);
			jOptionsPanel.add(getJDateTextField(), gridBagConstraints4);
		}
		return jOptionsPanel;
	}

	/**
	 * This method initializes jFileTextField	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getJFileTextField() {
		if (jFileTextField == null) {
			jFileTextField = new JTextField();
			jFileTextField.setMaximumSize(new Dimension(1024,20));
		}
		return jFileTextField;
	}

	/**
	 * This method initializes jSkipTextField	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getJSkipTextField() {
		if (jSkipTextField == null) {
			jSkipTextField = new JTextField();
			jSkipTextField.setText("0");
			jSkipTextField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
		}
		return jSkipTextField;
	}

	/**
	 * This method initializes jHeaderTextField	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getJHeaderTextField() {
		if (jHeaderTextField == null) {
			jHeaderTextField = new JTextField();
			jHeaderTextField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
			jHeaderTextField.setText("0");
		}
		return jHeaderTextField;
	}

	/**
	 * This method initializes jDateTextField	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getJDateTextField() {
		if (jDateTextField == null) {
			jDateTextField = new JTextField();
			jDateTextField.setText("1");
			jDateTextField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
		}
		return jDateTextField;
	}

	/**
	 * This method initializes jSeparatorPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJSeparatorCharacterPanel() {
		if (jSeparatorCharacterPanel == null) {
			GridLayout gridLayout = new GridLayout();
			gridLayout.setRows(2);
			gridLayout.setColumns(2);
			jSeparatorCharacterPanel = new JPanel();
			jSeparatorCharacterPanel.setLayout(gridLayout);
			//jSeparatorPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.LOWERED), "Column Separators", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
			jSeparatorCharacterPanel.add(getJSpaceCheckBox(), null);
			jSeparatorCharacterPanel.add(getJTabsCheckBox(), null);
			jSeparatorCharacterPanel.add(getJCommaCheckBox(), null);
			jSeparatorCharacterPanel.add(getJSCCheckBox(), null);
		}
		return jSeparatorCharacterPanel;
	}
	
	private JPanel getJSeparatorPanel() {
		if (jSeparatorPanel == null) {
			jSeparatorPanel = new JPanel();
			jSeparatorPanel.setLayout(new BorderLayout());
			jSeparatorPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.LOWERED), "Column Separators", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
			jSeparatorPanel.add(getJSeparatorCharacterPanel(), BorderLayout.CENTER);
			jSeparatorPanel.add(getJCombineCheckBox(), BorderLayout.SOUTH);
		}
		return jSeparatorPanel;
	}

	/**
	 * This method initializes jSpaceCheckBox	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private JCheckBox getJSpaceCheckBox() {
		if (jSpaceCheckBox == null) {
			jSpaceCheckBox = new JCheckBox();
			jSpaceCheckBox.setText("Spaces");
			jSpaceCheckBox.setSelected(true);
		}
		return jSpaceCheckBox;
	}

	/**
	 * This method initializes jTabsCheckBox	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private JCheckBox getJTabsCheckBox() {
		if (jTabsCheckBox == null) {
			jTabsCheckBox = new JCheckBox();
			jTabsCheckBox.setText("Tabs");
			jTabsCheckBox.setSelected(true);
		}
		return jTabsCheckBox;
	}

	/**
	 * This method initializes jCommaCheckBox	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private JCheckBox getJCommaCheckBox() {
		if (jCommaCheckBox == null) {
			jCommaCheckBox = new JCheckBox();
			jCommaCheckBox.setText("Commas");
			jCommaCheckBox.setSelected(true);
		}
		return jCommaCheckBox;
	}

	/**
	 * This method initializes jSCCheckBox	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private JCheckBox getJSCCheckBox() {
		if (jSCCheckBox == null) {
			jSCCheckBox = new JCheckBox();
			jSCCheckBox.setText("SemiColons");
		}
		return jSCCheckBox;
	}
	
	/**
	 * This method initializes jSCCheckBox	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private JCheckBox getJCombineCheckBox() {
		if (jCombineCheckBox == null) {
			jCombineCheckBox = new JCheckBox();
			jCombineCheckBox.setText("Treat sequential separators as one");
		}
		return jCombineCheckBox;
	}
	
	private void importFile() {
		String separators = buildSeparators();
		
		int header_row = 0;
		try {
			header_row = new Integer(getJHeaderTextField().getText()).intValue();
		} catch (NumberFormatException nfe) {
			
		}
		
		int skip_rows = 0;
		try {
			skip_rows = new Integer(getJSkipTextField().getText()).intValue();
		} catch (NumberFormatException nfe) {
			
		}
		
		int date_col = 1;
		if(getJDateTextField().isVisible()) {
			try {
				date_col = new Integer(getJDateTextField().getText()).intValue();
			} catch (NumberFormatException nfe) {
				
			}
		}
		
		// First, get the text results
		Object[] text_data = ImportExport.LoadText(new File(getJFileTextField().getText()),
				                                   header_row,
				                                   skip_rows,
				                                   separators,
				                                   0);
		
		// Determine what we are now processing
		if(getJDateTextField().isVisible()) {
			StatTableModel modified = ImportExport.ImportTimeSeriesData(this.getMainWindow().getWindowTableModel(),
			                                  (ArrayList)text_data[0],
			                                  date_col,
			                                  (String[])text_data[1]);
			this.getMainWindow().setWindowTableModel(modified);
			this.getMainWindow().getWindowTableModel().fireTableDataChanged();
			this.getMainWindow().getWindowTableModel().fireTableStructureChanged();
		} else {
			StatTableModel modified = ImportExport.CreatePanelModel((ArrayList)text_data[0],(String[])text_data[1]);
			this.getMainWindow().setWindowTableModel(modified);
			this.getMainWindow().getWindowTableModel().fireTableDataChanged();
			this.getMainWindow().getWindowTableModel().fireTableStructureChanged();
		}
	}
	
	/** Builds a regex string based on selected separators to use
	 * during file importing.
	 * 
	 * @return a regex String
	 */
	private String buildSeparators() {
		StringBuffer builder = new StringBuffer();
		
		if(getJCombineCheckBox().isSelected()) {
			builder.append("[");
			if(getJSpaceCheckBox().isSelected() && getJTabsCheckBox().isSelected()) 				
				builder.append("\\s");
			else if(getJSpaceCheckBox().isSelected())
				builder.append(" ");
			else if(getJTabsCheckBox().isSelected()) 
				builder.append("\t");
			
			if(getJCommaCheckBox().isSelected())
				builder.append(",");
			if(getJSCCheckBox().isSelected())
				builder.append(";");
			
			builder.append("]+");

		} else {

			if(getJSpaceCheckBox().isSelected() && getJTabsCheckBox().isSelected()) {
				builder.append("[\\s]+");
			} else if(getJSpaceCheckBox().isSelected()) {
				builder.append("[ ]+");
			} else if(getJTabsCheckBox().isSelected()) {
				builder.append("[\t]+");
			}

			if(getJCommaCheckBox().isSelected()) {
				if(builder.length()>1 && !getJCombineCheckBox().isSelected()) 
					builder.append("|");
				builder.append(",");
			}

			
			if(getJSCCheckBox().isSelected()) {
				if(builder.length()>0 && !getJCombineCheckBox().isSelected()) 
					builder.append("|");
				builder.append(";");
			}

		}
		//System.out.println(builder.toString());
		
		return builder.toString();
	}

	/** The import window has no menu items associated with it
	 * 
	 * @return null since ther are no menu items
	 * @see com.approximatrix.draco.application.ChildFrame#getMenuItems()
	 */
	public JMenu[] getMenuItems() {
		// TODO Auto-generated method stub
		return null;
	}

	/** The import window does not have any toolbar buttons associated with it
	 * 
	 * @return null since there are no buttons
	 * @see com.approximatrix.draco.application.ChildFrame#getToolbarButtons()
	 */
	public Component[] getToolbarButtons() {
		return null;
	}

	/** There is no reason to rename an import window
	 * 
	 * @return false
	 * @see com.approximatrix.draco.application.ChildFrame#isRenameable()
	 */
	public boolean isRenameable() {
		return false;
	}
	
	/** Returns the help key for the Import Data 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="16,13"
