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

// INCLUDE ---------------------------------------------------------------


#include <sot/formats.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/sdbc/XDataSource.hpp>
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#include <com/sun/star/sdb/XQueriesSupplier.hpp>
#include <com/sun/star/sdb/XDatabaseAccess.hpp>
#include <com/sun/star/sdb/CommandType.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/sdb/XCompletedConnection.hpp>
#include <com/sun/star/container/XContainerListener.hpp>
#include <com/sun/star/container/XContainer.hpp>
#include <cppuhelper/implbase1.hxx>
#include <svx/dbaexchange.hxx>

#ifndef _DBMGR_HXX
#include <dbmgr.hxx>
#endif
#include <swmodule.hxx>
#ifndef _VIEW_HXX
#include <view.hxx>
#endif
#include <wrtsh.hxx>
#include <dbtree.hxx>
#include <vos/mutex.hxx>
#include <vcl/svapp.hxx>

#ifndef _HELPID_H
#include <helpid.h>
#endif
#ifndef _UTLUI_HRC
#include <utlui.hrc>
#endif

#include <unomid.h>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::task;
using namespace ::com::sun::star::beans;

/* -----------------------------17.07.01 13:10--------------------------------

 ---------------------------------------------------------------------------*/
struct SwConnectionData
{
    ::rtl::OUString                sSourceName;
    Reference<XConnection>  xConnection;
};

typedef SwConnectionData* SwConnectionDataPtr;
SV_DECL_PTRARR_DEL( SwConnectionArr, SwConnectionDataPtr, 32, 32 )
SV_IMPL_PTRARR( SwConnectionArr, SwConnectionDataPtr )
/* -----------------------------17.07.01 13:24--------------------------------

 ---------------------------------------------------------------------------*/
class SwDBTreeList_Impl : public cppu::WeakImplHelper1 < XContainerListener >
{
    Reference< XNameAccess > xDBContext;
    SwConnectionArr aConnections;
    SwWrtShell* pWrtSh;

    public:
        SwDBTreeList_Impl(SwWrtShell* pShell) :
            pWrtSh(pShell) {}
        ~SwDBTreeList_Impl();

    virtual void SAL_CALL elementInserted( const ContainerEvent& Event ) throw (RuntimeException);
    virtual void SAL_CALL elementRemoved( const ContainerEvent& Event ) throw (RuntimeException);
    virtual void SAL_CALL elementReplaced( const ContainerEvent& Event ) throw (RuntimeException);
    virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);

    sal_Bool                        HasContext();
    SwWrtShell*                 GetWrtShell() { return pWrtSh;}
    void                        SetWrtShell(SwWrtShell& rSh) { pWrtSh = &rSh;}
    Reference< XNameAccess >    GetContext() {return xDBContext;}
    Reference<XConnection>      GetConnection(const rtl::OUString& rSourceName);
};
/* -----------------------------17.07.01 13:24--------------------------------

 ---------------------------------------------------------------------------*/
SwDBTreeList_Impl::~SwDBTreeList_Impl()
{
    Reference<XContainer> xContainer(xDBContext, UNO_QUERY);
    if(xContainer.is())
    {
        m_refCount++;
        //block necessary due to solaris' compiler behaviour to
        //remove temporaries at the block's end
        {
            xContainer->removeContainerListener( this );
        }
        m_refCount--;
    }
}
/* -----------------------------17.07.01 13:24--------------------------------

 ---------------------------------------------------------------------------*/
void SwDBTreeList_Impl::elementInserted( const ContainerEvent&  ) throw (RuntimeException)
{
    // information not needed
}
/* -----------------------------17.07.01 13:24--------------------------------

 ---------------------------------------------------------------------------*/
void SwDBTreeList_Impl::elementRemoved( const ContainerEvent& rEvent ) throw (RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    ::rtl::OUString sSource;
    rEvent.Accessor >>= sSource;
    for(sal_uInt16 i = 0; i < aConnections.Count(); i++)
    {
        SwConnectionDataPtr pPtr = aConnections[i];
        if(pPtr->sSourceName == sSource)
        {
//            SwConnectionDataPtr pPtr = aConnections[i];
//            Reference<XComponent> xComp(pPtr->xConnection, UNO_QUERY);
//            if(xComp.is())
//                xComp->dispose();
            aConnections.DeleteAndDestroy(i);
            break;
        }
    }
}
/* -----------------------------17.07.01 13:24--------------------------------

 ---------------------------------------------------------------------------*/
