#include <QtGui>
#include <iostream>

#include "Plot.h"

typedef unsigned int uint;

void Plot::setDefaults(){
	
	showGrid=true;
	showLines=false;
	zoomLock=false;
	analog=true;
	gridSpace=20;
	border=10;
	XStep=1;
	YStep=1;
	xDist=0;
	
	// Colors
	gridColor = new QColor(Qt::darkCyan);
	axesColor = new QColor(Qt::green);
	lineColor = new QColor(Qt::darkGray);
	bgColor = new QColor(Qt::black);
	fgColor = new QColor(Qt::red);
	
	//Animation
	animStatus=STOPED;
	animSleepTime=50;
	animationTimer=-1000;
	animPos=0;
	
	selStarted=false;
}

Plot::Plot(QWidget *parent) : QWidget(parent){
	setDefaults();
	createUI();
	createMenus();
	connectSlots();
	clearScene();
}

Plot::Plot(QString &filename, QWidget *parent) : QWidget(parent){
	setDefaults();
	createUI();
	createMenus();
	loadSignal(filename);
	connectSlots();
}

Plot::~Plot(){

	/*
	 * Reject the dialog. If the dialog is running and the main window send close
	 * event, the dialog will hide... but the application will not terminate!!!!
	 * If the close event is sent by the Plot widget, reject is not needed...(???)
	 */
	propDlg->reject();
}

//-----Public Methods-----------------------------------------------------

// !!!! Color Changes do not redraw the scene... do it manually
void Plot::setFgColor(QColor c){*fgColor=c;}
void Plot::setBgColor(QColor c){
	*bgColor=c;
}
void Plot::setLinesColor(QColor c){*lineColor=c;}
void Plot::setGridColor(QColor c){*gridColor=c;}
void Plot::setAxesColor(QColor c){*axesColor=c;}

// Basic Items Of the Scene -> redraw or show/hide imediatelly
void Plot::setShowGrid(bool b){
	if (showGrid!=b) toggleGrid();
}

void Plot::setDrawAnalog(bool b){
	if (analog!=b) changeSignalType();
}

void Plot::setShowLines(bool b){
	if (showLines!=b) toggleLines();
}

void Plot::setSignal(Signal &sig){
	signal.clear();
	signal.push(sig);

	redrawScene();

	
	actionStartStopAnim->setEnabled(true);
	actionSave->setEnabled(true);
	actionSaveAsImage->setEnabled(true);
}

void Plot::setSignalProperties(SignalProperties &sp){
	signalProp=sp;
}

void Plot::setGridSpace(int s){gridSpace=s;}
void Plot::setBorder(int b){border=b;}
void Plot::setAnimSleepTime(int time){
	if (animStatus == RUNNING){
		killTimer(animationTimer);
		animationTimer=startTimer(time);
	}
	animSleepTime=time;
}
void Plot::setXDist(int d){xDist=d;}

QColor Plot::getFgColor() {return *fgColor;}
QColor Plot::getLinesColor() {return *lineColor;}
QColor Plot::getBgColor(){return *bgColor;}
QColor Plot::getGridColor(){return *gridColor;}
QColor Plot::getAxesColor(){return *axesColor;}
Signal & Plot::getSignal() {return signal.top();}
bool Plot::getShowGrid(){return showGrid;}
bool Plot::getDrawAnalog(){return analog;}
bool Plot::getShowLines(){return showLines;}
int Plot::getGridSpace(){return gridSpace;}
int Plot::getBorder(){return border;}
int Plot::getAnimSleepTime(){return animSleepTime;}
int Plot::getAnimStatus(){return animStatus;}
SignalProperties & Plot::getSignalProperties(){return signalProp;}
int Plot::getXDist(){return xDist;}

bool Plot::loadSignal(QString &filename){
	
	// Init Signal
	Signal tmp=Signal(filename.toStdString().c_str());
	if (tmp.size()<1) return false;
	signal.push(tmp);

	// Init Signal Properties if there is any .cfg file
	QFileInfo sigfile(filename);
	QFileInfo propfile(sigfile.absolutePath()+"/"+sigfile.baseName()+".cfg");
	
	if (propfile.exists()){
		signalProp.loadSignalProp(propfile.filePath().toStdString().c_str());
		applySignalProperties();
	}

	redrawScene();
	
	actionSave->setEnabled(true);
	actionSaveAsImage->setEnabled(true);
	actionStartStopAnim->setEnabled(true);
	actionStartStopAnim->setEnabled(true);

	propDlg->setWindowTitle("Plot Properties - "+QString(signal.top().getFileName().c_str()));
	
	return true;
}

