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

#include "dbexchange.hxx"
#include "dbtreelistbox.hxx"
#include "dbtreemodel.hxx"
#include "dbtreeview.hxx"
#include "dbu_brw.hrc"
#include "dbustrings.hrc"
#include "QEnumTypes.hxx"
#include "UITools.hxx"
#include "unodatbr.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/sdb/CommandType.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
/** === end UNO includes === **/

#include <connectivity/dbexception.hxx>
#include <connectivity/dbtools.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <svtools/treelist.hxx>
#include <svx/dataaccessdescriptor.hxx>
#include <tools/diagnose_ex.h>

#include <functional>
// .........................................................................
namespace dbaui
{
// .........................................................................

	using namespace ::com::sun::star::uno;
	using namespace ::com::sun::star::sdb;
	using namespace ::com::sun::star::sdbc;
	using namespace ::com::sun::star::sdbcx;
	using namespace ::com::sun::star::beans;
	using namespace ::com::sun::star::util;
	using namespace ::com::sun::star::frame;
	using namespace ::com::sun::star::container;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::form;
	using namespace ::com::sun::star::io;
	using namespace ::com::sun::star::i18n;
	using namespace ::com::sun::star::task;
	using namespace ::com::sun::star::datatransfer;
	using namespace ::dbtools;
	using namespace ::svx;

	// -----------------------------------------------------------------------------
	TransferableHelper* SbaTableQueryBrowser::implCopyObject( SvLBoxEntry* _pApplyTo, sal_Int32 _nCommandType, sal_Bool _bAllowConnection )
	{
		try
		{
			::rtl::OUString aName = GetEntryText( _pApplyTo );
			::rtl::OUString aDSName = getDataSourceAcessor( m_pTreeView->getListBox().GetRootLevelParent( _pApplyTo ) );

			ODataClipboard* pData = NULL;
			SharedConnection xConnection;
			if ( CommandType::QUERY != _nCommandType )
			{
				if ( _bAllowConnection && !ensureConnection( _pApplyTo, xConnection) )
					return NULL;
				pData = new ODataClipboard(aDSName, _nCommandType, aName, xConnection, getNumberFormatter(), getORB());
			}
			else
				pData = new ODataClipboard(aDSName, _nCommandType, aName, getNumberFormatter(), getORB());

			// the owner ship goes to ODataClipboards
			return pData;
		}
		catch(const SQLException& )
		{
            showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
		}
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
		return NULL;
	}
	// -----------------------------------------------------------------------------
	sal_Int8 SbaTableQueryBrowser::queryDrop( const AcceptDropEvent& _rEvt, const DataFlavorExVector& _rFlavors )
	{
        // check if we're a table or query container
		SvLBoxEntry* pHitEntry = m_pTreeView->getListBox().GetEntry( _rEvt.maPosPixel );

		if ( pHitEntry ) // no drop if no entry was hit ....
		{
			// it must be a container
			EntryType eEntryType = getEntryType( pHitEntry );
            SharedConnection xConnection;
			if ( eEntryType == etTableContainer && ensureConnection( pHitEntry, xConnection ) && xConnection.is() )
			{
                Reference<XChild> xChild(xConnection,UNO_QUERY);
                Reference<XStorable> xStore(xChild.is() ? getDataSourceOrModel(xChild->getParent()) : Reference<XInterface>(),UNO_QUERY);
				// check for the concrete type
				if ( xStore.is() && !xStore->isReadonly() && ::std::find_if(_rFlavors.begin(),_rFlavors.end(),TAppSupportedSotFunctor(E_TABLE,sal_True)) != _rFlavors.end())
					return DND_ACTION_COPY;
			}
		}

		return DND_ACTION_NONE;
	}
	// -----------------------------------------------------------------------------
	sal_Int8 SbaTableQueryBrowser::executeDrop( const ExecuteDropEvent& _rEvt )
	{
        SvLBoxEntry* pHitEntry = m_pTreeView->getListBox().GetEntry( _rEvt.maPosPixel );
		EntryType eEntryType = getEntryType( pHitEntry );
		if (!isContainer(eEntryType))
		{
			DBG_ERROR("SbaTableQueryBrowser::executeDrop: what the hell did queryDrop do?");
				// queryDrop shoud not have allowed us to reach this situation ....
			return DND_ACTION_NONE;
		}
		// a TransferableDataHelper for accessing the dropped data
	    TransferableDataHelper aDroppedData(_rEvt.maDropEvent.Transferable);


	    // reset the data of the previous async drop (if any)
	    if ( m_nAsyncDrop )
		    Application::RemoveUserEvent(m_nAsyncDrop);


	    m_nAsyncDrop = 0;
	    m_aAsyncDrop.aDroppedData.clear();
        m_aAsyncDrop.nType			= E_TABLE;
	    m_aAsyncDrop.nAction		= _rEvt.mnAction;
	    m_aAsyncDrop.bError			= sal_False;
	    m_aAsyncDrop.bHtml			= sal_False;
        m_aAsyncDrop.pDroppedAt		= NULL;
	    m_aAsyncDrop.aUrl			= ::rtl::OUString();


	    // loop through the available formats and see what we can do ...
	    // first we have to check if it is our own format, if not we have to copy the stream :-(
	    if ( ODataAccessObjectTransferable::canExtractObjectDescriptor(aDroppedData.GetDataFlavorExVector()) )
	    {
            m_aAsyncDrop.aDroppedData	= ODataAccessObjectTransferable::extractObjectDescriptor(aDroppedData);
			m_aAsyncDrop.pDroppedAt		= pHitEntry;

		    // asyncron because we some dialogs and we aren't allowed to show them while in D&D
		    m_nAsyncDrop = Application::PostUserEvent(LINK(this, SbaTableQueryBrowser, OnAsyncDrop));
		    return DND_ACTION_COPY;
	    }
	    else
	    {
            SharedConnection xDestConnection;
		    if (  ensureConnection( pHitEntry, xDestConnection )
               && xDestConnection.is()
               && m_aTableCopyHelper.copyTagTable( aDroppedData, m_aAsyncDrop, xDestConnection )
               )
            {
                m_aAsyncDrop.pDroppedAt	= pHitEntry;

			    // asyncron because we some dialogs and we aren't allowed to show them while in D&D
			    m_nAsyncDrop = Application::PostUserEvent(LINK(this, SbaTableQueryBrowser, OnAsyncDrop));
			    return DND_ACTION_COPY;
		    }
	    }

	    return DND_ACTION_NONE;
	}

