/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"

#ifndef _DBAUI_PARAMDIALOG_HXX_
#include "paramdialog.hxx"
#endif
#ifndef _DBAUI_PARAMDIALOG_HRC_
#include "paramdialog.hrc"
#endif
#ifndef _DBU_DLG_HRC_
#include "dbu_dlg.hrc"
#endif
#ifndef _DBAUI_COMMON_TYPES_HXX_
#include "commontypes.hxx"
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTER_HPP_
#include <com/sun/star/util/XNumberFormatter.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
#include <com/sun/star/sdbc/DataType.hpp>
#endif
#ifndef _CONNECTIVITY_DBTOOLS_HXX_
#include <connectivity/dbtools.hxx>
#endif
#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
#include "dbustrings.hrc"
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#include <tools/diagnose_ex.h>
#ifndef _DBAUI_LOCALRESACCESS_HXX_
#include "localresaccess.hxx"
#endif
#ifndef INCLUDED_SVTOOLS_SYSLOCALE_HXX
#include <unotools/syslocale.hxx>
#endif

#define EF_VISITED		0x0001
#define EF_DIRTY		0x0002

//.........................................................................
namespace dbaui
{
//.........................................................................
									
	using namespace ::com::sun::star::uno;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::beans;
	using namespace ::com::sun::star::container;
	using namespace ::com::sun::star::sdbc;
	using namespace ::com::sun::star::util;
	using namespace ::connectivity;

	//==================================================================
	//= OParameterDialog
	//==================================================================

	//------------------------------------------------------------------------------
	#define INIT_MEMBERS()											\
		:ModalDialog( pParent, ModuleRes(DLG_PARAMETERS))			\
		,m_aNamesFrame	(this, ModuleRes(FL_PARAMS))					\
		,m_aAllParams	(this, ModuleRes(LB_ALLPARAMS))					\
		,m_aValueFrame	(this, ModuleRes(FT_VALUE))						\
		,m_aParam		(this, ModuleRes(ET_PARAM))						\
		,m_aTravelNext	(this, ModuleRes(BT_TRAVELNEXT))				\
		,m_aOKBtn		(this, ModuleRes(BT_OK))						\
		,m_aCancelBtn	(this, ModuleRes(BT_CANCEL))					\
		,m_nCurrentlySelected(LISTBOX_ENTRY_NOTFOUND)				\
		,m_xConnection(_rxConnection)								\
		,m_aPredicateInput( _rxORB, _rxConnection, getParseContext() )	\
		,m_bNeedErrorOnCurrent(sal_True)							\


	//------------------------------------------------------------------------------
DBG_NAME(OParameterDialog)

