/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include <QPainter>
#include <QDebug>
#include <QGraphicsSceneMouseEvent>
#include <QResizeEvent>

#include "MvQOdbTableView.h"
#include "MvQOdbMetaData.h"

MvQOdbTableView::MvQOdbTableView(QWidget *parent) : QGraphicsView(parent)
{
	//Table graph
	tableOffsetX_=15;
	tableWidth_=70;
	tableGapX_=12;			
	tableOffsetY_=15;
	tableHeight_=15;
	tableGapY_=12;

	odb_=0;
	tablePixmap_=0;
}


void MvQOdbTableView::init(MvQOdbMetaData *odb,QString table)
{
	odb_=odb;
	selectedTable_=table;

	//Number of rows and cols in graph
	int nx,ny;
	odb_->getTreePosRange(nx,ny);
	nx+=1;
	//ny+=1;

	//Compute the area occupied by the graph
	int w=2*tableOffsetX_+nx*tableWidth_+(nx-1)*tableGapX_;
	int h=2*tableOffsetY_+ny*tableHeight_+(ny-1)*tableGapY_;
	
	graphWidth_=w;
	graphHeight_=h;	

	int dw,dh, pw,ph;
	//adjustPixmapSizeToView(width(),height(),dw,dh);
	adjustPixmapSizeToView(w,h,dw,dh);
	pw=w+dw;
	ph=h+dh;

	//pw=width()+dw;
	//ph=height()+dh;
	
	//Create the pixmap
	tablePixmap_ = new QPixmap(pw,ph);

	//Scene rect
	setSceneRect(0,0,pw,ph);

	//Create a scene for the table graph
	OdbTableScene *scene= new OdbTableScene;

	//Add scene to the graphics view
	setScene(scene);

	//Mouse press event in scene goes to 
	connect(scene, SIGNAL( mousePressed(int,int) ), 
		this, SLOT( mousePressedInTableGraph(int,int) ) );

	setCacheMode(QGraphicsView::CacheBackground);
	//setBackgroundBrush(*tablePixmap_);

	renderTableGraph();

	emit tableSelection(selectedTable_);
}


void MvQOdbTableView::renderTableGraph()
{
	//QPixmap *pixmap = new QPixmap(600,400);
	QPainter painter(tablePixmap_);

	painter.setRenderHint(QPainter::Antialiasing, false);
	
//QLinearGradient grad(0,0,100,100);

			QLinearGradient grad(0,0,tablePixmap_->width(),tablePixmap_->height());
     			grad.setColorAt(0, QColor::fromRgb(255,242,222));
     			grad.setColorAt(1, QColor::fromRgb(255,255,255));


	// Define clear color and clear the display 
	painter.fillRect(0,0,tablePixmap_->width(),tablePixmap_->height(),
			 QBrush(grad));
			 //QBrush(Qt::white, Qt::SolidPattern));

	//Render net
	int xp,yp;
	painter.setPen(QPen(QColor(213,209,217), 0.5, Qt::SolidLine, Qt::RoundCap));

	yp=tablePixmap_->height(); 
	while(yp> 0)
	{			
		painter.drawLine(0,yp,tablePixmap_->width(),yp);		
		yp-=15;
	}	
		
	xp=0; 
	while(xp < tablePixmap_->width())
	{
		painter.drawLine(xp,0,xp,tablePixmap_->height());	
		xp+=15;
	}	

	painter.setPen(QPen(Qt::black, 0.5, Qt::SolidLine, Qt::RoundCap));

	//Draw the graph	 		
	
	QMapIterator<QString, MvQOdbTable*> it(odb_->tables());
 	while (it.hasNext()) 
	{
     		it.next();
		getTablePos(it.value()->treePosX(),it.value()->treePosY(),xp,yp);

		foreach(QString tblName,it.value()->linksTo())
		{
			int xp1,yp1; 
			MvQOdbTable *tbl=odb_->tables()[tblName];
			getTablePos(tbl->treePosX(),tbl->treePosY(),xp1,yp1);
			
			painter.drawLine(xp,yp,(xp+xp1)/2,yp);			
			painter.drawLine((xp+xp1)/2,yp,(xp+xp1)/2,yp1);
			painter.drawLine((xp+xp1)/2,yp1,xp1,yp1);
				
		}	
	}


	painter.setFont(QFont("Helvetica [Cronyx]", 8));
	painter.setRenderHint(QPainter::TextAntialiasing, true);
	//painter.setFont(QFont("Sans Serif", 7));

	it.toFront();
	while (it.hasNext()) 
	{
     		it.next();
		getTablePos(it.value()->treePosX(),it.value()->treePosY(),xp,yp);

		if(it.value()->name() == selectedTable_)
		{										
			QLinearGradient gradient(xp,yp-tableHeight_/2.,
			                         xp,yp+tableHeight_/2);
     			gradient.setColorAt(0, QColor::fromRgb(227,59,101));
     			gradient.setColorAt(1, QColor::fromRgb(229,117,128));  

			painter.fillRect(xp-tableWidth_/2.,yp-tableHeight_/2.,
			         tableWidth_,tableHeight_,QBrush(gradient));
				//QBrush(QColor(255,64,105), Qt::SolidPattern));

		}
		else
		{
			QLinearGradient gradient(xp,yp-tableHeight_/2.,
			                         xp,yp+tableHeight_/2);
     			gradient.setColorAt(0, QColor("#6ea1f1"));
     			gradient.setColorAt(1, QColor("#567dbc"));

			painter.fillRect(xp-tableWidth_/2.,yp-tableHeight_/2.,
			         tableWidth_,tableHeight_,QBrush(gradient));
				 //QBrush(QColor(119,215,196), Qt::SolidPattern));		
		}

		painter.drawRect(xp-tableWidth_/2.,yp-tableHeight_/2.,
				 tableWidth_,tableHeight_);

		if(it.value()->name() == selectedTable_)
		{
			//painter.setPen(QPen(Qt::white, 0.5, Qt::SolidLine, Qt::RoundCap));
		}
		
		
		painter.setPen(QPen(Qt::white, 0.5, Qt::SolidLine, Qt::RoundCap));
		painter.drawText(QRectF(xp-tableWidth_/2.,yp-tableHeight_/2,
					tableWidth_,tableHeight_),
				 Qt::AlignCenter,
				 it.value()->name());
		painter.setPen(QPen(Qt::black, 0.5, Qt::SolidLine, Qt::RoundCap));
				

		if(it.value()->name() == selectedTable_) 
		{
			//painter.setPen(QPen(Qt::black, 0.5, Qt::SolidLine, Qt::RoundCap));
		}
	}

	/*graphicsView_table->setCacheMode(QGraphicsView::CacheBackground);
	graphicsView_table->resetCachedContent();*/

	setBackgroundBrush(*tablePixmap_);
}


