/**************************************************************
 *
 * 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_svx.hxx"

#include "tabwin.hxx"
#include "svx/fmtools.hxx"
#include "fmservs.hxx"
#include "stringlistresource.hxx"

#include <svx/svxids.hrc>
#include <svx/dbaexchange.hxx>
#include <com/sun/star/sdb/CommandType.hpp>
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#include <com/sun/star/sdb/XQueriesSupplier.hpp>
#include <com/sun/star/sdbc/XPreparedStatement.hpp>
#include <com/sun/star/awt/XControlContainer.hpp>
#include <com/sun/star/util/XLocalizedAliases.hpp>
#include <comphelper/processfactory.hxx>
#include <comphelper/stl_types.hxx>

#ifndef _SVX_FMHELP_HRC
#include "fmhelp.hrc"
#endif
#include <svx/fmshell.hxx>
#include "fmshimp.hxx"
#include "svx/dbtoolsclient.hxx"
#include <svx/fmpage.hxx>

#ifndef _SVX_FMPGEIMP_HXX
#include "fmpgeimp.hxx"
#endif

#ifndef _SVX_FMPROP_HRC
#include "fmprop.hrc"
#endif

#ifndef _SVX_FMRESIDS_HRC
#include "svx/fmresids.hrc"
#endif
#include <svx/dialmgr.hxx>
#include <tools/shl.hxx>
#include <svx/svdpagv.hxx>
#include <sfx2/objitem.hxx>
#include <sfx2/dispatch.hxx>
#include <comphelper/property.hxx>
#include <sfx2/frame.hxx>
#include <svx/dataaccessdescriptor.hxx>

const long STD_WIN_POS_X = 50;
const long STD_WIN_POS_Y = 50;

const long STD_WIN_SIZE_X = 120;
const long STD_WIN_SIZE_Y = 150;

const long MIN_WIN_SIZE_X = 50;
const long MIN_WIN_SIZE_Y = 50;

const long LISTBOX_BORDER = 2;

using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::datatransfer;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::form;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star;
using namespace ::svxform;
using namespace ::svx;


struct ColumnInfo
{
    ::rtl::OUString sColumnName;
    ::rtl::OUString sLabel;
    bool bColumn;
    ColumnInfo(const ::rtl::OUString& i_sColumnName,const ::rtl::OUString& i_sLabel)
        : sColumnName(i_sColumnName)
        , sLabel(i_sLabel)
        , bColumn(true)
    {
    }
    ColumnInfo(const ::rtl::OUString& i_sColumnName)
        : sColumnName(i_sColumnName)
        , bColumn(false)
    {
    }
};

void lcl_addToList( SvTreeListBox& _rListBox, const uno::Reference< container::XNameAccess>& i_xColumns )
{
    uno::Sequence< ::rtl::OUString > aEntries = i_xColumns->getElementNames();
	const ::rtl::OUString* pEntries = aEntries.getConstArray();
	sal_Int32 nEntries = aEntries.getLength();
	for ( sal_Int32 i = 0; i < nEntries; ++i, ++pEntries )
    {
        uno::Reference< beans::XPropertySet> xColumn(i_xColumns->getByName(*pEntries),UNO_QUERY_THROW);
        ::rtl::OUString sLabel;
        if ( xColumn->getPropertySetInfo()->hasPropertyByName(FM_PROP_LABEL) )
            xColumn->getPropertyValue(FM_PROP_LABEL) >>= sLabel;
        if ( sLabel.getLength() )
		    _rListBox.InsertEntry( sLabel,NULL,sal_False,LIST_APPEND,new ColumnInfo(*pEntries,sLabel) );
        else
            _rListBox.InsertEntry( *pEntries,NULL,sal_False,LIST_APPEND,new ColumnInfo(*pEntries,sLabel) );
    }
}
//==================================================================
// class FmFieldWinListBox
//==================================================================
DBG_NAME(FmFieldWinListBox)
//------------------------------------------------------------------------------
FmFieldWinListBox::FmFieldWinListBox( FmFieldWin* pParent )
	:SvTreeListBox( pParent, WB_HASBUTTONS|WB_BORDER )
	,pTabWin( pParent )
{
	DBG_CTOR(FmFieldWinListBox,NULL);
	SetHelpId( HID_FIELD_SEL );

	SetHighlightRange( );
}

//------------------------------------------------------------------------------
FmFieldWinListBox::~FmFieldWinListBox()
{
	DBG_DTOR(FmFieldWinListBox,NULL);
}

//------------------------------------------------------------------------------
sal_Int8 FmFieldWinListBox::AcceptDrop( const AcceptDropEvent& /*rEvt*/ )
{
	return DND_ACTION_NONE;
}