	OParameterDialog::OParameterDialog(
			Window* pParent, const Reference< XIndexAccess > & rParamContainer,
			const Reference< XConnection > & _rxConnection, const Reference< XMultiServiceFactory >& _rxORB)
		INIT_MEMBERS()
	{
        DBG_CTOR(OParameterDialog,NULL);

		if (_rxORB.is())
			m_xFormatter = Reference< XNumberFormatter>(_rxORB->createInstance(
			::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.NumberFormatter"))), UNO_QUERY);
		else {
			DBG_ERROR("OParameterDialog::OParameterDialog: need a service factory!");
        }

		Reference< XNumberFormatsSupplier >  xNumberFormats = ::dbtools::getNumberFormats(m_xConnection, sal_True);
		if (!xNumberFormats.is())
			::comphelper::disposeComponent(m_xFormatter);
		else if (m_xFormatter.is())
			m_xFormatter->attachNumberFormatsSupplier(xNumberFormats);
		try
		{
			DBG_ASSERT(rParamContainer->getCount(), "OParameterDialog::OParameterDialog : can't handle empty containers !");

			m_aFinalValues.realloc(rParamContainer->getCount());
			PropertyValue* pValues = m_aFinalValues.getArray();

			for (sal_Int32 i = 0, nCount = rParamContainer->getCount(); i<nCount; ++i, ++pValues)
			{
				Reference< XPropertySet >  xParamAsSet;
				rParamContainer->getByIndex(i) >>= xParamAsSet;
				OSL_ENSURE(xParamAsSet.is(),"Parameter is null!");
				if(!xParamAsSet.is())
					continue;
				pValues->Name = ::comphelper::getString(xParamAsSet->getPropertyValue(PROPERTY_NAME));
				m_aAllParams.InsertEntry(pValues->Name);

				if (!pValues->Value.hasValue())
					// it won't have a value, 'cause it's default constructed. But may be later we support
					// initializing this dialog with values
					pValues->Value = makeAny(::rtl::OUString());
					// default the values to an empty string

                m_aVisitedParams.push_back(0);
					// not visited, not dirty
			}

			m_xParams = rParamContainer;
		}
		catch(Exception&)
		{
            DBG_UNHANDLED_EXCEPTION();
		}
		

		Construct();

		m_aResetVisitFlag.SetTimeoutHdl(LINK(this, OParameterDialog, OnVisitedTimeout));

		FreeResource();
	}

	//------------------------------------------------------------------------------
	OParameterDialog::~OParameterDialog()
	{
		if (m_aResetVisitFlag.IsActive())
			m_aResetVisitFlag.Stop();

        DBG_DTOR(OParameterDialog,NULL);
    }

	//------------------------------------------------------------------------------
	void OParameterDialog::Construct()
	{
		m_aAllParams.SetSelectHdl(LINK(this, OParameterDialog, OnEntrySelected));
		m_aParam.SetLoseFocusHdl(LINK(this, OParameterDialog, OnValueLoseFocus));
		m_aParam.SetModifyHdl(LINK(this, OParameterDialog, OnValueModified));
		m_aTravelNext.SetClickHdl(LINK(this, OParameterDialog, OnButtonClicked));
		m_aOKBtn.SetClickHdl(LINK(this, OParameterDialog, OnButtonClicked));
		m_aCancelBtn.SetClickHdl(LINK(this, OParameterDialog, OnButtonClicked));

		if (m_aAllParams.GetEntryCount())
		{
			m_aAllParams.SelectEntryPos(0);
			LINK(this, OParameterDialog, OnEntrySelected).Call(&m_aAllParams);

			if (m_aAllParams.GetEntryCount() == 1) 
			{
				m_aTravelNext.Enable(sal_False);
			}

			if (m_aAllParams.GetEntryCount() > 1) 
			{
				m_aOKBtn.SetStyle(m_aOKBtn.GetStyle() & ~WB_DEFBUTTON);
				m_aTravelNext.SetStyle(m_aTravelNext.GetStyle() | WB_DEFBUTTON);
			}
		}

		m_aParam.GrabFocus();
	}

	//------------------------------------------------------------------------------
	IMPL_LINK(OParameterDialog, OnValueLoseFocus, Control*, /*pSource*/)
	{
		if (m_nCurrentlySelected != LISTBOX_ENTRY_NOTFOUND)
		{
			if ( ( m_aVisitedParams[ m_nCurrentlySelected ] & EF_DIRTY ) == 0 )
				// nothing to do, the value isn't dirty
				return 0L;
		}

		// transform the current string according to the param field type
		::rtl::OUString sTransformedText(m_aParam.GetText());
		Reference< XPropertySet >  xParamAsSet;
		m_xParams->getByIndex(m_nCurrentlySelected) >>= xParamAsSet;
		if (xParamAsSet.is())
		{
			if (m_xConnection.is() && m_xFormatter.is())
			{
				::rtl::OUString sParamValue( m_aParam.GetText() );
				sal_Bool bValid = m_aPredicateInput.normalizePredicateString( sParamValue, xParamAsSet );
				m_aParam.SetText( sParamValue );
				if ( bValid )
				{
					// with this the value isn't dirty anymore
					if (m_nCurrentlySelected != LISTBOX_ENTRY_NOTFOUND)
						m_aVisitedParams[m_nCurrentlySelected] &= ~EF_DIRTY;
				}
				else
				{
					if (!m_bNeedErrorOnCurrent)
						return 1L;

					m_bNeedErrorOnCurrent = sal_False;	// will be reset in OnValueModified

					::rtl::OUString sName;
					try 
					{ 
						sName = ::comphelper::getString(xParamAsSet->getPropertyValue(PROPERTY_NAME)); 
					} 
					catch(Exception&) 
					{
                        DBG_UNHANDLED_EXCEPTION();
					}

					String sMessage;
					{
						LocalResourceAccess aDummy(DLG_PARAMETERS, RSC_MODALDIALOG);
						sMessage = String(ModuleRes(STR_COULD_NOT_CONVERT_PARAM));
					}
					sMessage.SearchAndReplaceAll(String::CreateFromAscii("$name$"), sName.getStr());
					ErrorBox(NULL, WB_OK, sMessage).Execute();
					m_aParam.GrabFocus();
					return 1L;
				}
			}
		}

		return 0L;
	}

	//------------------------------------------------------------------------------
	IMPL_LINK(OParameterDialog, OnButtonClicked, PushButton*, pButton)
	{
		if (&m_aCancelBtn == pButton)
		{
			// no interpreting of the given values anymore ....
			m_aParam.SetLoseFocusHdl(Link());	// no direct call from the control anymore ...
			m_bNeedErrorOnCurrent = sal_False;		// in case of any indirect calls -> no error message
			m_aCancelBtn.SetClickHdl(Link());
			m_aCancelBtn.Click();
		}
		else if (&m_aOKBtn == pButton)
		{
			// transfer the current values into the Any
			if (LINK(this, OParameterDialog, OnEntrySelected).Call(&m_aAllParams) != 0L)
			{	// there was an error interpreting the current text
				m_bNeedErrorOnCurrent = sal_True;
					// we're are out of the complex web :) of direct and indirect calls to OnValueLoseFocus now,
					// so the next time it is called we need an error message, again ....
					// (TODO : there surely are better solutions for this ...)
				return 1L;
			}

			if (m_xParams.is())
			{
				// write the parameters
				try
				{
					::rtl::OUString sError;
					PropertyValue* pValues = m_aFinalValues.getArray();
					for (sal_Int32 i = 0, nCount = m_xParams->getCount(); i<nCount; ++i, ++pValues)
					{
						Reference< XPropertySet >  xParamAsSet;
						m_xParams->getByIndex(i) >>= xParamAsSet;

						::rtl::OUString sValue;
						pValues->Value >>= sValue;
						pValues->Value <<= ::rtl::OUString( m_aPredicateInput.getPredicateValue( sValue, xParamAsSet, sal_False ) );
					}
				}
				catch(Exception&)
				{
                    DBG_UNHANDLED_EXCEPTION();
				}
				
			}
			// to close the dialog (which is more code than a simple EndDialog)
			m_aOKBtn.SetClickHdl(Link());
			m_aOKBtn.Click();
		}
		else if (&m_aTravelNext == pButton)
		{
			sal_uInt16 nCurrent = m_aAllParams.GetSelectEntryPos();
			sal_uInt16 nCount = m_aAllParams.GetEntryCount();
			DBG_ASSERT(nCount == m_aVisitedParams.size(), "OParameterDialog::OnButtonClicked : inconsistent lists !");

			// search the next entry in list we haven't visited yet
			sal_uInt16 nNext = (nCurrent + 1) % nCount;
			while ((nNext != nCurrent) && ( m_aVisitedParams[nNext] & EF_VISITED ))
				nNext = (nNext + 1) % nCount;

			if ( m_aVisitedParams[nNext] & EF_VISITED )
				// there is no such "not visited yet" entry -> simpy take the next one
				nNext = (nCurrent + 1) % nCount;

			m_aAllParams.SelectEntryPos(nNext);
			LINK(this, OParameterDialog, OnEntrySelected).Call(&m_aAllParams);
			m_bNeedErrorOnCurrent = sal_True;
				// we're are out of the complex web :) of direct and indirect calls to OnValueLoseFocus now,
				// so the next time it is called we need an error message, again ....
				// (TODO : there surely are better solutions for this ...)
		}

		return 0L;
	}

	//------------------------------------------------------------------------------
	IMPL_LINK(OParameterDialog, OnEntrySelected, ListBox*, /*pList*/)
	{
		if (m_aResetVisitFlag.IsActive())
		{
			LINK(this, OParameterDialog, OnVisitedTimeout).Call(&m_aResetVisitFlag);
			m_aResetVisitFlag.Stop();
		}
		// save the old values
		if (m_nCurrentlySelected != LISTBOX_ENTRY_NOTFOUND)
		{
			// do the transformation of the current text
			if (LINK(this, OParameterDialog, OnValueLoseFocus).Call(&m_aParam) != 0L)
			{	// there was an error interpreting the text
				m_aAllParams.SelectEntryPos(m_nCurrentlySelected);
				return 1L;
			}

			m_aFinalValues[m_nCurrentlySelected].Value <<= ::rtl::OUString(m_aParam.GetText());
		}

		// initialize the controls with the new values
		sal_uInt16 nSelected = m_aAllParams.GetSelectEntryPos();
		DBG_ASSERT(nSelected != LISTBOX_ENTRY_NOTFOUND, "OParameterDialog::OnEntrySelected : no current entry !");

		m_aParam.SetText(::comphelper::getString(m_aFinalValues[nSelected].Value));
		m_nCurrentlySelected = nSelected;

		// with this the value isn't dirty
		DBG_ASSERT(m_nCurrentlySelected < m_aVisitedParams.size(), "OParameterDialog::OnEntrySelected : invalid current entry !");
		m_aVisitedParams[m_nCurrentlySelected] &= ~EF_DIRTY;

		m_aResetVisitFlag.SetTimeout(1000);
		m_aResetVisitFlag.Start();

		return 0L;
	}

	//------------------------------------------------------------------------------
	IMPL_LINK(OParameterDialog, OnVisitedTimeout, Timer*, /*pTimer*/)
	{
		DBG_ASSERT(m_nCurrentlySelected != LISTBOX_ENTRY_NOTFOUND, "OParameterDialog::OnVisitedTimeout : invalid call !");

		// mark the currently selected entry as visited
		DBG_ASSERT(m_nCurrentlySelected < m_aVisitedParams.size(), "OParameterDialog::OnVisitedTimeout : invalid entry !");
		m_aVisitedParams[m_nCurrentlySelected] |= EF_VISITED;

		// was it the last "not visited yet" entry ?
		ConstByteVectorIterator aIter;
		for	(	aIter = m_aVisitedParams.begin();
				aIter < m_aVisitedParams.end();
				++aIter
			)
		{
			if (((*aIter) & EF_VISITED) == 0)
				break;
		}
		if (aIter == m_aVisitedParams.end())
		{	// yes, there isn't another one -> change the "default button"
			m_aTravelNext.SetStyle(m_aTravelNext.GetStyle() & ~WB_DEFBUTTON);
			m_aOKBtn.SetStyle(m_aOKBtn.GetStyle() | WB_DEFBUTTON);
			
			// set to focus to one of the buttons temporary (with this their "default"-state is really updated)
			Window* pOldFocus = Application::GetFocusWindow();

			// if the old focus window is the value edit do some preparations ...
			Selection aSel;
			if (pOldFocus == &m_aParam)
			{
				m_aParam.SetLoseFocusHdl(Link());
				aSel = m_aParam.GetSelection();
			}
			m_aTravelNext.GrabFocus();
			if (pOldFocus)
				pOldFocus->GrabFocus();

			// restore the settings for the value edit
			if (pOldFocus == &m_aParam)
			{
				m_aParam.SetLoseFocusHdl(LINK(this, OParameterDialog, OnValueLoseFocus));
				m_aParam.SetSelection(aSel);
			}
		}

		return 0L;
	}

	//------------------------------------------------------------------------------
	IMPL_LINK(OParameterDialog, OnValueModified, Control*, /*pBox*/)
	{
		// mark the currently selected entry as dirty
		DBG_ASSERT(m_nCurrentlySelected < m_aVisitedParams.size(), "OParameterDialog::OnValueModified : invalid entry !");
		m_aVisitedParams[m_nCurrentlySelected] |= EF_DIRTY;

		m_bNeedErrorOnCurrent = sal_True;

		return 0L;
	}


//.........................................................................
}	// namespace dbaui
//.........................................................................
