/**************************************************************
 *
 * 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_dbui.hxx"
#ifndef DBAUI_TABLEWINDOWLISTBOX_HXX
#include "TableWindowListBox.hxx"
#endif
#ifndef DBAUI_TABLEWINDOW_HXX
#include "TableWindow.hxx"
#endif
#ifndef DBAUI_QUERYDESIGNVIEW_HXX
#include "QueryDesignView.hxx"
#endif
#ifndef DBAUI_QUERYTABLEVIEW_HXX
#include "QueryTableView.hxx"
#endif
#ifndef DBAUI_QUERYCONTROLLER_HXX
#include "querycontroller.hxx"
#endif
#ifndef DBAUI_JOINEXCHANGE_HXX
#include "JoinExchange.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
#endif
#ifndef _SVX_DBEXCH_HRC
#include <svx/dbexch.hrc>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

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

OJoinExchangeData::OJoinExchangeData(OTableWindowListBox* pBox)
	: pListBox(pBox)
	, pEntry(pBox->FirstSelected())
{ }

const sal_uLong SCROLLING_TIMESPAN = 500;
const long LISTBOX_SCROLLING_AREA = 6;
//==================================================================
// class OTableWindowListBox
//==================================================================
DBG_NAME(OTableWindowListBox)
//------------------------------------------------------------------------------
OTableWindowListBox::OTableWindowListBox( OTableWindow* pParent )
    :SvTreeListBox( pParent, WB_HASBUTTONS | WB_BORDER)
	,m_aMousePos( Point(0,0) )
	,m_pTabWin( pParent )
	,m_nDropEvent(0)
	,m_nUiEvent(0)
	,m_bReallyScrolled( sal_False )
{
	DBG_CTOR(OTableWindowListBox,NULL);
	m_aScrollTimer.SetTimeout( SCROLLING_TIMESPAN );
	SetDoubleClickHdl( LINK(this, OTableWindowListBox, OnDoubleClick) );

	SetSelectionMode(SINGLE_SELECTION);

	SetHighlightRange( );
}

//------------------------------------------------------------------------------
void OTableWindowListBox::dragFinished( )
{
	// first show the error msg when existing
	m_pTabWin->getDesignView()->getController().showError(m_pTabWin->getDesignView()->getController().clearOccuredError());
	// second look for ui activities which should happen after d&d
	if (m_nUiEvent)
		Application::RemoveUserEvent(m_nUiEvent);
	m_nUiEvent = Application::PostUserEvent(LINK(this, OTableWindowListBox, LookForUiHdl));
}

//------------------------------------------------------------------------------
OTableWindowListBox::~OTableWindowListBox()
{
	DBG_DTOR(OTableWindowListBox,NULL);
	if (m_nDropEvent)
		Application::RemoveUserEvent(m_nDropEvent);
	if (m_nUiEvent)
		Application::RemoveUserEvent(m_nUiEvent);
	if( m_aScrollTimer.IsActive() )
		m_aScrollTimer.Stop();
	m_pTabWin = NULL;
}

//------------------------------------------------------------------------------
SvLBoxEntry* OTableWindowListBox::GetEntryFromText( const String& rEntryText )
{
	//////////////////////////////////////////////////////////////////////
	// Liste durchiterieren
	SvTreeList* pTreeList = GetModel();
	SvLBoxEntry* pEntry = (SvLBoxEntry*)pTreeList->First();
	OJoinDesignView* pView = m_pTabWin->getDesignView();
	OJoinController& rController = pView->getController();

	sal_Bool bCase = sal_False;
	try
	{
		Reference<XConnection> xConnection = rController.getConnection();
		if(xConnection.is())
		{
			Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
			if(xMeta.is())
				bCase = xMeta->supportsMixedCaseQuotedIdentifiers();
		}
		while( pEntry )
		{
			if((bCase ? rEntryText == GetEntryText(pEntry) : rEntryText.EqualsIgnoreCaseAscii(GetEntryText(pEntry))))
			{
				return pEntry;
			}
			pEntry = (SvLBoxEntry*)pTreeList->Next( pEntry );
		}
	}
	catch(SQLException&)
	{
	}

	return NULL;
}

//------------------------------------------------------------------------------
void OTableWindowListBox::NotifyScrolled()
{
	m_bReallyScrolled = sal_True;
}

//------------------------------------------------------------------------------
void OTableWindowListBox::NotifyEndScroll()
{
	if (m_bReallyScrolled)
		// die Verbindungen, die diese Tabelle eventuell hat, muessen neu gezeichnet werden
		m_pTabWin->getTableView()->Invalidate(INVALIDATE_NOCHILDREN);
		// ohne das INVALIDATE_NOCHILDREN wuerden auch alle Tabellen neu gezeichnet werden,
		// sprich : es flackert
	m_bReallyScrolled = sal_False;
}

//------------------------------------------------------------------------------
long OTableWindowListBox::PreNotify(NotifyEvent& rNEvt)
{
	sal_Bool bHandled = sal_False;
	switch (rNEvt.GetType())
	{
		case EVENT_KEYINPUT:
		{
			const KeyEvent* pKeyEvent =	rNEvt.GetKeyEvent();
			const KeyCode& rCode = pKeyEvent->GetKeyCode();

			if (rCode.GetCode() != KEY_RETURN)
			{
				if(m_pTabWin)
				{
					bHandled = m_pTabWin->HandleKeyInput(*pKeyEvent);
					//	bHandled = sal_True;
				}
				break;
			}

			if (rCode.IsMod1() || rCode.IsMod2() || rCode.IsShift())
				break;
			if (FirstSelected())
				static_cast<OTableWindow*>(Window::GetParent())->OnEntryDoubleClicked(FirstSelected());
		}
		break;
	}

	if (!bHandled)
		return SvTreeListBox::PreNotify(rNEvt);
	return 1L;
}

//------------------------------------------------------------------------------
IMPL_LINK( OTableWindowListBox, ScrollUpHdl, SvTreeListBox*, /*pBox*/ )
{
	SvLBoxEntry* pEntry = GetEntry( m_aMousePos );
	if( !pEntry )
		return 0;

	if( pEntry != Last() )
	{
		ScrollOutputArea( -1 );
		pEntry = GetEntry( m_aMousePos );
		Select( pEntry, sal_True );
//		m_aScrollTimer.Start();
	}

	return 0;
}