//------------------------------------------------------------------------------
sal_Int8 FmFieldWinListBox::ExecuteDrop( const ExecuteDropEvent& /*rEvt*/ )
{
	return DND_ACTION_NONE;
}

//------------------------------------------------------------------------------
sal_Bool FmFieldWinListBox::DoubleClickHdl()
{
	if ( pTabWin->createSelectionControls() )
		return sal_True;

	return SvTreeListBox::DoubleClickHdl();
}

//------------------------------------------------------------------------------
void FmFieldWinListBox::StartDrag( sal_Int8 /*_nAction*/, const Point& /*_rPosPixel*/ )
{
	SvLBoxEntry* pSelected = FirstSelected();
	if (!pSelected)
		// no drag without a field
		return;

    ::svx::ODataAccessDescriptor aDescriptor;
    aDescriptor[ daDataSource ] <<= pTabWin->GetDatabaseName();
    aDescriptor[ daConnection ] <<= pTabWin->GetConnection().getTyped();
    aDescriptor[ daCommand ]    <<= pTabWin->GetObjectName();
    aDescriptor[ daCommandType ]<<= pTabWin->GetObjectType();
    ColumnInfo* pInfo = static_cast<ColumnInfo*>(pSelected->GetUserData());
	aDescriptor[ daColumnName ]	<<= pInfo->sColumnName;

    TransferableHelper* pTransferColumn = new OColumnTransferable(
		aDescriptor, CTF_FIELD_DESCRIPTOR | CTF_CONTROL_EXCHANGE | CTF_COLUMN_DESCRIPTOR
	);
	Reference< XTransferable> xEnsureDelete = pTransferColumn;
	if (pTransferColumn)
	{
		EndSelection();
		pTransferColumn->StartDrag( this, DND_ACTION_COPY );
	}
}

//========================================================================
// class FmFieldWinData
//========================================================================
DBG_NAME(FmFieldWinData);
//-----------------------------------------------------------------------
FmFieldWinData::FmFieldWinData()
{
	DBG_CTOR(FmFieldWinData,NULL);
}

//-----------------------------------------------------------------------
FmFieldWinData::~FmFieldWinData()
{
	DBG_DTOR(FmFieldWinData,NULL);
}

//========================================================================
// class FmFieldWin
//========================================================================
DBG_NAME(FmFieldWin);
//-----------------------------------------------------------------------
FmFieldWin::FmFieldWin(SfxBindings* _pBindings, SfxChildWindow* _pMgr, Window* _pParent)
			:SfxFloatingWindow(_pBindings, _pMgr, _pParent, WinBits(WB_STDMODELESS|WB_SIZEABLE))
			,SfxControllerItem(SID_FM_FIELDS_CONTROL, *_pBindings)
			,::comphelper::OPropertyChangeListener(m_aMutex)
			,pData(new FmFieldWinData)
			,m_nObjectType(0)
			,m_pChangeListener(NULL)
{
	DBG_CTOR(FmFieldWin,NULL);
	SetHelpId( HID_FIELD_SEL_WIN );

	SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetFaceColor()) );
	pListBox = new FmFieldWinListBox( this );
	pListBox->Show();
	UpdateContent(NULL);
	SetSizePixel(Size(STD_WIN_SIZE_X,STD_WIN_SIZE_Y));
}

//-----------------------------------------------------------------------
FmFieldWin::~FmFieldWin()
{
	if (m_pChangeListener)
	{
		m_pChangeListener->dispose();
		m_pChangeListener->release();
		//	delete m_pChangeListener;
	}
	delete pListBox;
	delete pData;
	DBG_DTOR(FmFieldWin,NULL);
}

