/**************************************************************
 * 
 * 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"
#ifndef DBAUI_CONNECTIONLINE_HXX
#include "ConnectionLine.hxx"
#endif
#ifndef DBAUI_CONNECTIONLINEDATA_HXX
#include "ConnectionLineData.hxx"
#endif
#ifndef DBAUI_TABLEWINDOW_HXX
#include "TableWindow.hxx"
#endif
#ifndef DBAUI_TABLEWINDOWLISTBOX_HXX
#include "TableWindowListBox.hxx"
#endif
#ifndef DBAUI_TABLECONNECTION_HXX
#include "TableConnection.hxx"
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _INC_MATH
#include <math.h>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#include <vcl/lineinfo.hxx>


using namespace dbaui;
const long DESCRIPT_LINE_WIDTH = 15;
const long HIT_SENSITIVE_RADIUS = 5;

namespace
{
	/** calcRect creates a new rectangle with the given points
			@param	_rBase		the base point
			@param	_aVector	the vector which will be added
	*/
	inline Rectangle calcRect(const Point& _rBase,const Point& _aVector)
	{
		return Rectangle( _rBase - _aVector, _rBase + _aVector );
	}
	// -----------------------------------------------------------------------------
	/** GetTextPos calculate the rectangle for the connection to be drawn
			@param	_pWin			the table window where to draw it
			@param	_aConnPos		the connection point
			@param	_aDescrLinePos	the description line pos
	*/
	Rectangle GetTextPos(const OTableWindow* _pWin, const Point& _aConnPos,const Point& _aDescrLinePos)
	{
		OTableWindowListBox* pListBox = _pWin ? _pWin->GetListBox() : NULL;
		DBG_ASSERT(_pWin && pListBox, "OConnectionLine::GetSourceTextPos : invalid call !");

		Rectangle aReturn;
		if ( pListBox )
		{
			const long nRowHeight = pListBox->GetEntryHeight();
			aReturn.Top() = _aConnPos.Y() - nRowHeight;
			aReturn.Bottom() = aReturn.Top() + nRowHeight;
			if (_aDescrLinePos.X() < _aConnPos.X())
			{
				aReturn.Left() = _aDescrLinePos.X();
				aReturn.Right() = aReturn.Left() + _aConnPos.X() - _aDescrLinePos.X();
			}
			else
			{
				aReturn.Left() = _aConnPos.X();
				aReturn.Right() = aReturn.Left() + _aDescrLinePos.X() - _aConnPos.X();
			}
		}

		return aReturn;
	}
	// -----------------------------------------------------------------------------
	/** calcPointsYValue calculate the points Y value in relation to the listbox entry
			@param	_pWin			the corresponding window
			@param	_pEntry			the source or dest entry
			@param	_rNewConPos		(in/out) the connection pos
			@param	_rNewDescrPos	(in/out) the description pos
	*/
	void calcPointsYValue(const OTableWindow* _pWin,SvLBoxEntry* _pEntry,Point& _rNewConPos,Point& _rNewDescrPos)
	{
		const OTableWindowListBox* pListBox = _pWin->GetListBox();
		_rNewConPos.Y() = _pWin->GetPosPixel().Y();
        if ( _pEntry )
        {
            const long nRowHeight = pListBox->GetEntryHeight();
		    _rNewConPos.Y() += pListBox->GetPosPixel().Y();
		    long nEntryPos = pListBox->GetEntryPosition( _pEntry ).Y();

		    if( nEntryPos >= 0 )
		    {
			    _rNewConPos.Y() += nEntryPos;
			    _rNewConPos.Y() += (long)( 0.5 * nRowHeight );
		    }
		    else
			    _rNewConPos.Y() -= (long)( 0.5 * nRowHeight );

		    long nListBoxBottom = _pWin->GetPosPixel().Y()
								    + pListBox->GetPosPixel().Y()
								    + pListBox->GetSizePixel().Height();
		    if( _rNewConPos.Y() > nListBoxBottom )
			    _rNewConPos.Y() = nListBoxBottom + 2;
        }
        else
            _rNewConPos.Y() += static_cast<sal_Int32>(pListBox->GetPosPixel().Y()*0.5);

		_rNewDescrPos.Y() = _rNewConPos.Y();
	}
	// -----------------------------------------------------------------------------
}