bool Plot::isEmpty(){return signal.isEmpty();}

/*
 * Redraw occurs only when the signal 
 * or plot vars are changed
 * so re-configure everything
 */
void Plot::redrawScene(){
	clearScene();

	// Set Scene Size
	if (!signal.isEmpty()) resizeRectCalcStep();

	drawGrid();
	drawAxes();

	if (analog)
		drawAnalogSignal();
	else {
		drawDigitalSignal();
		drawLines();
	}

	
	// Add Selection Point
	if (!isEmpty() && animStatus==STOPED) {
		QPainter painter(&scene);
		painter.drawPixmap(2,scene.height()-18,16,16, QPixmap(":frame_image.png"));
		selRect=QRect(2,scene.height()-18,16,16);
	}
	
	updateScene();
	
	// update Properties
	propDlg->updateContents();

}


void Plot::startAnimation(){
	if (animStatus==RUNNING) return;
	
	// No Line Drawing on Animation
	if (!analog) {
		if (showLines) toggleLines();
		actionToggleLines->setEnabled(false);
	}
	
	animPos=0;
	
	//Draw Basics
	clearScene();
	drawGrid();
	drawAxes();
	animStatus=RUNNING;
	actionPauseAnim->setEnabled(true);
	actionStartStopAnim->setText(QApplication::translate("MainWin", "Stop", 0, QApplication::UnicodeUTF8));
	
	animationTimer=startTimer(animSleepTime);
}

void Plot::pauseAnimation(){
	if (animStatus!=RUNNING) return;

	killTimer(animationTimer);
	animStatus=PAUSED;
	actionPauseAnim->setText(QApplication::translate("MainWin", "Resume", 0, QApplication::UnicodeUTF8));
}

void Plot::stopAnimation(){
	if (animStatus==STOPED) return;
	

	if (animStatus==PAUSED)
		actionPauseAnim->setText(QApplication::translate("MainWin", "Pause", 0, QApplication::UnicodeUTF8));


	killTimer(animationTimer);
	animPos=0;
	animStatus=STOPED;
	actionPauseAnim->setEnabled(false);
	actionStartStopAnim->setText(QApplication::translate("MainWin", "Start", 0, QApplication::UnicodeUTF8));
	redrawScene();
	
	if (!analog) actionToggleLines->setEnabled(true);
}

void Plot::resumeAnimation(){
	if (animStatus!=PAUSED) return;

	animationTimer=startTimer(animSleepTime);
	animStatus=RUNNING;
	actionPauseAnim->setText(QApplication::translate("MainWin", "Pause", 0, QApplication::UnicodeUTF8));
}


//----Private Methods-----------------------------------------------------
// Drawing -----------------------
void Plot::drawLines(){
	if (!showLines) return;
	
	if (signal.isEmpty()) return;
	
	QPen linepen(*lineColor,1,Qt::DashLine);
	
	QPointF zero=signalToScene(Point(0,0));
	
	for (uint i=0; i<signal.top().size(); i++){
		QPointF current=signalToScene(signal.top()[i]);
		QLineF l;
		if (signal.top()[i].y > 0)
			l=QLineF(current.x(),current.y()+1,current.x(),zero.y()-1);
		else
			l=QLineF(current.x(),current.y()-1,current.x(),zero.y()+1);
		
		QPainter painter(&scene);
		painter.setPen(linepen);
		painter.drawLine(l);
	}
	
}

void Plot::drawGrid(){
	if (!showGrid) return;
	
	int linecount=0;
	
	QRectF srect = scene.rect();
	QPen pen(*gridColor,1);
	QPainter p(&scene);
	p.setPen(pen);
	
	QPointF zero=signalToScene(Point(0,0));
	
	int leftStart=(int)zero.x()%gridSpace;
	int topStart=(int)zero.y()%gridSpace;
	
	// VR
	for (int i=leftStart; i<(int)srect.right(); i+=gridSpace){
		QLineF l(i,srect.top(),i,srect.bottom());
		p.drawLine(l);
		linecount++;
	}

	// HR
	for (int i=topStart; i<(int)srect.bottom(); i+=gridSpace){
		QLineF l(srect.left(),i,srect.right(),i);
		p.drawLine(l);
		linecount++;
	}
		
}