//-----------------------------------------------------------------------
void FmFieldWin::GetFocus()
{
	if ( pListBox )
		pListBox->GrabFocus();
	else
		SfxFloatingWindow::GetFocus();
}

//-----------------------------------------------------------------------
sal_Bool FmFieldWin::createSelectionControls( )
{
	SvLBoxEntry* pSelected = pListBox->FirstSelected();
	if ( pSelected )
	{
		// build a descriptor for the currently selected field
		ODataAccessDescriptor aDescr;
		aDescr.setDataSource(GetDatabaseName());

		aDescr[ daConnection ]  <<= GetConnection().getTyped();

        aDescr[ daCommand ]		<<= GetObjectName();
		aDescr[ daCommandType ]	<<= GetObjectType();
        ColumnInfo* pInfo = static_cast<ColumnInfo*>(pSelected->GetUserData());
		aDescr[ daColumnName ]	<<= pInfo->sColumnName;//::rtl::OUString( pListBox->GetEntryText( pSelected) );

		// transfer this to the SFX world
		SfxUnoAnyItem aDescriptorItem( SID_FM_DATACCESS_DESCRIPTOR, makeAny( aDescr.createPropertyValueSequence() ) );
		const SfxPoolItem* pArgs[] =
		{
			&aDescriptorItem, NULL
		};

		// execute the create slot
		GetBindings().Execute( SID_FM_CREATE_FIELDCONTROL, pArgs );
	}

	return NULL != pSelected;
}

//-----------------------------------------------------------------------
long FmFieldWin::PreNotify( NotifyEvent& _rNEvt )
{
	if ( EVENT_KEYINPUT == _rNEvt.GetType() )
	{
		const KeyCode& rKeyCode = _rNEvt.GetKeyEvent()->GetKeyCode();
		if ( ( 0 == rKeyCode.GetModifier() ) && ( KEY_RETURN == rKeyCode.GetCode() ) )
		{
			if ( createSelectionControls() )
				return 1;
		}
	}

	return SfxFloatingWindow::PreNotify( _rNEvt );
}

//-----------------------------------------------------------------------
sal_Bool FmFieldWin::Close()
{
	return SfxFloatingWindow::Close();
}

//-----------------------------------------------------------------------
void FmFieldWin::_propertyChanged(const ::com::sun::star::beans::PropertyChangeEvent& evt) throw( ::com::sun::star::uno::RuntimeException )
{
	::com::sun::star::uno::Reference< ::com::sun::star::form::XForm >  xForm(evt.Source, ::com::sun::star::uno::UNO_QUERY);
	UpdateContent(xForm);
}

//-----------------------------------------------------------------------
void FmFieldWin::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState)
{
	if (!pState  || SID_FM_FIELDS_CONTROL != nSID)
		return;

	if (eState >= SFX_ITEM_AVAILABLE)
	{
		FmFormShell* pShell = PTR_CAST(FmFormShell,((SfxObjectItem*)pState)->GetShell());
		UpdateContent(pShell);
	}
	else
		UpdateContent(NULL);
}

//-----------------------------------------------------------------------
void FmFieldWin::UpdateContent(FmFormShell* pShell)
{
	pListBox->Clear();
	String aTitle( SVX_RES( RID_STR_FIELDSELECTION ) );
	SetText( aTitle );

	if (!pShell || !pShell->GetImpl())
		return;

	Reference< XForm >  xForm = pShell->GetImpl()->getCurrentForm();
	if ( xForm.is() )
	    UpdateContent( xForm );
}