//========================================================================
// class OConnectionLine
//========================================================================
DBG_NAME(OConnectionLine)
//------------------------------------------------------------------------
OConnectionLine::OConnectionLine( OTableConnection* _pConn, OConnectionLineDataRef _pLineData )
	: m_pTabConn( _pConn )
	 ,m_pData( _pLineData )
{
	DBG_CTOR(OConnectionLine,NULL);
}

//------------------------------------------------------------------------
OConnectionLine::OConnectionLine( const OConnectionLine& _rLine )
{
	DBG_CTOR(OConnectionLine,NULL);
	m_pData = new OConnectionLineData( *_rLine.GetData() );
	*this = _rLine;
}

//------------------------------------------------------------------------
OConnectionLine::~OConnectionLine()
{
	DBG_DTOR(OConnectionLine,NULL);
}

//------------------------------------------------------------------------
OConnectionLine& OConnectionLine::operator=( const OConnectionLine& rLine )
{
	if( &rLine != this )
	{
		// da mir die Daten nicht gehoeren, loesche ich die alten nicht
		m_pData->CopyFrom(*rLine.GetData());
			// CopyFrom ist virtuell, damit ist es kein Problem, wenn m_pData von einem von OTableConnectionData abgeleiteten Typ ist

		m_pTabConn = rLine.m_pTabConn;
		m_aSourceConnPos = rLine.m_aSourceConnPos;
		m_aDestConnPos = rLine.m_aDestConnPos;
		m_aSourceDescrLinePos = rLine.m_aSourceDescrLinePos;
		m_aDestDescrLinePos = rLine.m_aDestDescrLinePos;
	}

	return *this;
}

