package com.sap.dbmtk.demo;

import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import com.sap.dbmtk.demo.ui.ResultSetTableModel;
import com.sap.dbmtk.demo.utils.Configuration;
import com.sap.dbmtk.demo.utils.SwingUtils;

import net.miginfocom.swing.MigLayout;

public class PreferencesDialog
extends JDialog
{
	private static final long serialVersionUID = 1L;

	private Window              _owner        = null;

//	protected JLabel            _filter_lbl   = new JLabel("Filter: ");
//	protected JTextField        _filter_txt   = new JTextField();
//	protected JLabel            _filter_hlp   = new JLabel("<html></html>");

	private JButton             _toDefault = new JButton("Set to Default");
	private JButton             _ok     = new JButton("OK");
	private JButton             _cancel = new JButton("Cancel");

	private boolean             _okWasPressed = false;
	
	public PreferencesDialog(Window owner)
	{
		super(owner, "Application Preferences", ModalityType.APPLICATION_MODAL);

		_owner = owner;
		
		pinit();
		loadProps();
		pack();

		SwingUtils.installEscapeButton(this, _cancel);

		setLocationRelativeTo(owner);
	}

	private void pinit()
	{
		setLayout(new MigLayout());

		String desc = 
				"<html>"
				+ "<b>Application Preferences</b><br>"
				+ "</html>";

//		_filter_txt.setToolTipText(desc);
//		_filter_hlp.setText(desc);

		add(new JLabel(desc),      "growx, pushx, wrap");
//		add(_filter_lbl,           "split");
//		add(_filter_txt,           "growx, pushx");
//		add(_filter_hlp,           "wrap");
		add(createPrefPanel(),     "grow, push, wrap");
		add(createOkCancelPanel(), "growx, pushx, tag right, wrap");


		_toDefault.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				setAllToDefault();
			}
		});
		_ok.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				saveProps();
				_okWasPressed = true;
				setVisible(false);
			}
		});

		_cancel.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				_okWasPressed = false;
				setVisible(false);
			}
		});
	}

	private JPanel createOkCancelPanel()
	{
		JPanel p = new JPanel(new MigLayout());

		p.add(new JLabel(),    "split, span, growx, pushx"); // dummy label to push everything to the right

		p.add(_ok,     "tag ok");
		p.add(_cancel, "tag cancel");

		return p;
	}

	public boolean wasOkPressed()
	{
		return _okWasPressed;
	}

	private JPanel createPrefPanel()
	{
		JPanel p = new JPanel(new MigLayout());
		
		//-----------------------------------------------------------------------------
		JPanel p1 = SwingUtils.createPanel("Error Handling", true, new MigLayout());
		p1.add(_showExtErrInfo_chk,             "span, wrap");
		p1.add(_enableDbmsOutput_chk,           "span, wrap");
		
		//-----------------------------------------------------------------------------
		JPanel p2 = SwingUtils.createPanel("DB/Server Filter", true, new MigLayout());
		p2.add(_dbShowSearchPanelThreshold_lbl, "");
		p2.add(_dbShowSearchPanelThreshold_txt, "growx, pushx, wrap");
		p2.add(_onRefreshGetDbCount_chk,        "span, wrap");

		//-----------------------------------------------------------------------------
		JPanel p3 = SwingUtils.createPanel("Add/Change Dialogs", true, new MigLayout());
		p3.add(_sendBlankStrAsNull_chk,         "span, wrap");

		//-----------------------------------------------------------------------------
		JPanel p4 = SwingUtils.createPanel("SQL Execution", true, new MigLayout());
		p4.add(_sqlPopupGraceTime_lbl, "");
		p4.add(_sqlPopupGraceTime_txt, "growx, pushx, wrap");
		
		//-----------------------------------------------------------------------------
		JPanel p5 = SwingUtils.createPanel("Result Set Options", true, new MigLayout());
		p5.add(_rsNullReplace_lbl           , "");
		p5.add(_rsNullReplace_txt           , "growx, pushx, wrap");
		p5.add(_rsShowRowNumber_chk         , "span, wrap");
		p5.add(_rsStringTrim_chk            , "span, wrap");
		
		p.add(p1, "growx, pushx, wrap");
		p.add(p2, "growx, pushx, wrap");
		p.add(p3, "growx, pushx, wrap");
		p.add(p4, "growx, pushx, wrap");
		p.add(p5, "growx, pushx, wrap");

		p.add(_toDefault, "tag right, wrap");

		installHandlers();
		installToolTip();

		return p;
	}

	private void installHandlers()
	{
		_dbShowSearchPanelThreshold_txt.addKeyListener(new KeyListener()
		{
			@Override public void keyTyped(KeyEvent e) {}
			@Override public void keyPressed(KeyEvent e) {}
			@Override
			public void keyReleased(KeyEvent e)
			{
				try { Integer.parseInt(_dbShowSearchPanelThreshold_txt.getText().trim()); }
				catch (NumberFormatException ex) { SwingUtils.showErrorMessage(_owner, "Must be a Integer", "Must be a Integer", ex); _dbShowSearchPanelThreshold_txt.setText(DataPanelAbstract.DEFAULT_DB_SEARCH_PANEL_THRESHOLD+"");}
			}
		});

		_sqlPopupGraceTime_txt.addKeyListener(new KeyListener()
		{
			@Override public void keyTyped(KeyEvent e) {}
			@Override public void keyPressed(KeyEvent e) {}
			@Override
			public void keyReleased(KeyEvent e)
			{
				try { Integer.parseInt(_sqlPopupGraceTime_txt.getText().trim()); }
				catch (NumberFormatException ex) { SwingUtils.showErrorMessage(_owner, "Must be a Integer", "Must be a Integer", ex); _sqlPopupGraceTime_txt.setText(SqlStatement.DEFAULT_EXEC_WAITFOR_POPUP_GRACETIME+"");}
			}
		});
	}

	public void installToolTip()
	{
		_showExtErrInfo_chk            .setToolTipText("<html>Show ASE 'print' messages and 'decoded' messages from any SQLExceptions</html>");
		_enableDbmsOutput_chk          .setToolTipText("<html>Enable or Disable Oracle 'DBMS_OUTPUT' subsystem, which is emulated in the SAP DBMTK Runtime Components as 'buffered_output'.<br><b>NOTE</b>: The '<i>Show Extended Error information</i>' option must be enabled for this to work.</html>");

		_dbShowSearchPanelThreshold_txt.setToolTipText("<html>Number of records in the <i>base table</i> before we show the <i>DB/Server Filter Panel</i>.<br><b>NOTE</b>: If this is set to -1 the <i>DB/Server Filter Panel</i> will always be visible after a connection has been established.</html>");
		_dbShowSearchPanelThreshold_lbl.setToolTipText(_dbShowSearchPanelThreshold_txt.getToolTipText());
		_onRefreshGetDbCount_chk       .setToolTipText("<html>Get rowcount from the <i>base table</i> when refreshing the data set. And also show/hide the <i>DB/Server Filter Panel</i>.</html>");

		_sendBlankStrAsNull_chk        .setToolTipText("<html>Should <i>empty</i> string fields in the Add/Change dialog be send as NULL or '' (empty strings).</html>");

		_sqlPopupGraceTime_txt         .setToolTipText("<html>Number of milliseconds before a progress dialog is displayed when executing SQL.</html>");
		_sqlPopupGraceTime_lbl         .setToolTipText(_sqlPopupGraceTime_txt.getToolTipText());

		_rsStringTrim_chk              .setToolTipText("<html>When reading Results from the server, do we want strings to remove leading/trailing spaces?</html>");
		_rsShowRowNumber_chk           .setToolTipText("<html>Show a <i>row#</i> colummn in the Result Set<br><b>NOTE</b>: This requires a reconnect to work properly.</html>");
		_rsNullReplace_txt             .setToolTipText("<html>If the value from the server contains NULL, this is the String representation of the NULL value displaied in the GUI Table.</html>");
		_rsNullReplace_lbl             .setToolTipText(_rsNullReplace_txt.getToolTipText());
	}

	private JCheckBox   _showExtErrInfo_chk             = new JCheckBox("Show Extended Error information");
	private JCheckBox   _enableDbmsOutput_chk           = new JCheckBox("Enable DBMS Output subsystem");

	private JLabel      _dbShowSearchPanelThreshold_lbl = new JLabel("Show DB Filter Panel Threshold");
	private JTextField  _dbShowSearchPanelThreshold_txt = new JTextField();
	private JCheckBox   _onRefreshGetDbCount_chk        = new JCheckBox("On Refresh Get DB Table Count");

	private JCheckBox   _sendBlankStrAsNull_chk         = new JCheckBox("Send Empty Strings as NULL");

	private JLabel      _sqlPopupGraceTime_lbl          = new JLabel("Show Progress Window after X ms");
	private JTextField  _sqlPopupGraceTime_txt          = new JTextField();

	private JCheckBox   _rsStringTrim_chk               = new JCheckBox("Trim Strings");
	private JCheckBox   _rsShowRowNumber_chk            = new JCheckBox("Show Row Number");
	private JLabel      _rsNullReplace_lbl              = new JLabel("Show NULL Values as");
	private JTextField  _rsNullReplace_txt              = new JTextField();

	private void setAllToDefault()
	{
		_showExtErrInfo_chk            .setSelected(DemoApp.DEFAULT_showExtErrInfo);
		_enableDbmsOutput_chk          .setSelected(DemoApp.DEFAULT_enableDbmsOutput);

		_dbShowSearchPanelThreshold_txt.setText(    DataPanelAbstract.DEFAULT_DB_SEARCH_PANEL_THRESHOLD+"");
		_onRefreshGetDbCount_chk       .setSelected(DataPanelAbstract.DEFAULT_ON_REFRESH_GET_DB_COUNT);

		_sendBlankStrAsNull_chk        .setSelected(AddOrChangeAbstract.DEFAULT_blankToNull);

		_sqlPopupGraceTime_txt         .setText(    SqlStatement.DEFAULT_EXEC_WAITFOR_POPUP_GRACETIME+"");

		_rsStringTrim_chk              .setSelected(ResultSetTableModel.DEFAULT_StringTrim);
		_rsShowRowNumber_chk           .setSelected(ResultSetTableModel.DEFAULT_ShowRowNumber);
		_rsNullReplace_txt             .setText    (ResultSetTableModel.DEFAULT_NULL_REPLACE);
	}

	private void loadProps()
	{
		Configuration conf = Configuration.getCombinedConfiguration();
		setAllToDefault();

		_showExtErrInfo_chk            .setSelected(conf.getBooleanProperty(DemoApp.PROPKEY_showExtErrInfo,   DemoApp.DEFAULT_showExtErrInfo));
		_enableDbmsOutput_chk          .setSelected(conf.getBooleanProperty(DemoApp.PROPKEY_enableDbmsOutput, DemoApp.DEFAULT_enableDbmsOutput));

		_dbShowSearchPanelThreshold_txt.setText(    conf.getProperty       (DataPanelAbstract.PROPKEY_DB_SEARCH_PANEL_THRESHOLD, DataPanelAbstract.DEFAULT_DB_SEARCH_PANEL_THRESHOLD+""));
		_onRefreshGetDbCount_chk       .setSelected(conf.getBooleanProperty(DataPanelAbstract.PROPKEY_ON_REFRESH_GET_DB_COUNT,   DataPanelAbstract.DEFAULT_ON_REFRESH_GET_DB_COUNT));

		_sendBlankStrAsNull_chk        .setSelected(conf.getBooleanProperty(AddOrChangeAbstract.PROPKEY_blankToNull, AddOrChangeAbstract.DEFAULT_blankToNull));

		_sqlPopupGraceTime_txt         .setText(    conf.getProperty       (SqlStatement.PROPKEY_EXEC_WAITFOR_POPUP_GRACETIME, SqlStatement.DEFAULT_EXEC_WAITFOR_POPUP_GRACETIME+""));

		_rsStringTrim_chk              .setSelected(conf.getBooleanProperty(ResultSetTableModel.PROPKEY_StringTrim,             ResultSetTableModel.DEFAULT_StringTrim));
		_rsShowRowNumber_chk           .setSelected(conf.getBooleanProperty(ResultSetTableModel.PROPKEY_ShowRowNumber,          ResultSetTableModel.DEFAULT_ShowRowNumber));
		_rsNullReplace_txt             .setText    (conf.getProperty       (ResultSetTableModel.PROPKEY_NULL_REPLACE,           ResultSetTableModel.DEFAULT_NULL_REPLACE));
	}

	private void saveProps()
	{
		Configuration conf = Configuration.getInstance(Configuration.USER_TEMP);
		if (conf == null)
			return;
		
		conf.setProperty(DemoApp.PROPKEY_showExtErrInfo,   _showExtErrInfo_chk  .isSelected());
		conf.setProperty(DemoApp.PROPKEY_enableDbmsOutput, _enableDbmsOutput_chk.isSelected());

		conf.setProperty(DataPanelAbstract.PROPKEY_DB_SEARCH_PANEL_THRESHOLD, _dbShowSearchPanelThreshold_txt.getText());
		conf.setProperty(DataPanelAbstract.PROPKEY_ON_REFRESH_GET_DB_COUNT,   _onRefreshGetDbCount_chk       .isSelected());

		conf.setProperty(AddOrChangeAbstract.PROPKEY_blankToNull,             _sendBlankStrAsNull_chk        .isSelected());

		conf.setProperty(SqlStatement.PROPKEY_EXEC_WAITFOR_POPUP_GRACETIME,   _sqlPopupGraceTime_txt         .getText());

		conf.setProperty(ResultSetTableModel.PROPKEY_StringTrim,             _rsStringTrim_chk               .isSelected());
		conf.setProperty(ResultSetTableModel.PROPKEY_ShowRowNumber,          _rsShowRowNumber_chk            .isSelected());
		conf.setProperty(ResultSetTableModel.PROPKEY_NULL_REPLACE,           _rsNullReplace_txt              .getText());
	}
}