/**************************************************************
 * 
 * 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_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;
}
// -----------------------------------------------------------------------------