void Plot::drawAxes(){
	if (isEmpty()) return;
	QRectF srect = scene.rect();
	
	QPen pen(*axesColor,1);
	QPainter p(&scene);
	p.setPen(pen);
		
	//y'y
	double minx=signal.top().getMinX();
	double miny=signal.top().getMinY();
	double maxx=signal.top().getMaxX();
	double maxy=signal.top().getMaxY();
	
	if (maxx*minx<=0) {
		QPointF zero=signalToScene(Point(0,0));
		p.drawLine((int)zero.x(),0,(int)zero.x(),(int)srect.height());
	}

	// x'x
	if (maxy*miny<=0) {
		QPointF zero=signalToScene(Point(0,0));
		p.drawLine(0,(int)zero.y(),(int)srect.width(),(int)zero.y());
	}
}

QPointF Plot::signalToScene(const Point & p){
	return QPointF(XStep*(p.x-signal.top().getMinX())+border,(signal.top().getMaxY()-p.y)*YStep+border);
}
Point Plot::sceneToSignal(const QPointF & p){
	double x=(p.x()-border)/XStep + signal.top().getMinX();
	double y=signal.top().getMaxY() - ( (p.y()-border ) / YStep );
	return Point(x,y);
}

Point Plot::sceneToSignal(const QPoint & p){
	double x=(p.x()-border)/XStep + signal.top().getMinX();
	double y=signal.top().getMaxY() - ( (p.y()-border ) / YStep );
	return Point(x,y);
}

void Plot::resizeRectCalcStep(){
	
	/* 
	OLD COUNTS 
	double len=fabs(signal.top().getMaxX()-signal.top().getMinX());
	qreal posx=signal.top().getMinX()*XStep-border;
	*/
	// Check for 0 (maxY==minY (ex. =0)) OR TOO CLOSE TO ZERO (epsilon)
	double amp=fabs(signal.top().getMaxY()-signal.top().getMinY());

	if (amp!=0) YStep=(scene.height()-2*border)/amp;
	else YStep=scene.height()/2;
	
	XStep=1/signal.top().getMinXdist();

	// Resize Scene
	qreal w=fabs(signal.top().getMaxX()-signal.top().getMinX())*XStep+2*border;
	
	qreal posy=-signal.top().getMaxY()*YStep-border;

	if (amp==0){
		posy=-signal.top().getMaxY()*YStep-DEFSCENE_H/2;
	}


	//QRectF newrect(posx,posy,w,DEFSCENE_H);
	scene=QImage((int)w,DEFSCENE_H,QImage::Format_RGB32);
	clearScene(); 	//<- set bg Color
	updateScene(); 	//<- set new Scene
	
}

void Plot::drawAnalogSignal(){

	if (signal.isEmpty()) return;

	QPointF lastPoint=signalToScene(signal.top()[0]);

	
	QPen pen(*fgColor,1);
	QPainter p (&scene);
	p.setPen(pen);
	
	uint stopPoint=animPos+1;
	if (animStatus==STOPED) stopPoint=signal.top().size();
	
	for (uint i=1; i<stopPoint; i++){

		QPointF nextPoint=signalToScene(signal.top()[i]);

		QLineF l(lastPoint,nextPoint);

		lastPoint=nextPoint;

		p.drawLine(l);
	}
}

void Plot::drawDigitalSignal(){

	if (signal.isEmpty()) return;

	
	QPen pen(*fgColor,1);
	QPainter p (&scene);
	p.setPen(pen);
	
	uint stopPoint=animPos+1;
	if (animStatus==STOPED) stopPoint=signal.top().size();
	
	for (uint i=0; i<stopPoint; i++){

		QPointF curPoint=signalToScene(signal.top()[i]);

		// Create line/point
		QLineF l(curPoint,curPoint);

		p.drawLine(l);
	}

}