//-----------------------------------------------------------------------
void FmFieldWin::UpdateContent(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm > & xForm)
{
    try
    {
        // ListBox loeschen
	    pListBox->Clear();
	    UniString aTitle(SVX_RES(RID_STR_FIELDSELECTION));
	    SetText(aTitle);

	    if (!xForm.is())
		    return;

	    Reference< XPreparedStatement >  xStatement;
	    Reference< XPropertySet >  xSet(xForm, UNO_QUERY);

	    m_aObjectName	= ::comphelper::getString(xSet->getPropertyValue(FM_PROP_COMMAND));
	    m_aDatabaseName	= ::comphelper::getString(xSet->getPropertyValue(FM_PROP_DATASOURCE));
	    m_nObjectType 	= ::comphelper::getINT32(xSet->getPropertyValue(FM_PROP_COMMANDTYPE));

	    // get the connection of the form
        OStaticDataAccessTools aTools;
        m_aConnection.reset(
            aTools.connectRowset( Reference< XRowSet >( xForm, UNO_QUERY ), ::comphelper::getProcessServiceFactory(), sal_True ),
            SharedConnection::NoTakeOwnership
        );
        // TODO: When incompatible changes (such as extending the "virtualdbtools" interface by ensureRowSetConnection)
        // are allowed, again, we should change this: dbtools should consistently use SharedConnection all over
        // the place, and connectRowset should be replaced with ensureRowSetConnection

        // get the fields of the object

	    if ( m_aConnection.is() && m_aObjectName.getLength() )
        {
            Reference< XComponent > xKeepFieldsAlive;
            Reference< XNameAccess > xColumns = getFieldsByCommandDescriptor( m_aConnection, m_nObjectType, m_aObjectName,xKeepFieldsAlive );
            if ( xColumns.is() )
                lcl_addToList(*pListBox,xColumns);
        }

	    // Prefix setzen
	    UniString  aPrefix;
        StringListResource aPrefixes( SVX_RES( RID_RSC_TABWIN_PREFIX ) );

	    switch (m_nObjectType)
	    {
		    case CommandType::TABLE:
			    aPrefix = aPrefixes[0];
			    break;
		    case CommandType::QUERY:
			    aPrefix = aPrefixes[1];
			    break;
		    default:
			    aPrefix = aPrefixes[2];
			    break;
	    }

	    // an dem PropertySet nach Aenderungen der ControlSource lauschen
	    if (m_pChangeListener)
	    {
		    m_pChangeListener->dispose();
		    m_pChangeListener->release();
	    }
	    m_pChangeListener = new ::comphelper::OPropertyChangeMultiplexer(this, xSet);
	    m_pChangeListener->acquire();
	    m_pChangeListener->addProperty(FM_PROP_DATASOURCE);
	    m_pChangeListener->addProperty(FM_PROP_COMMAND);
	    m_pChangeListener->addProperty(FM_PROP_COMMANDTYPE);

        // Titel setzen
	    aTitle.AppendAscii(" ");
	    aTitle += aPrefix;
	    aTitle.AppendAscii(" ");
	    aTitle += m_aObjectName.getStr();
	    SetText( aTitle );
    }
    catch( const Exception& )
    {
        DBG_ERROR( "FmTabWin::UpdateContent: caught an exception!" );
    }
}

//-----------------------------------------------------------------------
void FmFieldWin::Resize()
{
	SfxFloatingWindow::Resize();

	Point aPos(GetPosPixel());
	Size aOutputSize( GetOutputSizePixel() );

	//////////////////////////////////////////////////////////////////////

	// Groesse der ::com::sun::star::form::ListBox anpassen
	Point aLBPos( LISTBOX_BORDER, LISTBOX_BORDER );
	Size aLBSize( aOutputSize );
	aLBSize.Width() -= (2*LISTBOX_BORDER);
	aLBSize.Height() -= (2*LISTBOX_BORDER);

	pListBox->SetPosSizePixel( aLBPos, aLBSize );
}

//-----------------------------------------------------------------------
void FmFieldWin::FillInfo( SfxChildWinInfo& rInfo ) const
{
	rInfo.bVisible = sal_False;
}

//-----------------------------------------------------------------------
SFX_IMPL_FLOATINGWINDOW(FmFieldWinMgr, SID_FM_ADD_FIELD)

//-----------------------------------------------------------------------
FmFieldWinMgr::FmFieldWinMgr(Window* _pParent, sal_uInt16 _nId,
			   SfxBindings* _pBindings, SfxChildWinInfo* _pInfo)
			  :SfxChildWindow(_pParent, _nId)
{
	pWindow = new FmFieldWin(_pBindings, this, _pParent);
	SetHideNotDelete(sal_True);
	eChildAlignment = SFX_ALIGN_NOALIGNMENT;
	((SfxFloatingWindow*)pWindow)->Initialize( _pInfo );
}
