package com.sap.dbmtk.demo;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

import com.sap.dbmtk.demo.AddOrChangeAbstract.OpType;
import com.sap.dbmtk.demo.SqlStatement.Type;
import com.sap.dbmtk.demo.ui.GTable;
import com.sap.dbmtk.demo.ui.ResultSetTableModel;
import com.sap.dbmtk.demo.utils.Configuration;
import com.sap.dbmtk.demo.utils.SelectAllFocusListener;
import com.sap.dbmtk.demo.utils.StringUtil;
import com.sap.dbmtk.demo.utils.SwingUtils;

import net.miginfocom.swing.MigLayout;

public class DataPanelTitles
extends DataPanelAbstract
{
	private static final long serialVersionUID = 1L;
	public static final String NAME = "Titles";

	private String[] _au_ids  = {};
	private String[] _pub_ids  = {};

	public DataPanelTitles(DemoApp owner)
	{
		super(owner, NAME, true);
	}

	@Override
	public boolean showTableToolTipCheckbox()
	{
		return true;
	}

	//----------------------------------------------------------------
	// BEGIN: DB filter stuff
	//----------------------------------------------------------------
	private JLabel     _titleName_lbl;
	private JTextField _titleName_txt;

	private JComboBox  _image_cbx;

	@Override
	public JPanel createDbSearchPanel()
	{
		_titleName_lbl = new JLabel("Title Name");
		_titleName_txt = new JTextField();

		_image_cbx    = new JComboBox(new String[] {"With or Without Picture", "With Picture", "Without Picture"});

		
		JPanel p = SwingUtils.createPanel("DB/Server Filter", true, new MigLayout());		
		
		p.add(_titleName_lbl, "");
		p.add(_titleName_txt, "growx, pushx");

		p.add(_image_cbx,     "");

		p.add(_dbRowCount_lbl, "");

		// On return in some fields, press "refresh" button
		ActionListener al = new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				_refresh_but.doClick();
			}
		};
		_titleName_txt.addActionListener(al);
		_image_cbx    .addActionListener(al);

		_titleName_txt.addFocusListener(new SelectAllFocusListener());

		return p;
	}

	private Integer getPictureParamValue()
	{
		int index = _image_cbx.getSelectedIndex();

		if (index == 0) return null;  // with or without picture
		if (index == 1) return 1;     // with picture
		if (index == 2) return 0;     // without picture
		return null;
	}
	
	@Override
	public int getDbRowCount()
	{
		SqlStatement stmnt = new SqlStatement(Type.CALLABLE, "{call ${PKG:titles_pkg}get_titles_count(?)}");
		stmnt.addParam( SqlStatementParam.createOutParam("rcount", Types.INTEGER) );
		
		stmnt.execute(getConnectionProvider(), getOwner(), "Get rowcount");

		Integer rcount = (Integer) stmnt.getParameterValue("rcount");
		return rcount == null ? -1 : rcount;
	}

	@Override
	public void saveProps()
	{
		Configuration conf = Configuration.getInstance(Configuration.USER_TEMP);
		if (conf != null)
		{
			conf.setProperty(NAME+".field.titleName", _titleName_txt.getText());
			conf.setProperty(NAME+".field.image",     _image_cbx    .getSelectedIndex());
		}
	}
	@Override
	public void loadProps()
	{
		Configuration conf = Configuration.getCombinedConfiguration();
		_titleName_txt.setText(          conf.getProperty   (NAME+".field.titleName", "The"));
		_image_cbx    .setSelectedIndex( conf.getIntProperty(NAME+".field.image",     0));
	}
	//----------------------------------------------------------------
	// END: DB filter stuff
	//----------------------------------------------------------------

	/**
	 * Is called when the "New" button is pressed
	 */
	@Override
	public void actionAdd()
	{
		AddOrChangeAbstract dialog = new AddOrChangeTitle(_owner.getWindow(), getConnectionProvider(), OpType.INSERT);
		if (dialog.open() == AddOrChangeAbstract.OK)
		{
			refreshDbRowCount();
			refreshTableData();
		}
		dialog.dispose();
	}

	/**
	 * Is called when the "Change" button is pressed
	 */
	@Override
	public void actionChange()
	{
		AddOrChangeAbstract dialog = new AddOrChangeTitle(_owner.getWindow(), getConnectionProvider(), OpType.UPDATE);

		int vrow = getTable().getSelectedRow();
		dialog.setFields(getTable(), vrow);

		if (dialog.open() == AddOrChangeAbstract.OK)
			refreshTableData();
		dialog.dispose();
	}

	/**
	 * Is called when the "Remove" button is pressed
	 */
	@Override
	public void actionRemove()
	{
		AddOrChangeAbstract dialog = new AddOrChangeTitle(_owner.getWindow(), getConnectionProvider(), OpType.DELETE);

		int vrow = getTable().getSelectedRow();
		dialog.setFields(getTable(), vrow);

		if (dialog.open() == AddOrChangeAbstract.OK)
		{
			refreshDbRowCount();
			refreshTableData();
		}
		dialog.dispose();
	}

	/**
	 * Is called when the "Refresh" button is pressed
	 */
	@Override
	public void actionRefresh()
	{
		_au_ids  = new String[0];
		_pub_ids = new String[0];
		
		super.actionRefresh();
	}

	@Override
	public void onParentTableSelection(DataPanelAbstract parent)
	{
		// Only go to work if tab is UNDOCKED
		if ( ! isUndocked() )
			return;

		// Authors
		if (DataPanelAuthors.NAME.equals(parent.getName()))
		{
			GTable tab = parent.getTable();
			
			int[] selectedRows = tab.getSelectedRows();
			
			// Allocate some strings for AU_ID
			_au_ids = new String[selectedRows.length];
			
			for (int r=0; r<selectedRows.length; r++)
			{
				String str = tab.getValueAsString(selectedRows[r], "au_id", false);
				if (str != null)
					_au_ids[r] = str;
			}
		}

		// Publishers
		if (DataPanelPublishers.NAME.equals(parent.getName()))
		{
			GTable tab = parent.getTable();
			
			int[] selectedRows = tab.getSelectedRows();
			
			// Allocate some strings for AU_ID
			_pub_ids = new String[selectedRows.length];
			
			for (int r=0; r<selectedRows.length; r++)
			{
				String str = tab.getValueAsString(selectedRows[r], "pub_id", false);
				if (str != null)
					_pub_ids[r] = str;
			}
		}
		
		// Refresh the local table, which will call getTableDataSqlStatement() to get a SqlStatement to execute
		refreshTableData();
	}

	@Override
	public SqlStatement getTableDataSqlStatement()
	{
//		SqlStatement stmnt = new SqlStatement(Type.LANGUAGE, "select * from titles");
//		return stmnt;

		String au_id_values = null;
		if (_au_ids.length > 0)
			au_id_values = StringUtil.toCommaStr(_au_ids, ",");

		String pub_id_values = null;
		if (_pub_ids.length > 0)
			pub_id_values = StringUtil.toCommaStr(_pub_ids, ",");

		String  titleName   = null;
		Integer pictureType = null;
		if (isDbSearchPanelVisible())
		{
			titleName   = _titleName_txt.getText();
			pictureType = getPictureParamValue();
		}

//		SqlStatement stmnt = new SqlStatement(Type.CALLABLE, "{call get_titles(?, ?, ?)}");
//
//		stmnt.addParam( SqlStatementParam.createInParam("au_id_list",  Types.VARCHAR, au_id_values) );
//		stmnt.addParam( SqlStatementParam.createInParam("pub_id_list", Types.VARCHAR, pub_id_values) );
//		stmnt.addParam( SqlStatementParam.createOracleResultSetParam("a_cursor") );

		SqlStatement stmnt = new SqlStatement(Type.CALLABLE, "{call ${PKG:titles_pkg}get_titles(?, ?, ?, ?, ?)}");

		stmnt.addParam( SqlStatementParam.createInParam("au_id_list",  Types.VARCHAR, au_id_values) );
		stmnt.addParam( SqlStatementParam.createInParam("pub_id_list", Types.VARCHAR, pub_id_values) );
		stmnt.addParam( SqlStatementParam.createInParam("title_name",  Types.VARCHAR, titleName) );
		stmnt.addParam( SqlStatementParam.createInParam("has_picture", Types.INTEGER, pictureType) );
		stmnt.addParam( SqlStatementParam.createOracleResultSetParam("a_cursor") );

		return stmnt;
	}

	@Override
	public List<String> getHiddenColumns()
	{
		List<String> hiddenCols = new ArrayList<String>();
		hiddenCols.add("title_id");
		hiddenCols.add("au_id");
		hiddenCols.add("pub_id");
		return hiddenCols;
	}

	@Override
	public String getTableToolTipText(ResultSetTableModel rstm, int mrow, int mcol)
	{
		if ( ! isTableToolTipEnabled() )
			return null;
		
		String tt = getTableToolTipTextWithPicture(rstm, mrow, mcol, "{call ${PKG:titles_pkg}get_title_picture(?,?)}", "title_id", AddOrChangeAuthor.NO_PICTURE, new Dimension(300, 400));

		// Include: Get Sales Report
		if (true)
		{
    		int titleId = rstm.getValueAsInteger(mrow, "title_id", false);
    
    		SqlStatement stmnt = new SqlStatement(Type.CALLABLE, "{call ${PKG:titles_pkg}get_title_report(?, ?)}");
    
    		stmnt.addParam( SqlStatementParam.createInParam ("p_title_id",      Types.INTEGER, titleId ) );
    		stmnt.addParam( SqlStatementParam.createOutParam("p_report_output", Types.VARCHAR));
    
    		stmnt.execute(getConnectionProvider(), getOwner(), "Sales Details Report <b>failed.</b>");
    
    		String report = (String) stmnt.getParameterValue("p_report_output");
			if (StringUtil.hasValue(report))
			{
        		report = "<h3>Sales Details Report</h3>" + report.replace(";", "<br>");
        		
        		if (tt != null)
        			tt = tt.replace("</html>", report + "</html>");
			}
		}
		return tt;
	}

	@Override
	public JPopupMenu createDataTablePopupMenu(final ResultSetTable tab)
	{
		JPopupMenu pm = super.createDataTablePopupMenu(tab);

		JMenuItem mi;
		final JMenuItem salesDetails_mi = new JMenuItem("Sales Details...");
		
		mi = salesDetails_mi;
		mi.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				int vrow = tab.getSelectedRow();
				int titleId = tab.getValueAsInteger(vrow, "title_id", false);
				
				SqlStatement stmnt = new SqlStatement(Type.CALLABLE, "{call ${PKG:titles_pkg}get_title_report(?, ?)}");

				stmnt.addParam( SqlStatementParam.createInParam ("p_title_id",      Types.INTEGER, titleId ) );
				stmnt.addParam( SqlStatementParam.createOutParam("p_report_output", Types.VARCHAR));

				stmnt.execute(getConnectionProvider(), getOwner(), "Sales Details Report <b>failed.</b>");

				String report = (String) stmnt.getParameterValue("p_report_output");
				if (StringUtil.hasValue(report))
					SwingUtils.showInfoMessage(getOwner(), "Sales Details Report", report);
			}
		});
		pm.add(mi);

		pm.addPopupMenuListener(new PopupMenuListener()
		{
			@Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
			@Override public void popupMenuCanceled(PopupMenuEvent e) {}
			
			@Override
			public void popupMenuWillBecomeVisible(PopupMenuEvent e)
			{
				boolean enable = tab.getSelectedRowCount() == 1;
				if (salesDetails_mi != null) salesDetails_mi.setEnabled(enable);
			}
		});

		return pm;
	}
}