void SwDBTreeList_Impl::disposing( const EventObject&  ) throw (RuntimeException)
{
    xDBContext = 0;
}
/* -----------------------------17.07.01 13:24--------------------------------

 ---------------------------------------------------------------------------*/
void SwDBTreeList_Impl::elementReplaced( const ContainerEvent& rEvent ) throw (RuntimeException)
{
    elementRemoved(rEvent);
}
/* -----------------------------17.07.01 13:24--------------------------------

 ---------------------------------------------------------------------------*/
sal_Bool SwDBTreeList_Impl::HasContext()
{
    if(!xDBContext.is())
    {
        Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
        if( xMgr.is() )
        {
            Reference<XInterface> xInstance = xMgr->createInstance(
                        C2U( "com.sun.star.sdb.DatabaseContext" ));
            xDBContext = Reference<XNameAccess>(xInstance, UNO_QUERY) ;
            Reference<XContainer> xContainer(xDBContext, UNO_QUERY);
            if(xContainer.is())
                xContainer->addContainerListener( this );
        }
        DBG_ASSERT(xDBContext.is(), "com.sun.star.sdb.DataBaseContext: service not available");
    }
    return xDBContext.is();
}
/* -----------------------------17.07.01 13:24--------------------------------

 ---------------------------------------------------------------------------*/
Reference<XConnection>  SwDBTreeList_Impl::GetConnection(const rtl::OUString& rSourceName)
{
    Reference<XConnection>  xRet;
    for(sal_uInt16 i = 0; i < aConnections.Count(); i++)
    {
        SwConnectionDataPtr pPtr = aConnections[i];
        if(pPtr->sSourceName == rSourceName)
        {
            xRet = pPtr->xConnection;
            break;
        }
    }
    if(!xRet.is() && xDBContext.is() && pWrtSh)
    {
        SwConnectionDataPtr pPtr = new SwConnectionData();
        pPtr->sSourceName = rSourceName;
        xRet = pWrtSh->GetNewDBMgr()->RegisterConnection(pPtr->sSourceName);
        aConnections.Insert(pPtr, aConnections.Count());
    }
    return xRet;
}
/*------------------------------------------------------------------------
 Beschreibung:
------------------------------------------------------------------------*/
SwDBTreeList::SwDBTreeList(Window *pParent, const ResId& rResId,
                        SwWrtShell* pSh,
                        const String& rDefDBName, const sal_Bool bShowCol):

	SvTreeListBox	(pParent, rResId),
    aImageList      (SW_RES(ILIST_DB_DLG    )),
    aImageListHC    (SW_RES(ILIST_DB_DLG_HC )),
	sDefDBName		(rDefDBName),
    bInitialized    (sal_False),
	bShowColumns	(bShowCol),
    pImpl(new SwDBTreeList_Impl(pSh))
{
	SetHelpId(HID_DB_SELECTION_TLB);

	if (IsVisible())
		InitTreeList();
}

/*------------------------------------------------------------------------
 Beschreibung:
------------------------------------------------------------------------*/
SwDBTreeList::~SwDBTreeList()
{
    delete pImpl;
}

/*------------------------------------------------------------------------
 Beschreibung:
------------------------------------------------------------------------*/