void Plot::clearScene(){
	// Clear Everything
	//QImage newScene(scene.width(),scene.height(),QImage::Format_RGB32);
	QPainter p (&scene);
	p.fillRect(scene.rect(),*bgColor);
	updateScene();
	//scene=newScene;
	cout<<"CLEAR CALLED"<<endl;
}

void Plot::animateAnalog(){

	if (signal.isEmpty()) return;

	if (animPos<signal.top().size()-1){
		QPointF lastPoint=signalToScene(signal.top()[animPos]);
		QPen pen(*fgColor,1);
		QPainter p (&scene);
		p.setPen(pen);
		
	
		QPointF nextPoint=signalToScene(signal.top()[animPos+1]);
		QLineF l(lastPoint,nextPoint);
	
		p.drawLine(l);
	
		view->ensureVisible((int)nextPoint.x(),(int)nextPoint.y(),  50,  50 );
		animPos++;
	}else{
		clearScene();
		drawGrid();
		drawAxes();
		animPos=0;
	}
	updateScene();

}

void Plot::animateDigital(){

	if (signal.isEmpty()) return;

	if (animPos<signal.top().size()){
		QPen pen(*fgColor,1);
		QPainter p (&scene);
		p.setPen(pen);
	
		QPointF nextPoint=signalToScene(signal.top()[animPos+1]);
		QPointF testPoint(nextPoint);
		QLineF l(nextPoint,testPoint);
	
		p.drawLine(l);
	
		view->ensureVisible((int)nextPoint.x(),(int)nextPoint.y(),  50,  50 );
		animPos++;
	}else{
		clearScene();
		drawGrid();
		drawAxes();
		animPos=0;
	}
	updateScene();

}
// End Of Drawing-----

//Private Methods
void Plot::applySignalProperties(){
	analog=signalProp.isAnalog();
}

void Plot::connectSlots(){
	
}

void Plot::createUI(){
	
	topLayout = new QGridLayout;
	
	// View
	view=new QScrollArea;
	view->setMinimumSize(DEFSCENE_W+5,DEFSCENE_H+20);
	view->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Fixed);
	view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
	view -> setBackgroundRole(QPalette::Dark);
	
	setAcceptDrops(true);


	// Scene
	scene=QImage(DEFSCENE_W,DEFSCENE_H,QImage::Format_RGB32);
	QPainter p(&scene);
	p.fillRect(scene.rect(),*bgColor);
	
	view -> setWidget(&sceneHolder);
	view->setAlignment(Qt::AlignCenter);
	topLayout->addWidget(view);

	setLayout(topLayout);
	setMouseTracking (true);
	
	// Properties
	propDlg=new PlotProperties(this);
	
}


