/***************************************************************************
                          geoline.cpp  -  description
                             -------------------
    begin                : Sat Aug 4 2001
    copyright            : (C) 2001 by Marc Bartsch
    email                : marc.bartsch@web.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "geoline.h"
#define	desk KApplication::desktop()

GeoLine::GeoLine(): GeoObjects()
{
  kapp->config()->setGroup( "Sizes" );
	width = kapp->config()->readNumEntry( "LineWidth", 1 );

//  kapp->config()->setGroup( "Colors" );
//	color = kapp->config()->readColorEntry( "Draw" );
  zOrder = 0;
	ID = ID_geoLine;
  identificator = "GeoLine";

	acceptsQPoint = false;
	acceptsGeoPoint = true;
	canBeDestroyed = false;

	startCoords.coords 	 			 = Coordinates();
	startCoords.printCoords 	 = Coordinates();
	startCoords.drawArrow  		 = false;
	startCoords.goBeyond 			 = false;

	endCoords.coords 	 			 	 = Coordinates();
	endCoords.printCoords 	 	 = Coordinates();
	endCoords.drawArrow  	 		 = false;
	endCoords.goBeyond 			 	 = false;
}

GeoLine::~GeoLine()
{
}

void GeoLine::paint( QPainter *p )
{
	if ( initComplete )
	{
		QPoint rp1 = startCoords.printCoords.getQPoint();
  	QPoint rp2 = endCoords.printCoords.getQPoint();

		if ( isChosen )
		{
			p->setPen( QPen( Qt::black, width + 2, Qt::SolidLine ) );
	    p->drawLine( rp1,rp2 );
			p->setPen( QPen( QColor( 255, 192, 0 ), width, Qt::SolidLine ) );
	    p->drawLine( rp1,rp2 );
		}
		else
		{
			p->setBrush( color );
			p->setPen( QPen( color, width, Qt::SolidLine ) );
    	p->drawLine( rp1, rp2 );
		}

		//	And draw arrows
		if ( startCoords.drawArrow )
		{
			p->setPen( QPen( color, 1, Qt::SolidLine ) );
			p->drawPolygon( startCoords.arrow );
		}

		if ( endCoords.drawArrow )
		{
			p->setPen( QPen( color, 1, Qt::SolidLine ) );
			p->drawPolygon( endCoords.arrow );
		}
	}
	else
	{
	  kapp->config()->setGroup( "Sizes" );
		width = kapp->config()->readNumEntry( "LineWidth", 1 );
	}
}

bool GeoLine::contains( QPoint *pt  )
{
	Coordinates coord1( *pt );

	return MetricsCenter::lineContainsPoint( coord1, startCoords.printCoords, endCoords.printCoords );
}

void GeoLine::move()
{
}

void GeoLine::moveMe( Coordinates & coords )
{
	MetricsCenter::mapPointToLine( coords, startCoords.printCoords, endCoords.printCoords );
}

void GeoLine::moveMe( Coordinates & coords, double position )
{
	Coordinates coord1;
	coord1 = endCoords.coords - startCoords.coords;
	coord1.setLength( coord1.getLength() * position );
	coords = startCoords.coords + coord1;
}

double GeoLine::positionMe( Coordinates & coords )
{
	moveMe( coords );
	Coordinates coord1, coord2, coord3;
	
	coord1 = endCoords.coords - startCoords.coords;
	coord2 = coords - startCoords.coords;
	coord3 = endCoords.coords - coords;
	double ret;

	if ( coord1.getLength() != 0 )
	{
		ret = coord2.getLength() / coord1.getLength();
		if ( coord1.getLength() < coord3.getLength() )
		{
			ret *= -1;
		}
	}
	else
	{
		ret = 1;
	}

	return ret;
}

void GeoLine::writeToFile( KSimpleConfig *config )
{
	config->writeEntry( "Geo", ID );
	config->writeEntry( "Color", getColor() );
	config->writeEntry( "Size", width );
}

void GeoLine::readFromFile( KSimpleConfig *config )
{
	color = config->readColorEntry( "Color" );
	width =	config->readNumEntry( "Size", 1 );
	initComplete = true;
}

void GeoLine::getObjectOverlay( QList <QRect> & list )
{
	getLineOverlay( list, ID_overlayRectSize, startCoords.printCoords, endCoords.printCoords );

	if ( startCoords.arrow )
	{
		list.append( new QRect( startCoords.arrow.boundingRect() ) );
	}

	if ( endCoords.arrow )
	{
		list.append( new QRect( endCoords.arrow.boundingRect() ) );
	}
}

void GeoLine::computeGoBeyond()
{
 	//	Compute point of conc of baseline points and the four edges
 	//	of the widget.
 	int ScreenDx = desk->width();
 	int ScreenDy = desk->height();

 	Coordinates coord1, coord2;
 	Coordinates coord3( 0, 0 );
 	Coordinates coord4( ScreenDx, 0 );
 	Coordinates coord5( 0, ScreenDy );
 	Coordinates coord6( ScreenDx, ScreenDy );

 	Coordinates coord7, coord8;
 	coord7 = startCoords.coords;
 	coord8 = endCoords.coords;

 	Coordinates coordTop, coordBottom, coordLeft, coordRight;
 	Coordinates top, bottom;

	if ( coord7.isHorizontal( coord8 ) )
	{
 		coord1 = Coordinates( 0, startCoords.coords.getD_Y() );
 		coord2 = Coordinates( ScreenDx, startCoords.coords.getD_Y() );
	}
	else if ( coord7.isVertical( coord8 ) )
	{
 		coord1 = Coordinates( startCoords.coords.getD_X(), 0 );
 		coord2 = Coordinates( startCoords.coords.getD_X(), ScreenDy );
	}
	else
	{
  	MetricsCenter::pointOfConc( coordTop, coord3, coord4, coord7, coord8 );
  	MetricsCenter::pointOfConc( coordBottom, coord5, coord6, coord7, coord8 );
  	MetricsCenter::pointOfConc( coordLeft, coord3, coord5, coord7, coord8 );
  	MetricsCenter::pointOfConc( coordRight, coord4, coord6, coord7, coord8 );

  	QRect RecX( coordTop.getQPoint(), coordBottom.getQPoint() );
  	RecX = RecX.normalize();
  	QRect RecY( coordLeft.getQPoint(), coordRight.getQPoint() );
  	RecY = RecY.normalize();
     	
  	QRect finalRect = RecX.intersect( RecY );

  	if ( coordTop.getD_X() <= coordBottom.getD_X() )
  	{
  		coord1 = Coordinates( finalRect.topLeft() );
  		coord2 = Coordinates( finalRect.bottomRight() );
  	}
  	else
  	{
  		coord1 = Coordinates( finalRect.topRight() );
  		coord2 = Coordinates( finalRect.bottomLeft() );
  	}
	}

 	if ( startCoords.goBeyond )
 	{
 		if ( coord1.getDistance( startCoords.coords ) < coord1.getDistance( endCoords.coords ) )
 		{
 			startCoords.printCoords = coord1;
 		}
 		else
 		{
 			startCoords.printCoords = coord2;
 		}
 	}

 	if ( endCoords.goBeyond )
 	{
 		if ( coord1.getDistance( endCoords.coords ) < coord1.getDistance( startCoords.coords ) )
 		{
 			endCoords.printCoords = coord1;
 		}
 		else
 		{
 			endCoords.printCoords = coord2;
 		}
 	}
}

void GeoLine::computeArrow()
{
	if ( startCoords.drawArrow )
	{
		computeArrow( endCoords, startCoords );
	}

	if ( endCoords.drawArrow )
	{
		computeArrow( startCoords, endCoords );
	}
}

void GeoLine::computeArrow( pointInfo & infoCoord1, pointInfo & infoCoord2 )
{
 	Coordinates coord1, coord2, coord3, coord4, coord5, coord6, coord7, coord8;

 	coord1 = infoCoord1.printCoords;
 	coord2 = infoCoord2.printCoords;

  coord3 = coord1 - coord2;
	coord3.setLength( 6 );
	coord4 = coord3;
	coord4.orthogonalize();
	coord4.setLength( 6 );
	coord5 = coord4;
	coord5.orthogonalize();
	coord5.orthogonalize();

 	coord6 = coord3;
	coord6.setLength( 6 + parents.at( 1 )->getSize() );

 	coord3 += coord2;
 	coord6 += coord2;
	coord4 += coord6;
	coord5 += coord6;

  infoCoord2.arrow.setPoints( 3, coord3.getQPoint().x(), coord3.getQPoint().y(),
												         coord4.getQPoint().x(), coord4.getQPoint().y(),
																 coord5.getQPoint().x(), coord5.getQPoint().y() );
}