	// -----------------------------------------------------------------------------
	sal_Bool SbaTableQueryBrowser::requestDrag( sal_Int8 /*_nAction*/, const Point& _rPosPixel )
	{
		// get the affected list entry
		// ensure that the entry which the user clicked at is selected
		SvLBoxEntry* pHitEntry = m_pTreeView->getListBox().GetEntry( _rPosPixel );
		if (!pHitEntry)
			// no drag of no entry was hit ....
			return sal_False;

		// it must be a query/table
		EntryType eEntryType = getEntryType( pHitEntry );
		if (!isObject(eEntryType))
			return DND_ACTION_NONE;

		TransferableHelper* pTransfer = implCopyObject( pHitEntry, ( etTableOrView == eEntryType ) ? CommandType::TABLE : CommandType::QUERY);
		Reference< XTransferable> xEnsureDelete = pTransfer;

		if (pTransfer)
			pTransfer->StartDrag( &m_pTreeView->getListBox(), DND_ACTION_COPY );

		return NULL != pTransfer;
	}
	// -----------------------------------------------------------------------------
	IMPL_LINK(SbaTableQueryBrowser, OnCopyEntry, void*, /*NOTINTERESIN*/)
	{
        SvLBoxEntry* pSelected = m_pTreeView->getListBox().FirstSelected();
		if( isEntryCopyAllowed( pSelected ) )
			copyEntry( pSelected );
		return 0;
	}
	// -----------------------------------------------------------------------------
	sal_Bool SbaTableQueryBrowser::isEntryCopyAllowed(SvLBoxEntry* _pEntry) const
	{
		EntryType eType = getEntryType(_pEntry);
		return  ( eType == etTableOrView || eType == etQuery );
	}
	// -----------------------------------------------------------------------------
	void SbaTableQueryBrowser::copyEntry(SvLBoxEntry* _pEntry)
	{
		TransferableHelper* pTransfer = NULL;
		Reference< XTransferable> aEnsureDelete;
		EntryType eType = getEntryType(_pEntry);
		pTransfer		= implCopyObject( _pEntry, eType == etQuery ? CommandType::QUERY : CommandType::TABLE);
		aEnsureDelete	= pTransfer;
		if (pTransfer)
			pTransfer->CopyToClipboard(getView());
	}
    // -----------------------------------------------------------------------------
    IMPL_LINK( SbaTableQueryBrowser, OnAsyncDrop, void*, /*NOTINTERESTEDIN*/ )
    {
	    m_nAsyncDrop = 0;
	    ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	    ::osl::MutexGuard aGuard( getMutex() );

	    if ( m_aAsyncDrop.nType == E_TABLE )
	    {
            SharedConnection xDestConnection;
		    if ( ensureConnection( m_aAsyncDrop.pDroppedAt, xDestConnection ) && xDestConnection.is() )
            {
                SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent(m_aAsyncDrop.pDroppedAt);
		        m_aTableCopyHelper.asyncCopyTagTable( m_aAsyncDrop, getDataSourceAcessor( pDataSourceEntry ), xDestConnection );
            }
	    }

	    m_aAsyncDrop.aDroppedData.clear();

	    return 0L;
    }
    // -----------------------------------------------------------------------------
	void SbaTableQueryBrowser::clearTreeModel()
	{
		if (m_pTreeModel)
		{
			// clear the user data of the tree model
			SvLBoxEntry* pEntryLoop = m_pTreeModel->First();
			while (pEntryLoop)
			{
				DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pEntryLoop->GetUserData());
				if(pData)
				{
					pEntryLoop->SetUserData(NULL);
					Reference< XContainer > xContainer(pData->xContainer, UNO_QUERY);
					if (xContainer.is())
						xContainer->removeContainerListener(this);

					if ( pData->xConnection.is() )
					{
                        DBG_ASSERT( impl_isDataSourceEntry( pEntryLoop ), "SbaTableQueryBrowser::clearTreeModel: no data source entry, but a connection?" );
                        // connections are to be stored *only* at the data source entries
                        impl_releaseConnection( pData->xConnection );
					}

					delete pData;
				}
				pEntryLoop = m_pTreeModel->Next(pEntryLoop);
			}
		}
		m_pCurrentlyDisplayed = NULL;
	}
// .........................................................................
}	// namespace dbaui
// .........................................................................