void Plot::createMenus(){
	// PopUp Menu
	PlotPopUp=new QMenu("Menu");
		// Actions    
	actionLoad = new QAction(this);
	actionLoad->setText(QApplication::translate("MainWin", "&Load Signal", 0, QApplication::UnicodeUTF8));
	connect(actionLoad,SIGNAL(triggered()),this,SLOT(load()));
    
	actionSave = new QAction(this);
	actionSave->setText(QApplication::translate("MainWin", "&Save Signal", 0, QApplication::UnicodeUTF8));
	actionSave->setEnabled(false);
	connect(actionSave,SIGNAL(triggered()),this,SLOT(save()));
	
	actionSaveAsImage = new QAction(this);
	actionSaveAsImage->setText(QApplication::translate("MainWin", "&Save As Image", 0, QApplication::UnicodeUTF8));
	actionSaveAsImage->setEnabled(false);
	connect(actionSaveAsImage,SIGNAL(triggered()),this,SLOT(saveAsImage()));
	
	actionToggleGrid = new QAction(this);
	actionToggleGrid->setCheckable(true);
	actionToggleGrid->setChecked(true);
	actionToggleGrid->setText(QApplication::translate("MainWin", "Show G&rid", 0, QApplication::UnicodeUTF8));
	connect(actionToggleGrid,SIGNAL(triggered()),this,SLOT(toggleGrid()) );

	actionDrawDigital = new QAction(this);
	actionDrawDigital->setText(QApplication::translate("MainWin", "Draw &Digital", 0, QApplication::UnicodeUTF8));
	connect(actionDrawDigital,SIGNAL(triggered()),this,SLOT(changeSignalType()) );
	
	actionToggleLines = new QAction(this);
	actionToggleLines->setText(QApplication::translate("MainWin", "Show L&ines", 0, QApplication::UnicodeUTF8));
	actionToggleLines->setEnabled(false);
	actionToggleLines->setCheckable(true);
	actionToggleLines->setChecked(false);
	connect(actionToggleLines,SIGNAL(triggered()),this,SLOT(toggleLines()) );
	
	actionProperties = new QAction(this);
	actionProperties->setText(QApplication::translate("MainWin", "&Properties", 0, QApplication::UnicodeUTF8));
	connect(actionProperties,SIGNAL(triggered()),this,SLOT(showPropDlg()) );
	
	actionBack=new QAction (this);
	actionBack->setText(QApplication::translate("MainWin", "&Back", 0, QApplication::UnicodeUTF8));
	//actionBack->setShortcut(tr("B"));
	actionBack->setEnabled(false);
	connect(actionBack,SIGNAL(triggered()),this,SLOT(zoomOut()));
	
	actionLockZoom= new QAction(this);
	actionLockZoom->setText(QApplication::translate("MainWin", "Lo&ck Zoom", 0, QApplication::UnicodeUTF8));
	actionLockZoom->setCheckable(true);
	actionLockZoom->setChecked(false);
	connect(actionLockZoom,SIGNAL(triggered()),this,SLOT(toggleZoomLock()));
	
	// Animation
	
	animationMenu=new QMenu("Animation");
	
	actionStartStopAnim = new QAction(this);
	actionStartStopAnim->setEnabled(false);
	actionStartStopAnim->setText(QApplication::translate("MainWin", "Start", 0, QApplication::UnicodeUTF8));
	connect(actionStartStopAnim,SIGNAL(triggered()),this,SLOT(startStopAnim()));
	
	actionPauseAnim = new QAction(this);
	actionPauseAnim->setEnabled(false);
	actionPauseAnim->setText(QApplication::translate("MainWin", "Pause", 0, QApplication::UnicodeUTF8));
	connect(actionPauseAnim,SIGNAL(triggered()),this,SLOT(pauseResumeAnim()));
	
	animationMenu->addAction(actionStartStopAnim);
	animationMenu->addAction(actionPauseAnim);

	PlotPopUp->addAction(actionLoad);
	PlotPopUp->addAction(actionSave);
	PlotPopUp->addAction(actionSaveAsImage);
	PlotPopUp->addSeparator();
	PlotPopUp->addAction(actionToggleGrid);
	PlotPopUp->addMenu(animationMenu);
	PlotPopUp->addSeparator();
	PlotPopUp->addAction(actionDrawDigital);
	PlotPopUp->addAction(actionToggleLines);
	PlotPopUp->addSeparator();
	PlotPopUp->addAction(actionBack);
	PlotPopUp->addAction(actionLockZoom);
	PlotPopUp->addSeparator();
	PlotPopUp->addAction(actionProperties);
}

void Plot::zoomIn(){
	if (zoomLock) return;
	if (signal.isEmpty()) return;
	if (animStatus!=STOPED) return;
	
	//QPointF toSceneStart=mapToScene(selStart);
	//QPointF toSceneStop=mapToScene(selStop);
	
	if (!scene.rect().contains(selStop) && !scene.rect().contains(selStart)) return;
		
	Point toSigStart=sceneToSignal(selStart);
	Point toSigStop=sceneToSignal(selStop);
		
		
	// find Bounds
	double maxX,maxY,minX,minY;
	
	if (toSigStart.x>toSigStop.x) {
		maxX=toSigStart.x;
		minX=toSigStop.x;
	}else{
		maxX=toSigStop.x;
		minX=toSigStart.x;
	}
	
	if (toSigStart.y>toSigStop.y) {
		maxY=toSigStart.y;
		minY=toSigStop.y;
	}else{
		maxY=toSigStop.y;
		minY=toSigStart.y;
	}
	
	Signal sig;
	
	//Hold if Y went out. If it get's in again ->ERROR
	bool wentOut=false;
	
	for (uint i=0; i<signal.top().size(); i++){
		// Check range
		if (signal.top()[i].x<minX) continue;
		if (signal.top()[i].x>=maxX) break;
		
		// Check amp
		if (signal.top()[i].y>maxY || signal.top()[i].y<minY){
			if (sig.size()>0) wentOut=true;
			continue;
		}
		
		//Point is in  bounds. Check if it was gone out
		if (wentOut){
			QMessageBox::critical(this,"ERROR","Amplitude (y) MUST not exceed selection area.");
			return;
		}
		
		// Accept point
		Point p=signal.top()[i];
		sig+=p;
	}
	
	// Not goot at pointing ...
	if (sig.size()<2) return;
	
	signal.push(sig);
	actionBack->setEnabled(true);
	redrawScene();
}