//------------------------------------------------------------------------------
IMPL_LINK( OTableWindowListBox, ScrollDownHdl, SvTreeListBox*, /*pBox*/ )
{
	SvLBoxEntry* pEntry = GetEntry( m_aMousePos );
	if( !pEntry )
		return 0;

	if( pEntry != Last() )
	{
		ScrollOutputArea( 1 );
		pEntry = GetEntry( m_aMousePos );
		Select( pEntry, sal_True );
//		m_aScrollTimer.Start();
	}

	return 0;
}

//------------------------------------------------------------------------------
void OTableWindowListBox::StartDrag( sal_Int8 /*nAction*/, const Point& /*rPosPixel*/ )
{
	OJoinTableView* pCont = m_pTabWin->getTableView();
	if (!pCont->getDesignView()->getController().isReadOnly() && pCont->getDesignView()->getController().isConnected())
	{
		// #100271# OJ asterix was not allowed to be copied to selection browsebox
		sal_Bool bFirstNotAllowed = FirstSelected() == First() && m_pTabWin->GetData()->IsShowAll();
		EndSelection();
		// create a description of the source
		OJoinExchangeData jxdSource(this);
		// put it into a exchange object
		OJoinExchObj* pJoin = new OJoinExchObj(jxdSource,bFirstNotAllowed);
		Reference< XTransferable > xEnsureDelete(pJoin);
		pJoin->StartDrag(this, DND_ACTION_LINK, this);
	}
}

//------------------------------------------------------------------------------
sal_Int8 OTableWindowListBox::AcceptDrop( const AcceptDropEvent& _rEvt )
{
	sal_Int8 nDND_Action = DND_ACTION_NONE;
	// check the format
	if ( !OJoinExchObj::isFormatAvailable(GetDataFlavorExVector(),SOT_FORMATSTR_ID_SBA_TABID) // this means that the first entry is to be draged
		&& OJoinExchObj::isFormatAvailable(GetDataFlavorExVector(),SOT_FORMATSTR_ID_SBA_JOIN) )
	{	// don't drop into the window if it's the drag source itself


		// remove the selection if the dragging operation is leaving the window
		if (_rEvt.mbLeaving)
			SelectAll(sal_False);
		else
		{
			// hit test
			m_aMousePos = _rEvt.maPosPixel;
			Size aOutputSize = GetOutputSizePixel();
			SvLBoxEntry* pEntry = GetEntry( m_aMousePos );
			if( !pEntry )
				return DND_ACTION_NONE;

			// Scrolling Areas
			Rectangle aBottomScrollArea( Point(0, aOutputSize.Height()-LISTBOX_SCROLLING_AREA),
										 Size(aOutputSize.Width(), LISTBOX_SCROLLING_AREA) );
			Rectangle aTopScrollArea( Point(0,0), Size(aOutputSize.Width(), LISTBOX_SCROLLING_AREA) );

			// Wenn Zeiger auf der oberen ScrollingArea steht, nach oben scrollen
			if( aBottomScrollArea.IsInside(m_aMousePos) )
			{
				if( !m_aScrollTimer.IsActive() )
				{
					m_aScrollTimer.SetTimeoutHdl( LINK(this, OTableWindowListBox, ScrollUpHdl) );
					ScrollUpHdl( this );
				}
			}

			// Wenn Zeiger auf der oberen ScrollingArea steht, nach unten scrollen
			else if( aTopScrollArea.IsInside(m_aMousePos) )
			{
				if( !m_aScrollTimer.IsActive() )
				{
					m_aScrollTimer.SetTimeoutHdl( LINK(this, OTableWindowListBox, ScrollDownHdl) );
					ScrollDownHdl( this );
				}
			}
			else
			{
				if( m_aScrollTimer.IsActive() )
					m_aScrollTimer.Stop();
			}

			// Beim Drag automatisch den richtigen Eintrag selektieren
			if ((FirstSelected() != pEntry) || (FirstSelected() && NextSelected(FirstSelected())))
				SelectAll(sal_False);
			Select(pEntry, sal_True);

			// Auf den ersten Eintrag (*) kann nicht gedroppt werden
			if(!( m_pTabWin->GetData()->IsShowAll() && (pEntry==First()) ))
				nDND_Action = DND_ACTION_LINK;
		}
	}
	return nDND_Action;
}
// -----------------------------------------------------------------------------