void SwDBTreeList::InitTreeList()
{
    if(!pImpl->HasContext() && pImpl->GetWrtShell())
		return;
	SetSelectionMode(SINGLE_SELECTION);
	SetStyle(GetStyle()|WB_HASLINES|WB_CLIPCHILDREN|WB_SORT|WB_HASBUTTONS|WB_HASBUTTONSATROOT|WB_HSCROLL);
	// Font nicht setzen, damit der Font des Controls uebernommen wird!
	SetSpaceBetweenEntries(0);
    SetNodeBitmaps( aImageList.GetImage(IMG_COLLAPSE),
                    aImageList.GetImage(IMG_EXPAND  ), BMP_COLOR_NORMAL );
    SetNodeBitmaps( aImageListHC.GetImage(IMG_COLLAPSE),
                    aImageListHC.GetImage(IMG_EXPAND  ), BMP_COLOR_HIGHCONTRAST );

	SetDragDropMode(SV_DRAGDROP_APP_COPY);

	GetModel()->SetCompareHdl(LINK(this, SwDBTreeList, DBCompare));

    Sequence< ::rtl::OUString > aDBNames = pImpl->GetContext()->getElementNames();
    const ::rtl::OUString* pDBNames = aDBNames.getConstArray();
	long nCount = aDBNames.getLength();

    Image aImg = aImageList.GetImage(IMG_DB);
    Image aHCImg = aImageListHC.GetImage(IMG_DB);
    for(long i = 0; i < nCount; i++)
	{
		String sDBName(pDBNames[i]);
        SvLBoxEntry* pEntry = InsertEntry(sDBName, aImg, aImg, NULL, sal_True);
        SetExpandedEntryBmp(pEntry, aHCImg, BMP_COLOR_HIGHCONTRAST);
        SetCollapsedEntryBmp(pEntry, aHCImg, BMP_COLOR_HIGHCONTRAST);
	}
	String sDBName(sDefDBName.GetToken(0, DB_DELIM));
	String sTableName(sDefDBName.GetToken(1, DB_DELIM));
	String sColumnName(sDefDBName.GetToken(2, DB_DELIM));
	Select(sDBName, sTableName, sColumnName);


	bInitialized = sal_True;
}
/*-- 27.05.2004 09:19:09---------------------------------------------------

  -----------------------------------------------------------------------*/
void    SwDBTreeList::AddDataSource(const String& rSource)
{
    Image aImg = aImageList.GetImage(IMG_DB);
    Image aHCImg = aImageListHC.GetImage(IMG_DB);
    SvLBoxEntry* pEntry = InsertEntry(rSource, aImg, aImg, NULL, sal_True);
    SetExpandedEntryBmp(pEntry, aHCImg, BMP_COLOR_HIGHCONTRAST);
    SetCollapsedEntryBmp(pEntry, aHCImg, BMP_COLOR_HIGHCONTRAST);
    SvTreeListBox::Select(pEntry);
}
/*------------------------------------------------------------------------
 Beschreibung:
------------------------------------------------------------------------*/

void SwDBTreeList::ShowColumns(sal_Bool bShowCol)
{
	if (bShowCol != bShowColumns)
	{
		bShowColumns = bShowCol;
		String sTableName, sColumnName;
		String  sDBName(GetDBName(sTableName, sColumnName));

		SetUpdateMode(sal_False);

		SvLBoxEntry* pEntry = First();

		while (pEntry)
		{
			pEntry = (SvLBoxEntry*)GetRootLevelParent( pEntry );
			Collapse(pEntry);		// zuklappen

			SvLBoxEntry* pChild;
			while ((pChild = FirstChild(pEntry)) != 0L)
				GetModel()->Remove(pChild);

			pEntry = Next(pEntry);
		}

		if (sDBName.Len())
		{
			Select(sDBName, sTableName, sColumnName);	// force RequestingChilds
		}
		SetUpdateMode(sal_True);
	}
}

/*------------------------------------------------------------------------
 Beschreibung:
------------------------------------------------------------------------*/