//------------------------------------------------------------------------
Rectangle OConnectionLine::GetBoundingRect()
{
	//////////////////////////////////////////////////////////////////////
	// Umgebendes Rechteck bestimmen
	Rectangle aBoundingRect( Point(0,0), Point(0,0) );
	if( !IsValid() )
		return aBoundingRect;

	Point aTopLeft;
	Point aBottomRight;

	if( m_aSourceDescrLinePos.Y() <= m_aDestDescrLinePos.Y() )
	{
		aTopLeft.Y() = m_aSourceDescrLinePos.Y();
		aBottomRight.Y() = m_aDestDescrLinePos.Y();
	}
	else
	{
		aTopLeft.Y() = m_aDestDescrLinePos.Y();
		aBottomRight.Y() = m_aSourceDescrLinePos.Y();
	}

	if( m_aSourceDescrLinePos.X() <= m_aDestDescrLinePos.X() )
	{
		aTopLeft.X() = m_aSourceDescrLinePos.X();
		aBottomRight.X() = m_aDestDescrLinePos.X();
	}
	else
	{
		aTopLeft.X() = m_aDestDescrLinePos.X();
		aBottomRight.X() = m_aSourceDescrLinePos.X();
	}

    const OTableWindow* pSourceWin = m_pTabConn->GetSourceWin();
	const OTableWindow* pDestWin = m_pTabConn->GetDestWin();
	//////////////////////////////////////////////////////////////////////
	// Linie verlaeuft in z-Form
	if( pSourceWin == pDestWin || Abs(m_aSourceConnPos.X() - m_aDestConnPos.X()) > Abs(m_aSourceDescrLinePos.X() - m_aDestDescrLinePos.X()) )
	{
		aTopLeft.X() -= DESCRIPT_LINE_WIDTH;
		aBottomRight.X() += DESCRIPT_LINE_WIDTH;
	}

	aBoundingRect = Rectangle( aTopLeft-Point(2,17), aBottomRight+Point(2,2) );

	return aBoundingRect;
}
// -----------------------------------------------------------------------------
void calcPointX1(const OTableWindow* _pWin,Point& _rNewConPos,Point& _rNewDescrPos)
{
	_rNewConPos.X() = _pWin->GetPosPixel().X() + _pWin->GetSizePixel().Width();
	_rNewDescrPos.X() = _rNewConPos.X();
	_rNewConPos.X() += DESCRIPT_LINE_WIDTH;
}
// -----------------------------------------------------------------------------
void calcPointX2(const OTableWindow* _pWin,Point& _rNewConPos,Point& _rNewDescrPos)
{
	_rNewConPos.X() = _pWin->GetPosPixel().X();
	_rNewDescrPos.X() = _rNewConPos.X();
	_rNewConPos.X() -= DESCRIPT_LINE_WIDTH;
}
//------------------------------------------------------------------------
sal_Bool OConnectionLine::RecalcLine()
{
	//////////////////////////////////////////////////////////////////////
	// Fenster und Entries muessen gesetzt sein
	const OTableWindow* pSourceWin = m_pTabConn->GetSourceWin();
	const OTableWindow* pDestWin = m_pTabConn->GetDestWin();

	if( !pSourceWin || !pDestWin )
		return sal_False;

	SvLBoxEntry* pSourceEntry = pSourceWin->GetListBox()->GetEntryFromText( GetData()->GetSourceFieldName() );
	SvLBoxEntry* pDestEntry = pDestWin->GetListBox()->GetEntryFromText( GetData()->GetDestFieldName() );

	//////////////////////////////////////////////////////////////////////
	// X-Koordinaten bestimmen
	Point aSourceCenter( 0, 0 );
	Point aDestCenter( 0, 0 );

	aSourceCenter.X() = pSourceWin->GetPosPixel().X() + (long)( 0.5*pSourceWin->GetSizePixel().Width() );
	aDestCenter.X() = pDestWin->GetPosPixel().X() + (long)( 0.5*pDestWin->GetSizePixel().Width() );

	const OTableWindow* pFirstWin	= pDestWin;
	const OTableWindow* pSecondWin	= pSourceWin;
	Point* pFirstConPos				= &m_aDestConnPos;
	Point* pFirstDescrPos			= &m_aDestDescrLinePos;
	Point* pSecondConPos			= &m_aSourceConnPos;
	Point* pSecondDescrPos			= &m_aSourceDescrLinePos;
	if( aDestCenter.X() > aSourceCenter.X() )
	{
		pFirstWin		= pSourceWin;
		pSecondWin		= pDestWin;
		pFirstConPos	= &m_aSourceConnPos;
		pFirstDescrPos	= &m_aSourceDescrLinePos;
		pSecondConPos	= &m_aDestConnPos;
		pSecondDescrPos	= &m_aDestDescrLinePos;
	}

    if ( pFirstWin == pSecondWin && pSourceEntry != pDestEntry )
        calcPointX2(pFirstWin,*pFirstConPos,*pFirstDescrPos);
    else
        calcPointX1(pFirstWin,*pFirstConPos,*pFirstDescrPos);
	calcPointX2(pSecondWin,*pSecondConPos,*pSecondDescrPos);

	//////////////////////////////////////////////////////////////////////
	// aSourceConnPosY bestimmen
    calcPointsYValue(pSourceWin,pSourceEntry,m_aSourceConnPos,m_aSourceDescrLinePos);
	
	//////////////////////////////////////////////////////////////////////
	// aDestConnPosY bestimmen
    calcPointsYValue(pDestWin,pDestEntry,m_aDestConnPos,m_aDestDescrLinePos);

	return sal_True;
}
// -----------------------------------------------------------------------------

