/***************************************************************************
                          arc.cpp  -  description
                             -------------------
    begin                : Tue Jul 31 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 "arc.h"

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

  zOrder = 0;
	ID = ID_arc;
  identificator = "Arc";

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

	int temp[] = { ID_geoPoint, 3, -1 };
	convertParams( temp, sizeof( temp ) / sizeof( temp[0] ) );

	surroundingRect = QRect( 0, 0, 50, 50 );
	textRect = QRect( 0, 0, 0, 0 );
}

Arc::~Arc()
{
}

void Arc::paint( QPainter *p )
{
	if ( initComplete )
	{
		p->setBrush( color );
		p->setPen( QPen( color, width, Qt::SolidLine ) );
		p->drawArc( surroundingRect, startAngle * 16, angle * 16 );
		p->setPen( QPen( color, 1, Qt::SolidLine ) );
		p->drawPolygon( arrow );
	}
}

bool Arc::contains( QPoint *pt )
{
	Coordinates coord1, coord2, coord3;

	coord1 = Coordinates( *pt );
	coord2 = parents.at( 1 )->getCoordinates();

	double dist = coord1.getDistance( coord2 );

	if ( !( ( dist < radius + width ) && ( dist > radius - width ) ) )
	{
		return false;
	}

	//	Ok, now we know that the point is in the circle, so...
  coord3 = Coordinates( coord2.getD_X() * 2, coord2.getD_Y() );

	coord1.invertY();
	coord2.invertY();
	coord3.invertY();

  double myAngle = coord2.getAngleDeg( coord3, coord1 );
  double endAngle = startAngle + angle;

	if ( endAngle >= 360 )
	{
		endAngle -= 360;
	}

	if ( startAngle < endAngle )
	{
		if ( ( myAngle > startAngle ) && ( myAngle < endAngle ) )
		{
			return true;
		}
	}

	if ( startAngle > endAngle )
	{
		if ( ( myAngle > startAngle ) || ( myAngle < endAngle ) )
		{
			return true;
		}
	}

	return false;
}

void Arc::move()
{
	Coordinates coord1, coord2, coord3, coord4, coord5, coord6, coord7, coord8;

	coord1 = parents.at( 0 )->getCoordinates();
	coord2 = parents.at( 1 )->getCoordinates();
	coord3 = parents.at( 2 )->getCoordinates();

  coord4 = coord1 - coord2;
  coord5 = coord3 - coord2;

	if ( coord4.getLength() < coord5.getLength() )
	{
		coord5.normalize( coord4.getLength() );
	}
	else
	{
		coord4.normalize( coord5.getLength() );
	}

	radius = coord5.getLength();
	radius *= 0.6;

	// Calculate arrow
	coord5.setLength( radius );
	coord6 = coord5;
	coord6.orthogonalize();
	coord6.setLength( 6 );
	coord7 = coord6;
	coord7.orthogonalize();
	coord8 = coord7;
	coord8.orthogonalize();
	coord8.orthogonalize();

	coord5 += coord2;
	coord6 += coord5;
	coord7 += coord6;
	coord8 += coord6;

  arrow.setPoints( 3, coord5.getQPoint().x(), coord5.getQPoint().y(),
                      coord8.getQPoint().x(), coord8.getQPoint().y(),
											coord7.getQPoint().x(), coord7.getQPoint().y() );

	// Calculate angles.
  coord4 = Coordinates( coord2.getD_X() * 2, coord2.getD_Y() );

	coord1.invertY();
	coord2.invertY();
	coord3.invertY();
	coord4.invertY();

	angle = coord2.getAngleDeg( coord1, coord3 );
  startAngle = coord2.getAngleDeg( coord4, coord1 );

	QPoint pt =  parents.at( 1 )->getCoordinates().getQPoint();
	surroundingRect = QRect( 0,0, radius * 2, radius * 2);
	surroundingRect.moveCenter( pt );
}

void Arc::move( QPoint *pt )
{
	textRect.moveCenter( *pt );
}

void Arc::writeToFile( KSimpleConfig *config )
{
	config->writeEntry( "Geo", ID_arc );
	config->writeEntry( "Color", getColor() );
	config->writeEntry( "Size", width );
	Coordinates coord1;
	coord1 = getCoordinates();
	MetricsCenter::mapCanvasToGrid( coord1 );
	config->writeEntry( "QPointX",  coord1.getD_X() );
	config->writeEntry( "QPointY",  coord1.getD_Y() );
}

double Arc::getAngle()
{
	return angle;
}

void Arc::readFromFile( KSimpleConfig *config )
{
	color = config->readColorEntry( "Color" );
	QString strX, strY;
	strX = config->readEntry( "QPointX" );
	strY = config->readEntry( "QPointY" );

	double x = strX.toDouble();
	double y = strY.toDouble();

	Coordinates coord1( x, y );
  MetricsCenter::mapGridToCanvas( coord1 );

	textRect = QRect( 0, 0, 50, 15 );
	textRect.moveCenter( coord1.getQPoint() );

	setSize( config->readNumEntry( "Size" ) );
	initComplete = true;
}

void Arc::getObjectOverlay( QList <QRect> & list )
{
	//	Append arc
	QRect rect( surroundingRect );

	rect.setWidth( rect.width() + ( ID_overlayRectSize ) );
	rect.setHeight( rect.height() + ( ID_overlayRectSize ) );
	rect.moveCenter( surroundingRect.center() );

	double rad = ( rect.width() / 2 );

	QRect rect1( rect.topLeft(), rect.center() );

	QRect rect2( rect );
	rect2.setLeft( rect2.left() + rad );
	rect2.setBottom( rect2.top() + rad );

	QRect rect3( rect );
	rect3.setRight( rect3.right() - rad );
	rect3.setTop( rect3.top() + rad );

	QRect rect4( rect.center(), rect.bottomRight() );

	Coordinates coord( rect.center() );

	getCircleOverlay( list, ID_overlayRectSize, rect1, coord, rad );
	getCircleOverlay( list, ID_overlayRectSize, rect2, coord, rad );
	getCircleOverlay( list, ID_overlayRectSize, rect3, coord, rad );
	getCircleOverlay( list, ID_overlayRectSize, rect4, coord, rad );

	//	Append arrow
	QRect *arrowRect = new QRect( arrow.boundingRect() );
	list.append( arrowRect );
}