void MvQOdbTableView::getTablePos(int row, int col, int &x, int &y)
{	
	x=tableOffsetX_+row*(tableWidth_+tableGapX_)+tableWidth_/2.;
	y=tableOffsetY_+col*(tableHeight_+tableGapY_/2.);
}


bool MvQOdbTableView::setSelectedTable(int x, int y)
{			
    	int xp,yp;
	QMapIterator<QString, MvQOdbTable*> it(odb_->tables());
 	while (it.hasNext()) 
	{
     		it.next();	
		getTablePos(it.value()->treePosX(),it.value()->treePosY(),xp,yp);

		if(x > xp-tableWidth_/2. && x< xp+tableWidth_/2. &&
		   y < yp+tableHeight_/2. && y > yp-tableHeight_/2.)
		{
			if(selectedTable_ != it.key())
			{
				selectedTable_=it.key();
				return true;
			}
		}
	}
	
	return false;			
}
void MvQOdbTableView::setSelectedTable(QString table)
{
	if(selectedTable_ != table)
	{
		selectedTable_ = table;	
		renderTableGraph();
		centreTableGraph();
	}
}

void MvQOdbTableView::mousePressedInTableGraph(int x,int y)
{
	if(setSelectedTable(x,y))
	{
			qDebug() << " Selected table: " << selectedTable_;
			renderTableGraph();
			
			emit tableSelection(selectedTable_);
	}		
}


void MvQOdbTableView::centreTableGraph()
{
	int x,y;
	MvQOdbTable* t=odb_->tables()[selectedTable_];
	getTablePos(t->treePosX(),t->treePosY(),x,y); 
	centerOn(x,y);
}


void MvQOdbTableView::resizeEvent(QResizeEvent* event)
{
	if(!tablePixmap_)
		return;

	int pw=tablePixmap_->width();
	int ph=tablePixmap_->height();

	int dw;
	int dh;	
	adjustPixmapSizeToView(pw,ph,dw,dh);

	if(dw != 0 || dh != 0)
	{	
		delete tablePixmap_;
		tablePixmap_ = new QPixmap(pw+dw,ph+dh);		

		//setBackgroundBrush(*tablePixmap_);
	
		setSceneRect(0,0,pw+dw,ph+dh);

		renderTableGraph();
	}

	QGraphicsView::resizeEvent(event);
}

void MvQOdbTableView::adjustPixmapSizeToView(int pw, int ph,int &dw,int &dh)
{
	dw=0;
	dh=0;

	int w=width();
	int h=height();

	if(pw < w) 
	{
		dw=(w-pw < 100)?100:(w-pw);
	}
	else
	{
		if(pw > graphWidth_ && w < graphWidth_)
		{
			dw=graphWidth_-pw;
		}
	}

	if(ph < h) 
	{
		dh=(h-ph < 100)?100:(h-ph);
	}
	else
	{
		if(ph > graphHeight_ && h < graphHeight_)
		{
			dh=graphHeight_-ph;
		}
	}
}



OdbTableScene::OdbTableScene(QGraphicsScene *parent) : QGraphicsScene(parent)
{

}

void OdbTableScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
	QPointF p=event->buttonDownScenePos(Qt::LeftButton);
	
	emit mousePressed(p.rx(),p.ry());
}

	