void Plot::updateScene(){
	QImage ns=scene;
	sceneHolder.setPixmap(QPixmap::fromImage(ns));
	sceneHolder.setFixedSize(scene.size());
	view->setWidget(&sceneHolder);
	scene=ns;
}

// Events Override

void Plot::timerEvent(QTimerEvent * event){
	if (event->timerId() == animationTimer) 
		if (analog) animateAnalog();
		else animateDigital();
}

void Plot::contextMenuEvent(QContextMenuEvent  * event){
	PlotPopUp->exec(event->globalPos());
}

void Plot::mousePressEvent(QMouseEvent *event){
	
	if (event->buttons() & Qt::LeftButton){
		// If empty no zoom neither drag n drop can be done
		if (isEmpty()) return;
		if (animStatus!=STOPED) return;
		
		if (selRect.contains(sceneHolder.mapFrom(this,event->pos())) ) {
			QDrag *drag = new QDrag(this);
			QMimeData *mimeData = new QMimeData;

			mimeData->setData("text/signal", 0 );
			drag->setMimeData(mimeData);

			drag->start();
		}else{
			selStarted=true;
			selStart=event->pos();
			selStop=event->pos();
			// Call Parent
			QWidget::mousePressEvent(event);
		}
	}

}
void Plot::mouseMoveEvent(QMouseEvent *event){
	if (event->buttons() & Qt::LeftButton){
		selStop=event->pos();
		QWidget::mouseMoveEvent(event);
	}
}

void Plot::mouseReleaseEvent(QMouseEvent *event){
	
		if (selStarted & (selStop-selStart).manhattanLength() > 3){
			zoomIn();
			QWidget::mouseReleaseEvent(event);
			selStarted=false;
		}
}

// Move is needed else it is not working..
void Plot::dragLeaveEvent(QDragLeaveEvent *){}
void Plot::dragMoveEvent(QDragMoveEvent *){}

void Plot::dragEnterEvent( QDragEnterEvent * event){
	if ((Plot *)event->source() != this && event->mimeData()->hasFormat("text/signal")){
		event->accept();
	}
	else
		event->ignore();
}

void Plot::dropEvent(QDropEvent *event){
	event->accept();
	setSignal(((Plot *)event->source())->getSignal());
	setSignalProperties(((Plot *)event->source())->getSignalProperties());
	redrawScene();
}



// Public Slots
void Plot::startStopAnim(){
	
	if (animStatus==STOPED) startAnimation();
	else stopAnimation();

	
}

void Plot::pauseResumeAnim(){
	if (animStatus==RUNNING) pauseAnimation();
	else if (animStatus==PAUSED) resumeAnimation();
}

void Plot::showPropDlg(){
	propDlg->updateContents();
	propDlg->show();
}

void Plot::zoomOut(){
	if (zoomLock) return;
	if (signal.size()>2)
		signal.pop();
	else if (signal.size()==2){
		signal.pop();
		actionBack->setEnabled(false);
	}
	redrawScene();
}
void Plot::toggleZoomLock(){	
	zoomLock=!zoomLock;
}

void Plot::toggleGrid(){
	if (showGrid){
		actionToggleGrid->setChecked(false);
	}
	else {
		actionToggleGrid->setChecked(true);
	}
	
	
	showGrid=!showGrid;
	redrawScene();
}

void Plot::toggleLines(){
	if (showLines){
		actionToggleLines->setChecked(false);
	}
	else {
		actionToggleLines->setChecked(true);
	}
	
	showLines=!showLines;
	redrawScene();
}

