/**************************************************************
 *
 * 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.
 *
 *************************************************************/


#ifndef _SVX_FMEXCH_HXX
#define _SVX_FMEXCH_HXX

#include <comphelper/stl_types.hxx>
#include <svtools/transfer.hxx>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/container/XNameContainer.hpp>
#include <tools/link.hxx>

#include <svx/svxdllapi.h>

class FmFormShell;
class FmFormPage;
class SvLBoxEntry;

//========================================================================
// Exchange types
#define SVX_FM_FIELD_EXCH			String("SvxFormFieldExch",				sizeof("SvxFormFieldExch"))
#define SVX_FM_CONTROL_EXCH			String("SvxFormExplCtrlExch",			sizeof("SvxFormExplCtrlExch"))
#define SVX_FM_CONTROLS_AS_PATH		String("SvxFormControlsAsPathExchange",	sizeof("SvxFormControlsAsPathExchange"))
#define SVX_FM_HIDDEN_CONTROLS		String("SvxFormHiddenControlsExchange",	sizeof("SvxFormHiddenControlsExchange"))
#define SVX_FM_FILTER_FIELDS		String("SvxFilterFieldExchange",		sizeof("SvxFilterFieldExchange"))

//========================================================================
class SvTreeListBox;

//........................................................................
namespace svxform
{
//........................................................................

	//====================================================================

    typedef ::std::set< SvLBoxEntry* >  ListBoxEntrySet;

	//====================================================================
	//= OLocalExchange
	//====================================================================
	class SVX_DLLPUBLIC OLocalExchange : public TransferableHelper
	{
	private:
		Link				m_aClipboardListener;
		sal_Bool			m_bDragging			: 1;
		sal_Bool			m_bClipboardOwner	: 1;

	public:
		class GrantAccess
		{
			friend class OLocalExchangeHelper;
		};

	public:
		OLocalExchange( );

		sal_Bool	isDragging() const { return m_bDragging; }
		sal_Bool	isClipboardOwner() const { return m_bClipboardOwner; }

		void		startDrag( Window* pWindow, sal_Int8 nDragSourceActions, const GrantAccess& );
		void		copyToClipboard( Window* _pWindow, const GrantAccess& );

		void		setClipboardListener( const Link& _rListener ) { m_aClipboardListener = _rListener; }

		void		clear();

		static	sal_Bool	hasFormat( const DataFlavorExVector& _rFormats, sal_uInt32 _nFormatId );

	protected:
		// XClipboardOwner
	    virtual void SAL_CALL lostOwnership( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard >& _rxClipboard, const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& _rxTrans ) throw(::com::sun::star::uno::RuntimeException);

		// TransferableHelper
		virtual void		DragFinished( sal_Int8 nDropAction );
		virtual sal_Bool	GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor );

