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

#include <sot/storage.hxx>
#include <svl/itempool.hxx>

#ifndef _SVX_DBEXCH_HRC
#include <svx/dbexch.hrc>
#endif
#include <sot/formats.hxx>
#include <svtools/svtreebx.hxx>
#include <tools/diagnose_ex.h>

#define _SVSTDARR_ULONGS
#include <svl/svstdarr.hxx>

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

	using namespace ::com::sun::star::uno;
	using namespace ::com::sun::star::datatransfer;

	//====================================================================
	//= OLocalExchange
	//====================================================================
	//--------------------------------------------------------------------
	OLocalExchange::OLocalExchange( )
		:m_bDragging( sal_False )
		,m_bClipboardOwner( sal_False )
	{
	}

	//--------------------------------------------------------------------
	void OLocalExchange::copyToClipboard( Window* _pWindow, const GrantAccess& )
	{
		if ( m_bClipboardOwner )
		{	// simulate a lostOwnership to notify parties interested in
			if ( m_aClipboardListener.IsSet() )
				m_aClipboardListener.Call( this );
		}

		m_bClipboardOwner = sal_True;
		CopyToClipboard( _pWindow );
	}

	//--------------------------------------------------------------------
	void OLocalExchange::clear()
	{
		if ( isClipboardOwner() )
		{
			try
			{
				Reference< clipboard::XClipboard > xClipBoard( getOwnClipboard() );
				if ( xClipBoard.is() )
					xClipBoard->setContents( NULL, NULL );
			}
			catch( const Exception& )
			{
                DBG_UNHANDLED_EXCEPTION();
			}
			m_bClipboardOwner = sal_False;
		}
	}

	//--------------------------------------------------------------------
    void SAL_CALL OLocalExchange::lostOwnership( const Reference< clipboard::XClipboard >& _rxClipboard, const Reference< XTransferable >& _rxTrans ) throw(RuntimeException)
	{
		TransferableHelper::implCallOwnLostOwnership( _rxClipboard, _rxTrans );
		m_bClipboardOwner = sal_False;

		if ( m_aClipboardListener.IsSet() )
			m_aClipboardListener.Call( this );
	}

	//--------------------------------------------------------------------
	void OLocalExchange::startDrag( Window* _pWindow, sal_Int8 _nDragSourceActions, const GrantAccess& )
	{
		m_bDragging = sal_True;
		StartDrag( _pWindow, _nDragSourceActions );
	}

	//--------------------------------------------------------------------
	void OLocalExchange::DragFinished( sal_Int8 nDropAction )
	{
		TransferableHelper::DragFinished( nDropAction );
		m_bDragging = sal_False;
	}

	//--------------------------------------------------------------------
	sal_Bool OLocalExchange::hasFormat( const DataFlavorExVector& _rFormats, sal_uInt32 _nFormatId )
	{
		DataFlavorExVector::const_iterator aSearch;

		for	( aSearch = _rFormats.begin(); aSearch != _rFormats.end(); ++aSearch )
			if ( aSearch->mnSotId == _nFormatId )
				break;

		return aSearch != _rFormats.end();
	}

	//--------------------------------------------------------------------
	sal_Bool OLocalExchange::GetData( const ::com::sun::star::datatransfer::DataFlavor& /*_rFlavor*/ )
	{
		return sal_False;	// do not have any formats by default
	}

	//====================================================================
	//= OControlTransferData
	//====================================================================
	//--------------------------------------------------------------------
	OControlTransferData::OControlTransferData( )
		:m_pFocusEntry( NULL )
	{
	}

	//--------------------------------------------------------------------
	OControlTransferData::OControlTransferData( const Reference< XTransferable >& _rxTransferable )
		:m_pFocusEntry( NULL )
	{
		TransferableDataHelper aExchangedData( _rxTransferable );

		// try the formats we know
		if ( OControlExchange::hasControlPathFormat( aExchangedData.GetDataFlavorExVector() ) )
		{	// paths to the controls, relative to a root
			Sequence< Any > aControlPathData;
			if ( aExchangedData.GetAny( OControlExchange::getControlPathFormatId() ) >>= aControlPathData )
			{
				DBG_ASSERT( aControlPathData.getLength() >= 2, "OControlTransferData::OControlTransferData: invalid data for the control path format!" );
				if ( aControlPathData.getLength() >= 2 )
				{
					aControlPathData[0] >>= m_xFormsRoot;
					aControlPathData[1] >>= m_aControlPaths;
				}
			}
			else
			{
				DBG_ERROR( "OControlTransferData::OControlTransferData: invalid data for the control path format (2)!" );
			}
		}
		if ( OControlExchange::hasHiddenControlModelsFormat( aExchangedData.GetDataFlavorExVector() ) )
		{	// sequence of models of hidden controls
			aExchangedData.GetAny( OControlExchange::getHiddenControlModelsFormatId() ) >>= m_aHiddenControlModels;
		}

		updateFormats( );
	}

	//--------------------------------------------------------------------
	static sal_Bool lcl_fillDataFlavorEx( SotFormatStringId nId, DataFlavorEx& _rFlavor )
	{
		_rFlavor.mnSotId = nId;
		return SotExchange::GetFormatDataFlavor( _rFlavor.mnSotId, _rFlavor );
	}

	//--------------------------------------------------------------------
	void OControlTransferData::updateFormats( )
	{
		m_aCurrentFormats.clear();
		m_aCurrentFormats.reserve( 3 );

		DataFlavorEx aFlavor;

		if ( m_aHiddenControlModels.getLength() )
		{
			if ( lcl_fillDataFlavorEx( OControlExchange::getHiddenControlModelsFormatId(), aFlavor ) )
				m_aCurrentFormats.push_back( aFlavor );
		}

		if ( m_xFormsRoot.is() && m_aControlPaths.getLength() )
		{
			if ( lcl_fillDataFlavorEx( OControlExchange::getControlPathFormatId(), aFlavor ) )
				m_aCurrentFormats.push_back( aFlavor );
		}

		if ( !m_aSelectedEntries.empty() )
		{
			if ( lcl_fillDataFlavorEx( OControlExchange::getFieldExchangeFormatId(), aFlavor ) )
				m_aCurrentFormats.push_back( aFlavor );
		}
	}

	//--------------------------------------------------------------------
	size_t OControlTransferData::onEntryRemoved( SvLBoxEntry* _pEntry )
	{
        m_aSelectedEntries.erase( _pEntry );
        return m_aSelectedEntries.size();
	}

	//--------------------------------------------------------------------
	void OControlTransferData::addSelectedEntry( SvLBoxEntry* _pEntry )
	{
		m_aSelectedEntries.insert( _pEntry );
	}

	//--------------------------------------------------------------------
	void OControlTransferData::setFocusEntry( SvLBoxEntry* _pFocusEntry )
	{
		m_pFocusEntry = _pFocusEntry;
	}

	//------------------------------------------------------------------------
	void OControlTransferData::addHiddenControlsFormat(const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > seqInterfaces)
	{
		m_aHiddenControlModels = seqInterfaces;
	}

	//------------------------------------------------------------------------
	void OControlTransferData::buildPathFormat(SvTreeListBox* pTreeBox, SvLBoxEntry* pRoot)
	{
		m_aControlPaths.realloc(0);

		sal_Int32 nEntryCount = m_aSelectedEntries.size();
		if (nEntryCount == 0)
			return;

		m_aControlPaths.realloc(nEntryCount);
		::com::sun::star::uno::Sequence<sal_uInt32>* pAllPaths = m_aControlPaths.getArray();
        for (   ListBoxEntrySet::const_iterator loop = m_aSelectedEntries.begin();
                loop != m_aSelectedEntries.end();
                ++loop, ++pAllPaths
            )
		{
			// erst mal sammeln wir den Pfad in einem Array ein
			::std::vector< sal_uInt32 > aCurrentPath;
			SvLBoxEntry* pCurrentEntry = *loop;

			SvLBoxEntry* pLoop = pCurrentEntry;
			while (pLoop != pRoot)
			{
				aCurrentPath.push_back(pLoop->GetChildListPos());
				pLoop = pTreeBox->GetParent(pLoop);
				DBG_ASSERT((pLoop != NULL) || (pRoot == 0), "OControlTransferData::buildPathFormat: invalid root or entry !");
					// pLoop == NULL heisst, dass ich am oberen Ende angelangt bin, dann sollte das Ganze abbrechen, was nur bei pRoot == NULL der Fall sein wird
			}

			// dann koennen wir ihn in die ::com::sun::star::uno::Sequence uebertragen
			Sequence<sal_uInt32>& rCurrentPath = *pAllPaths;
			sal_Int32 nDepth = aCurrentPath.size();

			rCurrentPath.realloc(nDepth);
			sal_uInt32* pSeq = rCurrentPath.getArray();
			sal_Int32 j,k;
			for (j = nDepth - 1, k = 0; k<nDepth; --j, ++k)
				pSeq[j] = aCurrentPath[k];
		}
	}

	//------------------------------------------------------------------------
	void OControlTransferData::buildListFromPath(SvTreeListBox* pTreeBox, SvLBoxEntry* pRoot)
	{
        ListBoxEntrySet aEmpty;
		m_aSelectedEntries.swap( aEmpty );

		sal_Int32 nControls = m_aControlPaths.getLength();
		const ::com::sun::star::uno::Sequence<sal_uInt32>* pPaths = m_aControlPaths.getConstArray();
		for (sal_Int32 i=0; i<nControls; ++i)
		{
			sal_Int32 nThisPatLength = pPaths[i].getLength();
			const sal_uInt32* pThisPath = pPaths[i].getConstArray();
			SvLBoxEntry* pSearch = pRoot;
			for (sal_Int32 j=0; j<nThisPatLength; ++j)
				pSearch = pTreeBox->GetEntry(pSearch, pThisPath[j]);

			m_aSelectedEntries.insert( pSearch );
		}
	}

	//====================================================================
	//= OControlExchange
	//====================================================================
	//--------------------------------------------------------------------
	OControlExchange::OControlExchange( )
	{
	}

	//--------------------------------------------------------------------
	sal_Bool OControlExchange::GetData( const DataFlavor& _rFlavor )
	{
		const sal_uInt32 nFormatId = SotExchange::GetFormat( _rFlavor );

		if ( getControlPathFormatId( ) == nFormatId )
		{
			// ugly. We have to pack all the info into one object
			Sequence< Any > aCompleteInfo( 2 );
			OSL_ENSURE( m_xFormsRoot.is(), "OLocalExchange::GetData: invalid forms root for this format!" );
			aCompleteInfo.getArray()[ 0 ] <<= m_xFormsRoot;
			aCompleteInfo.getArray()[ 1 ] <<= m_aControlPaths;

			SetAny( makeAny( aCompleteInfo ), _rFlavor );
		}
		else if ( getHiddenControlModelsFormatId() == nFormatId )
		{
			// just need to transfer the models
			SetAny( makeAny( m_aHiddenControlModels ), _rFlavor );
		}
		else
			return OLocalExchange::GetData( _rFlavor );

		return sal_True;
	}

	//--------------------------------------------------------------------
	void OControlExchange::AddSupportedFormats()
	{
		if (m_pFocusEntry && !m_aSelectedEntries.empty())
			AddFormat(getFieldExchangeFormatId());

		if (m_aControlPaths.getLength())
			AddFormat(getControlPathFormatId());

		if (m_aHiddenControlModels.getLength())
			AddFormat(getHiddenControlModelsFormatId());
	}

	//--------------------------------------------------------------------
	sal_uInt32 OControlExchange::getControlPathFormatId()
	{
		static sal_uInt32 s_nFormat = (sal_uInt32)-1;
		if ((sal_uInt32)-1 == s_nFormat)
		{
			s_nFormat = SotExchange::RegisterFormatName(String::CreateFromAscii("application/x-openoffice;windows_formatname=\"svxform.ControlPathExchange\""));
			DBG_ASSERT((sal_uInt32)-1 != s_nFormat, "OControlExchange::getControlPathFormatId: bad exchange id!");
		}
		return s_nFormat;
	}

	//--------------------------------------------------------------------
	sal_uInt32 OControlExchange::getHiddenControlModelsFormatId()
	{
		static sal_uInt32 s_nFormat = (sal_uInt32)-1;
		if ((sal_uInt32)-1 == s_nFormat)
		{
			s_nFormat = SotExchange::RegisterFormatName(String::CreateFromAscii("application/x-openoffice;windows_formatname=\"svxform.HiddenControlModelsExchange\""));
			DBG_ASSERT((sal_uInt32)-1 != s_nFormat, "OControlExchange::getHiddenControlModelsFormatId: bad exchange id!");
		}
		return s_nFormat;
	}

	//--------------------------------------------------------------------
	sal_uInt32 OControlExchange::getFieldExchangeFormatId()
	{
		static sal_uInt32 s_nFormat = (sal_uInt32)-1;
		if ((sal_uInt32)-1 == s_nFormat)
		{
			s_nFormat = SotExchange::RegisterFormatName(String::CreateFromAscii("application/x-openoffice;windows_formatname=\"svxform.FieldNameExchange\""));
			DBG_ASSERT((sal_uInt32)-1 != s_nFormat, "OControlExchange::getFieldExchangeFormatId: bad exchange id!");
		}
		return s_nFormat;
	}

	//====================================================================
	//= OControlExchangeHelper
	//====================================================================
	OLocalExchange* OControlExchangeHelper::createExchange() const
	{
		return new OControlExchange;
	}

	//====================================================================
	//= OLocalExchangeHelper
	//====================================================================
	//--------------------------------------------------------------------
	OLocalExchangeHelper::OLocalExchangeHelper(Window* _pDragSource)
		:m_pDragSource(_pDragSource)
		,m_pTransferable(NULL)
	{
	}

	//--------------------------------------------------------------------
	OLocalExchangeHelper::~OLocalExchangeHelper()
	{
		implReset();
	}

	//--------------------------------------------------------------------
	void OLocalExchangeHelper::startDrag( sal_Int8 nDragSourceActions )
	{
		DBG_ASSERT(m_pTransferable, "OLocalExchangeHelper::startDrag: not prepared!");
		m_pTransferable->startDrag( m_pDragSource, nDragSourceActions, OLocalExchange::GrantAccess() );
	}

	//--------------------------------------------------------------------
	void OLocalExchangeHelper::copyToClipboard( ) const
	{
		DBG_ASSERT( m_pTransferable, "OLocalExchangeHelper::copyToClipboard: not prepared!" );
		m_pTransferable->copyToClipboard( m_pDragSource, OLocalExchange::GrantAccess() );
	}

	//--------------------------------------------------------------------
	void OLocalExchangeHelper::implReset()
	{
		if (m_pTransferable)
		{
			m_pTransferable->setClipboardListener( Link() );
			m_pTransferable->release();
			m_pTransferable = NULL;
		}
	}

	//--------------------------------------------------------------------
	void OLocalExchangeHelper::prepareDrag( )
	{
		DBG_ASSERT(!m_pTransferable || !m_pTransferable->isDragging(), "OLocalExchangeHelper::prepareDrag: recursive DnD?");

		implReset();
		m_pTransferable = createExchange();
		m_pTransferable->acquire();
	}

//........................................................................
}
//........................................................................
