/*
 * (C) Copyright 1996-2016 ECMWF.
 * 
 * This software is licensed under the terms of the Apache Licence Version 2.0
 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
 * In applying this licence, ECMWF does not waive the privileges and immunities 
 * granted to it by virtue of its status as an intergovernmental organisation nor
 * does it submit to any jurisdiction.
 */

/*!
    \file MgQSymbol.h
    \brief Definition of MgQSymbol
    \author Graphics Section, ECMWF

    Started: Feb 2010
*/

#include "MgQSymbol.h"

#include <QDebug>
#include <QPainter>

//====================================
//
//  Item
//
//====================================

bool MgQSymbolItem::equal(const QString& id,const float size)
{
	return id == id_ && size == size_;
}

bool MgQSymbolItem::hasFilledPart()
{
	for(int i=0; i < paths_.count(); i++)
	{		
		if(paths_[i].isFilled())
		{
		  	return true;
		}
	}
	
	return false;
}

//====================================
//
//  Item set
//
//====================================

void MgQSymbolSetItem::setColor(QColor color)
{
	pen_=QPen(color);

	for(int i=0; i < symbol_->paths().count(); i++)
	{					
		if(symbol_->paths().at(i).isFilled())
		{
			if(symbol_->paths().at(i).isDefaultFill())
			{
				brushes_ << QBrush(Qt::white);
			}
			else
			{			
				brushes_ << QBrush(color);
			}
		}
		else
		{
			brushes_ << QBrush();
		}
	}
}

void MgQSymbolSetItem::setOutlineColor(QColor color)
{
	pen_=QPen(color);
	outline_=true;
} 
 
 void MgQSymbolSetItem::setConnectLinePen(QPen pen)
{
	connectLinePen_=pen;
} 
 
 
QRectF MgQSymbolSetItem::boundingRect() const
{
	//qDebug() << "PIXMAP" << QGraphicsPolylineSetItem::boundingRect();
	//qDebug() << "PIXMAP" << targetRect_;

	//return QGraphicsPolylineSetItem::boundingRect();
	//float w=boundingRectSize_;
	//return QRectF(-w/2.,-w/2.,w/2.,w/2.);
	return boundingRect_;
}

void MgQSymbolSetItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *,QWidget*)
{
	//qDebug() << "Symbol" << painter->clipRegion() << painter->clipPath() <<  painter->transform(); 

	float sx=painter->transform().m11();
	float sy=painter->transform().m22();

	bool clipping=(painter->clipRegion().isEmpty())?false:true;
	QRect clipRect=painter->clipRegion().boundingRect();

	if(keepSizeWhenScaling_)	
	{
		QTransform tr=painter->transform();
		tr.scale(1/sx,1/sy);
		painter->setTransform(tr);
	}	

	qDebug() << "Total"  << xp_.count()*symbol_->paths().count();

	//Draw lines conncting symbols
	if(connectLine_ && xp_.count() > 1 )
	{
	  	painter->setPen(connectLinePen_);	
		
		for(int j=1; j < xp_.count(); j++)
		{			  			  							
			painter->drawLine(xp_[j-1],yp_[j-1],xp_[j],yp_[j]);
		}
	}	
	
	int n=0;
	double dx,dy;
	double prevX=0., prevY=0.;
	
	painter->setPen(pen_);
	for(int j=0; j < xp_.count(); j++)
	{			  	  
	  	if(!clipping || 
	      	    clipRect.contains(xp_[j],yp_[j]))
		{		  
	  		dx=xp_[j]-prevX;
			dy=yp_[j]-prevY;
				
			if(!keepSizeWhenScaling_)	
				painter->translate(dx,dy);
			else
				painter->translate(dx*sx,dy*sy);
				
			for(int i=0; i < symbol_->paths().count(); i++)
			{		
				if(!symbol_->paths().at(i).renderOnlyForOutline()  || outline_ )
				{
					painter->setBrush(brushes_[i]);			
					painter->drawPath(symbol_->paths().at(i));
				}	
			}
			
			prevX=xp_[j];
			prevY=yp_[j];

			n++;
		}
	}	

	qDebug() << "Current"  << n;
}

void MgQSymbolSetItem::addPoint(double x, double y)
{
	xp_.push_back(x);
	yp_.push_back(y);
}

//====================================
//
//  Manager
//
//====================================

MgQSymbolManager::~MgQSymbolManager()
{	
	foreach(MgQSymbolItem *item, symbols_)
	{		
		delete item;
	}
}

MgQSymbolItem* MgQSymbolManager::getSymbol(const QString& id,const float size)
{	
	foreach(MgQSymbolItem *item, symbols_) 
	{
		if( item->equal(id,size) == true)
		{
			return item;
		}
	}
	
	return 0;		
}


MgQSymbolItem* MgQSymbolManager::addSymbol(const QString& id,const float size)
{
	MgQSymbolItem *sym = getSymbol(id,size);
	
	if(sym) 
	{
		return sym;
	}
	else
	{	
		sym=new MgQSymbolItem(id,size);
		symbols_.push_back(sym);
	}
	
	return sym;
}

void MgQSymbolManager::deleteSymbol(const QString& id,const float size)	
{	
	foreach(MgQSymbolItem *item, symbols_)
	{
		if( item->equal(id,size) == true)
		{
			delete item;
			return;
		}	
	}
}	