	private:
		void StartDrag( Window* pWindow, sal_Int8 nDragSourceActions, sal_Int32 nDragPointer = DND_POINTER_NONE, sal_Int32 nDragImage = DND_IMAGE_NONE )
		{	// don't allow this base class method to be called from outside
			TransferableHelper::StartDrag(pWindow, nDragSourceActions, nDragPointer, nDragImage);
		}
	};

	//====================================================================
	//= OLocalExchangeHelper
	//====================================================================
	/// a helper for navigator windows (SvTreeListBox'es) which allow DnD within themself
	class SVX_DLLPUBLIC OLocalExchangeHelper
	{
	protected:
		Window*				m_pDragSource;
		OLocalExchange*		m_pTransferable;

	public:
		OLocalExchangeHelper( Window* _pDragSource );
		virtual ~OLocalExchangeHelper();

		void		prepareDrag( );

		void		startDrag( sal_Int8 nDragSourceActions );
		void		copyToClipboard( ) const;

		inline	sal_Bool	isDragSource() const { return m_pTransferable && m_pTransferable->isDragging(); }
		inline	sal_Bool	isClipboardOwner() const { return m_pTransferable && m_pTransferable->isClipboardOwner(); }
		inline	sal_Bool	isDataExchangeActive( ) const { return isDragSource() || isClipboardOwner(); }
        inline  void        clear() { if ( isDataExchangeActive() ) m_pTransferable->clear(); }

		SVX_DLLPRIVATE void		setClipboardListener( const Link& _rListener ) { if ( m_pTransferable ) m_pTransferable->setClipboardListener( _rListener ); }

	protected:
		SVX_DLLPRIVATE virtual OLocalExchange* createExchange() const = 0;

	protected:
		SVX_DLLPRIVATE void implReset();
	};

	//====================================================================
	//= OControlTransferData
	//====================================================================
	class OControlTransferData
	{
	private:
		typedef ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< sal_uInt32 > > ControlPaths;

	private:
		DataFlavorExVector	m_aCurrentFormats;

	protected:
		ListBoxEntrySet	    m_aSelectedEntries;
		ControlPaths		m_aControlPaths;
		::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > >
							m_aHiddenControlModels;

		::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
							m_xFormsRoot;		// the root of the forms collection where the entries we represent reside
												// this uniquely identifies the page and the document

		SvLBoxEntry*		m_pFocusEntry;

	protected:
		// updates m_aCurrentFormats with all formats we currently could supply
		void	updateFormats( );

	public:
		OControlTransferData( );

		// ctor to construct the data from an arbitrary Transferable (usually clipboard data)
		OControlTransferData(
			const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& _rxTransferable
		);

		inline const DataFlavorExVector&	GetDataFlavorExVector() const;

		void addSelectedEntry( SvLBoxEntry* _pEntry );
		void setFocusEntry( SvLBoxEntry* _pFocusEntry );

        /** notifies the data transfer object that a certain entry has been removed from the owning tree

            In case the removed entry is part of the transfer object's selection, the entry is removed from
            the selection.

            @param  _pEntry
            @return the number of entries remaining in the selection.
        */
        size_t  onEntryRemoved( SvLBoxEntry* _pEntry );

		void setFormsRoot(
			const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& _rxFormsRoot
			) { m_xFormsRoot = _rxFormsRoot; }

		void buildPathFormat(SvTreeListBox* pTreeBox, SvLBoxEntry* pRoot);
			// baut aus m_aSelectedEntries m_aControlPaths auf
			// (es wird davon ausgegangen, dass die Eintraege in m_aSelectedEntries sortiert sind in Bezug auf die Nachbar-Beziehung)


		void buildListFromPath(SvTreeListBox* pTreeBox, SvLBoxEntry* pRoot);
			// der umgekehrte Weg : wirft alles aus m_aSelectedEntries weg und baut es mittels m_aControlPaths neu auf

		void addHiddenControlsFormat(const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > seqInterfaces);
			// fuegt ein SVX_FML_HIDDEN_CONTROLS-Format hinzu und merk sich dafuer die uebergebenen Interfaces
			// (es erfolgt KEINE Ueberpruefung, ob dadurch auch tatsaechlich nur hidden Controls bezeichnet werden, dass muss der
			// Aufrufer sicherstellen)

		SvLBoxEntry*				focused() const { return m_pFocusEntry; }
		const ListBoxEntrySet&	    selected() const { return m_aSelectedEntries; }
		::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > >
									hiddenControls() const { return m_aHiddenControlModels; }

		::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
								getFormsRoot() const { return m_xFormsRoot; }
	};

	//====================================================================
	inline const DataFlavorExVector& OControlTransferData::GetDataFlavorExVector() const
	{
		const_cast< OControlTransferData* >( this )->updateFormats( );
		return m_aCurrentFormats;
	}

	//====================================================================
	//= OControlExchange
	//====================================================================
	class OControlExchange : public OLocalExchange, public OControlTransferData
	{
	public:
		OControlExchange( );

	public:
		static sal_uInt32		getFieldExchangeFormatId( );
		static sal_uInt32		getControlPathFormatId( );
		static sal_uInt32		getHiddenControlModelsFormatId( );

		inline static sal_Bool	hasFieldExchangeFormat( const DataFlavorExVector& _rFormats );
		inline static sal_Bool	hasControlPathFormat( const DataFlavorExVector& _rFormats );
		inline static sal_Bool	hasHiddenControlModelsFormat( const DataFlavorExVector& _rFormats );

	protected:
		virtual sal_Bool	GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor );
		virtual void		AddSupportedFormats();
	};

	//====================================================================
	//= OControlExchangeHelper
	//====================================================================
	class OControlExchangeHelper : public OLocalExchangeHelper
	{
	public:
		OControlExchangeHelper(Window* _pDragSource) : OLocalExchangeHelper(_pDragSource) { }

		OControlExchange* operator->() const { return static_cast< OControlExchange* >( m_pTransferable ); }
		OControlExchange& operator*() const { return *static_cast< OControlExchange* >( m_pTransferable ); }

	protected:
		virtual OLocalExchange* createExchange() const;
	};

	//====================================================================
	//====================================================================
	inline sal_Bool OControlExchange::hasFieldExchangeFormat( const DataFlavorExVector& _rFormats )
	{
		return hasFormat( _rFormats, getFieldExchangeFormatId() );
	}

	inline sal_Bool OControlExchange::hasControlPathFormat( const DataFlavorExVector& _rFormats )
	{
		return hasFormat( _rFormats, getControlPathFormatId() );
	}

	inline sal_Bool OControlExchange::hasHiddenControlModelsFormat( const DataFlavorExVector& _rFormats )
	{
		return hasFormat( _rFormats, getHiddenControlModelsFormatId() );
	}

//........................................................................
}	// namespace svxform
//........................................................................

#endif