void Plot::changeSignalType(){
	if (analog) {
		// draw digital clicked
		actionDrawDigital->setText(tr("Draw Analog"));
		if (animStatus==STOPED) actionToggleLines->setEnabled(true);
	}else {
		// draw analog clicked
		actionDrawDigital->setText(tr("Draw Digital"));
		actionToggleLines->setEnabled(false);
	}
	
	analog=!analog;
	signalProp.setAnalog(analog);
	redrawScene();
}


void Plot::load(){
	
	//File Dialog
	QFileDialog dialog(this,tr("Load Signal From File"));
	
	// Initial Directory
	QString dir=QDir::homePath();
	
	dialog.setDirectory(dir);
	
	// File Extension Filters
	 QStringList filters;
		filters << "DAT Files (*.dat *.data)"
			<< "Sig Files (*.sig )"
			<< "Any files (*.*)";
	
	dialog.setFilters(filters);
	dialog.setFileMode(QFileDialog::ExistingFile);
	dialog.setViewMode(QFileDialog::Detail);
	dialog.setAcceptMode(QFileDialog::AcceptOpen);
	
	// Execute
	QString fileName;
	 if (dialog.exec()) 
	 	fileName = dialog.selectedFiles()[0];
	 else 
	 	return;

	loadSignal(fileName);
}
void Plot::save(){
	
	//File Dialog
	QFileDialog dialog(this,tr("Save Signal"));

	// Initial Directory
	QString dir;
	

	if (signal.top().getFileName()!=""){
		QFileInfo finfo(signal.top().getFileName().c_str());
		dir=finfo.path();
	}
	else
		dir=QDir::homePath();

	dialog.setDirectory(dir);

	dialog.setViewMode(QFileDialog::Detail);
	dialog.setAcceptMode(QFileDialog::AcceptSave);
	
	// Execute
	QString fileName;
	if (dialog.exec())
	 	fileName = dialog.selectedFiles()[0];
	else
		return;
	
	QFileInfo sigfile(fileName);
	QFileInfo propfile(sigfile.absolutePath()+"/"+sigfile.baseName()+".cfg");
	
	signal.top().save(fileName.toStdString().c_str());
	signalProp.save(propfile.filePath().toStdString().c_str());
}

void Plot::saveAsImage(){
	//File Dialog
	QFileDialog dialog(this,tr("Save Signal"));
	
	// Initial Directory
	QString dir=QDir::homePath();
	
	dialog.setDirectory(dir);

	dialog.setViewMode(QFileDialog::Detail);
	dialog.setAcceptMode(QFileDialog::AcceptSave);
	
	// Supported Image Extension Filters
	QStringList filters;
		filters << "PNG Image (*.png)";
	dialog.setFilters(filters);
	
	// Execute
	QString fileName;
	if (dialog.exec()){
		fileName = dialog.selectedFiles()[0];
		QFileInfo imginfo(fileName);
		if (imginfo.suffix()!="png")
			fileName+=".png";
 	}
	else
		return;
		
	QFile imgfile(fileName);
	if (imgfile.exists()) imgfile.remove();
	
	if (view->viewport()->rect().width()<scene.rect().width()){
		// Get only viewed Items.
		
		QImage img(view->viewport()->rect().width(),view->viewport()->rect().height(),QImage::Format_RGB32);
		QPainter painter(&img);
	
		// Background...
		painter.setBackground(QBrush(*bgColor));			// Set Color
		painter.setBackgroundMode(Qt::OpaqueMode);			// No Transparent Mode
		painter.fillRect(view->viewport()->rect(), painter.background());	// Now Draw it

	
		img.save(fileName,"PNG");
	}else{
		/* Get Only scene from the viewport (scene<viewport)
		 * DONT USE scene->render(...) it has bug and can't
		 * draw zoomed digital signals (no points on image..!?!?)
		 */
		
		QImage img((int)scene.rect().width(),(int)scene.rect().height(),QImage::Format_RGB32);
		QPainter painter(&img);
	
		// Background...
		painter.setBackground(QBrush(*bgColor));			// Set Color
		painter.setBackgroundMode(Qt::OpaqueMode);			// No Transparent Mode
		painter.fillRect(QRect(0,0,(int)scene.rect().width(),(int)scene.rect().height()), painter.background());	
		
		img.save(fileName,"PNG");
	}
	
}