void  SwDBTreeList::RequestingChilds(SvLBoxEntry* pParent)
{
	if (!pParent->HasChilds())
	{
		if (GetParent(pParent))	// column names
		{
            try
            {

                String sSourceName = GetEntryText(GetParent(pParent));
                String sTableName = GetEntryText(pParent);

                if(!pImpl->GetContext()->hasByName(sSourceName))
                    return;
                Reference<XConnection> xConnection = pImpl->GetConnection(sSourceName);
                sal_Bool bTable = pParent->GetUserData() == 0;
                Reference<XColumnsSupplier> xColsSupplier;
                if(bTable)
                {
                    Reference<XTablesSupplier> xTSupplier = Reference<XTablesSupplier>(xConnection, UNO_QUERY);
                    if(xTSupplier.is())
                    {
                        Reference<XNameAccess> xTbls = xTSupplier->getTables();
                        DBG_ASSERT(xTbls->hasByName(sTableName), "table not available anymore?");
                        try
                        {
                            Any aTable = xTbls->getByName(sTableName);
                            Reference<XPropertySet> xPropSet;
                            aTable >>= xPropSet;
                            xColsSupplier = Reference<XColumnsSupplier>(xPropSet, UNO_QUERY);
                        }
                        catch(Exception&)
                        {}
                    }
                }
                else
                {
                    Reference<XQueriesSupplier> xQSupplier = Reference<XQueriesSupplier>(xConnection, UNO_QUERY);
                    if(xQSupplier.is())
                    {
                        Reference<XNameAccess> xQueries = xQSupplier->getQueries();
                        DBG_ASSERT(xQueries->hasByName(sTableName), "table not available anymore?");
                        try
                        {
                            Any aQuery = xQueries->getByName(sTableName);
                            Reference<XPropertySet> xPropSet;
                            aQuery >>= xPropSet;
                            xColsSupplier = Reference<XColumnsSupplier>(xPropSet, UNO_QUERY);
                        }
                        catch(Exception&)
                        {}
                    }
                }

                if(xColsSupplier.is())
                {
                    Reference <XNameAccess> xCols = xColsSupplier->getColumns();
                    Sequence< ::rtl::OUString> aColNames = xCols->getElementNames();
                    const ::rtl::OUString* pColNames = aColNames.getConstArray();
                    long nCount = aColNames.getLength();
                    for (long i = 0; i < nCount; i++)
                    {
                        String sName = pColNames[i];
                        if(bTable)
                            InsertEntry(sName, pParent);
                        else
                            InsertEntry(sName, pParent);
                    }
                }
            }
            catch(const Exception&)
            {
            }
		}
		else	// Tabellennamen
		{
            try
            {
                String sSourceName = GetEntryText(pParent);
                if(!pImpl->GetContext()->hasByName(sSourceName))
                    return;
                Reference<XConnection> xConnection = pImpl->GetConnection(sSourceName);
                if (xConnection.is())
                {
                    Reference<XTablesSupplier> xTSupplier = Reference<XTablesSupplier>(xConnection, UNO_QUERY);
                    if(xTSupplier.is())
                    {
                        Reference<XNameAccess> xTbls = xTSupplier->getTables();
                        Sequence< ::rtl::OUString> aTblNames = xTbls->getElementNames();
                        String sTableName;
                        long nCount = aTblNames.getLength();
                        const ::rtl::OUString* pTblNames = aTblNames.getConstArray();
                        Image aImg = aImageList.GetImage(IMG_DBTABLE);
                        Image aHCImg = aImageListHC.GetImage(IMG_DBTABLE);
                        for (long i = 0; i < nCount; i++)
                        {
                            sTableName = pTblNames[i];
                            SvLBoxEntry* pTableEntry = InsertEntry(sTableName, aImg, aImg, pParent, bShowColumns);
                            //to discriminate between queries and tables the user data of table entries is set
                            pTableEntry->SetUserData((void*)0);
                            SetExpandedEntryBmp(pTableEntry, aHCImg, BMP_COLOR_HIGHCONTRAST);
                            SetCollapsedEntryBmp(pTableEntry, aHCImg, BMP_COLOR_HIGHCONTRAST);
                        }
                    }

                    Reference<XQueriesSupplier> xQSupplier = Reference<XQueriesSupplier>(xConnection, UNO_QUERY);
                    if(xQSupplier.is())
                    {
                        Reference<XNameAccess> xQueries = xQSupplier->getQueries();
                        Sequence< ::rtl::OUString> aQueryNames = xQueries->getElementNames();
                        String sQueryName;
                        long nCount = aQueryNames.getLength();
                        const ::rtl::OUString* pQueryNames = aQueryNames.getConstArray();
                        Image aImg = aImageList.GetImage(IMG_DBQUERY);
                        Image aHCImg = aImageListHC.GetImage(IMG_DBQUERY);
                        for (long i = 0; i < nCount; i++)
                        {
                            sQueryName = pQueryNames[i];
                            SvLBoxEntry* pQueryEntry = InsertEntry(sQueryName, aImg, aImg, pParent, bShowColumns);
                            pQueryEntry->SetUserData((void*)1);
                            SetExpandedEntryBmp(pQueryEntry, aHCImg, BMP_COLOR_HIGHCONTRAST);
                            SetCollapsedEntryBmp( pQueryEntry, aHCImg, BMP_COLOR_HIGHCONTRAST);
                        }
                    }
                }
            }
            catch(const Exception&)
            {
            }
        }
	}
}

/*------------------------------------------------------------------------
 Beschreibung:
------------------------------------------------------------------------*/