//------------------------------------------------------------------------------
IMPL_LINK( OTableWindowListBox, LookForUiHdl, void *, /*EMPTY_ARG*/)
{
	m_nUiEvent = 0;
	m_pTabWin->getTableView()->lookForUiActivities();
	return 0L;
}
//------------------------------------------------------------------------------
IMPL_LINK( OTableWindowListBox, DropHdl, void *, /*EMPTY_ARG*/)
{
	// create the connection
	m_nDropEvent = 0;
	OSL_ENSURE(m_pTabWin,"No TableWindow!");
	try
	{
		OJoinTableView* pCont = m_pTabWin->getTableView();
		OSL_ENSURE(pCont,"No QueryTableView!");
		pCont->AddConnection(m_aDropInfo.aSource, m_aDropInfo.aDest);
	}
	catch(const SQLException& e)
	{
		// remember the exception so that we can show them later when d&d is finished
		m_pTabWin->getDesignView()->getController().setErrorOccured(::dbtools::SQLExceptionInfo(e));
	}
	return 0L;
}
//------------------------------------------------------------------------------
sal_Int8 OTableWindowListBox::ExecuteDrop( const ExecuteDropEvent& _rEvt )
{
	TransferableDataHelper aDropped(_rEvt.maDropEvent.Transferable);
	if ( OJoinExchObj::isFormatAvailable(aDropped.GetDataFlavorExVector()))
	{	// don't drop into the window if it's the drag source itself
		m_aDropInfo.aSource	= OJoinExchangeData(this);
		m_aDropInfo.aDest	= OJoinExchObj::GetSourceDescription(_rEvt.maDropEvent.Transferable);

		if (m_nDropEvent)
			Application::RemoveUserEvent(m_nDropEvent);
		m_nDropEvent = Application::PostUserEvent(LINK(this, OTableWindowListBox, DropHdl));

		return DND_ACTION_LINK;
	}
	return DND_ACTION_NONE;
}

//------------------------------------------------------------------------------
void OTableWindowListBox::LoseFocus()
{
	if(m_pTabWin)
		m_pTabWin->setActive(sal_False);
	SvTreeListBox::LoseFocus();
}

//------------------------------------------------------------------------------
void OTableWindowListBox::GetFocus()
{
	if(m_pTabWin)
		m_pTabWin->setActive();

	if (GetCurEntry() != NULL)
	{
		if ( GetSelectionCount() == 0 || GetCurEntry() != FirstSelected() )
		{
			if ( FirstSelected() )
				Select(FirstSelected(), sal_False);
			Select(GetCurEntry(), sal_True);
		}
		else
			ShowFocusRect(FirstSelected());
	}
	SvTreeListBox::GetFocus();
}

//------------------------------------------------------------------------------
IMPL_LINK( OTableWindowListBox, OnDoubleClick, SvTreeListBox *, /*pBox*/ )
{
	// meinem Elter Bescheid sagen
	Window* pParent = Window::GetParent();
	DBG_ASSERT(pParent != NULL, "OTableWindowListBox::OnDoubleClick : habe kein Parent !");

	static_cast<OTableWindow*>(pParent)->OnEntryDoubleClicked(GetHdlEntry());

	return 0;
}
// -----------------------------------------------------------------------------
void OTableWindowListBox::Command(const CommandEvent& rEvt)
{
	switch (rEvt.GetCommand())
	{
		case COMMAND_CONTEXTMENU:
		{
			static_cast<OTableWindow*>(Window::GetParent())->Command(rEvt);
			break;
		}
		default:
			SvTreeListBox::Command(rEvt);
	}
}
// -----------------------------------------------------------------------------