//------------------------------------------------------------------------
void OConnectionLine::Draw( OutputDevice* pOutDev )
{
	const sal_uInt16 nRectSize = 3;

	//////////////////////////////////////////////////////////////////////
	// Neue Dimensionen berechnen
	if( !RecalcLine() )
		return;

	//////////////////////////////////////////////////////////////////////
	// Zeichnen der Linien
	if (m_pTabConn->IsSelected())
		pOutDev->SetLineColor(Application::GetSettings().GetStyleSettings().GetHighlightColor());
	else
		pOutDev->SetLineColor(Application::GetSettings().GetStyleSettings().GetWindowTextColor());

    LineInfo aLineInfo;
    if ( m_pTabConn->IsSelected() )
        aLineInfo.SetWidth(3);
    Polygon aPoly;
    aPoly.Insert(0,m_aSourceDescrLinePos);
    aPoly.Insert(1,m_aSourceConnPos);
    aPoly.Insert(2,m_aDestConnPos);
    aPoly.Insert(3,m_aDestDescrLinePos);
    pOutDev->DrawPolyLine(aPoly,aLineInfo);

	//////////////////////////////////////////////////////////////////////
	// draw the connection rectangles
	pOutDev->SetFillColor(Application::GetSettings().GetStyleSettings().GetWindowColor());

	Point aVector(nRectSize,nRectSize);
	pOutDev->DrawRect( calcRect(m_aSourceDescrLinePos,aVector) );
	pOutDev->DrawRect( calcRect( m_aDestDescrLinePos,aVector) );
}
// -----------------------------------------------------------------------------
sal_Bool OConnectionLine::IsValid() const
{
	return m_pData.isValid();
}
//------------------------------------------------------------------------
double dist_Euklid(const Point &p1, const Point& p2,const Point& pM, Point& q)
{
	Point v(p2 - p1);
	Point w(pM - p1);
	double a = sqrt((double)(v.X()*v.X() + v.Y()*v.Y()));
	double l = (v.X() * w.Y() - v.Y() * w.X()) / a;
	double a2 = w.X()*v.X()+w.Y()*v.Y();
	a = a2 / (a * a);
	q.X() = long(p1.X() + a * v.X()); 
	q.Y() = long(p1.Y() + a * v.Y());
	return l;
}
//------------------------------------------------------------------------
bool OConnectionLine::CheckHit( const Point& rMousePos ) const
{
	//////////////////////////////////////////////////////////////////////
	/*
		Vorgehensweise beim HitTest:
		Es wird der Abstand nach Euklid berechnet.
	*/
	Point q;
	double l = fabs(dist_Euklid(m_aSourceConnPos,m_aDestConnPos,rMousePos,q));
	if( l < HIT_SENSITIVE_RADIUS)
	{
		if(::std::min(m_aSourceConnPos.X(),m_aDestConnPos.X()) <= q.X() && ::std::min(m_aSourceConnPos.Y(),m_aDestConnPos.Y()) <= q.Y()
			&& q.X() <= ::std::max(m_aDestConnPos.X(),m_aSourceConnPos.X())   && q.Y() <= ::std::max(m_aDestConnPos.Y(),m_aSourceConnPos.Y()))
			return true;
	}

	return false;
}
// -----------------------------------------------------------------------------
Rectangle OConnectionLine::GetSourceTextPos() const 
{ 
	return GetTextPos(m_pTabConn->GetSourceWin(),m_aSourceConnPos,m_aSourceDescrLinePos); 
}
// -----------------------------------------------------------------------------
Rectangle OConnectionLine::GetDestTextPos() const 
{ 
	return GetTextPos(m_pTabConn->GetDestWin(),m_aDestConnPos,m_aDestDescrLinePos); 
}
// -----------------------------------------------------------------------------
Point OConnectionLine::getMidPoint() const
{
	Point aDest = m_aDestConnPos - m_aSourceConnPos;
	aDest.X() /= 2;
	aDest.Y() /= 2;

	return m_aSourceConnPos + aDest;
}
// -----------------------------------------------------------------------------