IMPL_LINK( SwDBTreeList, DBCompare, SvSortData*, pData )
{
	SvLBoxEntry* pRight = (SvLBoxEntry*)(pData->pRight );

	if (GetParent(pRight) && GetParent(GetParent(pRight)))
		return COMPARE_GREATER;	// Spaltennamen nicht sortieren

	return DefaultCompare(pData);	// Sonst Basisklasse rufen
}

/*------------------------------------------------------------------------
 Beschreibung:
------------------------------------------------------------------------*/

String  SwDBTreeList::GetDBName(String& rTableName, String& rColumnName, sal_Bool* pbIsTable)
{
	String sDBName;
	SvLBoxEntry* pEntry = FirstSelected();

	if (pEntry && GetParent(pEntry))
	{
		if (GetParent(GetParent(pEntry)))
		{
			rColumnName = GetEntryText(pEntry);
			pEntry = GetParent(pEntry);	// Spaltenname war selektiert
		}
		sDBName = GetEntryText(GetParent(pEntry));
		if(pbIsTable)
		{
            *pbIsTable = pEntry->GetUserData() == 0;
		}
		rTableName = GetEntryText(pEntry);
	}
	return sDBName;
}

/*------------------------------------------------------------------------
 Beschreibung:	Format: Datenbank.Tabelle
------------------------------------------------------------------------*/


void SwDBTreeList::Select(const String& rDBName, const String& rTableName, const String& rColumnName)
{
	SvLBoxEntry* pParent;
	SvLBoxEntry* pChild;
	sal_uInt16 nParent = 0;
	sal_uInt16 nChild = 0;

	while ((pParent = GetEntry(nParent++)) != NULL)
	{
		if (rDBName == GetEntryText(pParent))
		{
			if (!pParent->HasChilds())
				RequestingChilds(pParent);
			while ((pChild = GetEntry(pParent, nChild++)) != NULL)
			{
				if (rTableName == GetEntryText(pChild))
				{
					pParent = pChild;

					if (bShowColumns && rColumnName.Len())
					{
						nChild = 0;

						if (!pParent->HasChilds())
							RequestingChilds(pParent);

						while ((pChild = GetEntry(pParent, nChild++)) != NULL)
							if (rColumnName == GetEntryText(pChild))
								break;
					}
					if (!pChild)
						pChild = pParent;

					MakeVisible(pChild);
					SvTreeListBox::Select(pChild);
					return;
				}
			}
		}
	}
}

/*------------------------------------------------------------------------
 Beschreibung:
------------------------------------------------------------------------*/

void SwDBTreeList::StartDrag( sal_Int8 /*nAction*/, const Point& /*rPosPixel*/ )
{
	String sTableName, sColumnName;
	String  sDBName( GetDBName( sTableName, sColumnName ));
	if( sDBName.Len() )
	{
		TransferDataContainer* pContainer = new TransferDataContainer;
		STAR_REFERENCE( datatransfer::XTransferable ) xRef( pContainer );
		if( sColumnName.Len() )
		{
			// Datenbankfeld draggen
			svx::OColumnTransferable aColTransfer(
							sDBName
							,::rtl::OUString()
                            , sdb::CommandType::TABLE
							,sTableName
							, sColumnName
							,(CTF_FIELD_DESCRIPTOR |CTF_COLUMN_DESCRIPTOR ));
			aColTransfer.addDataToContainer( pContainer );
		}

		sDBName += '.';
		sDBName += sTableName;
		if( sColumnName.Len() )
		{
			sDBName += '.';
			sDBName += sColumnName;
		}

		pContainer->CopyString( FORMAT_STRING, sDBName );
		pContainer->StartDrag( this, DND_ACTION_COPY | DND_ACTION_LINK,
								Link() );
	}
}

/*------------------------------------------------------------------------
 Beschreibung:
------------------------------------------------------------------------*/
sal_Int8 SwDBTreeList::AcceptDrop( const AcceptDropEvent& /*rEvt*/ )
{
	return DND_ACTION_NONE;
}
/*-- 07.10.2003 13:28:22---------------------------------------------------

  -----------------------------------------------------------------------*/
void    SwDBTreeList::SetWrtShell(SwWrtShell& rSh)
{
    pImpl->SetWrtShell(rSh);
    if (IsVisible() && !bInitialized)
        InitTreeList();
}
