#include "PlotProperties.h"
#include <iostream>

PlotProperties::PlotProperties (QWidget *parent,Qt::WindowFlags f) : QDialog(parent,f){
	// cast and get Plot who called the dialog
	plot =  ((Plot*)parent);
	createUI();
}

PlotProperties::~PlotProperties(){}

//Private Methods

void PlotProperties::createUI(){
	//
	QVBoxLayout * topLayout =  new QVBoxLayout;
	
	tabs = new QTabWidget(this);
	connect(tabs,SIGNAL(currentChanged(int)),this,SLOT(manageApply()));
	
	// Make buttons
	buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
					| QDialogButtonBox::Apply
					| QDialogButtonBox::Cancel);
	buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
	connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
	connect(buttonBox, SIGNAL(accepted()), this, SLOT(okClicked()));
	connect(buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()),this,SLOT(applyClicked()) );
	

	// Add Tabs
	statsTb = new StatsTab(this);
	if (!plot->isEmpty()) statsTb->updateForSignal(plot->getSignal());
	tabs->addTab(statsTb,"Statistics");
	
	editTb = new EditTab(this);
	tabs->addTab(editTb,"Edit Signal");
	if (plot->isEmpty()){ 
		editTb->setEnabled(false);
		editTb->updateSignalProperties(plot->getSignalProperties());
	}
	connect(editTb,SIGNAL(modified()),this,SLOT(manageApply()));
	
	setTb=new SettingsTab(this);
	tabs->addTab(setTb,"Settings");
	setTb->updateSettings(plot);
	connect(setTb,SIGNAL(modified()),this,SLOT(manageApply()));
	connect(setTb,SIGNAL(speedChanged(int)),this,SLOT(changeAnimSpeed(int)));
	
	topLayout->addWidget(tabs);
	topLayout->addWidget(buttonBox);

	setLayout(topLayout);
	setWindowTitle("Plot Properties");
}

void PlotProperties::updateContents(){
	plot =  ((Plot*)parent());
	if (!plot->isEmpty()) {
		// Need Signal
		statsTb->updateForSignal(plot->getSignal());
		editTb->setEnabled(true);
		editTb->updateSignalProperties(plot->getSignalProperties());
	}
	
	setTb->updateSettings(plot);
}

void PlotProperties::changeAnimSpeed(int value){
	plot->setAnimSleepTime(value);
}

void PlotProperties::manageApply(){
	
	if (tabs->currentWidget()!=0 && ((PlotPropTab *)tabs->currentWidget())->isModified())
		buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true);
	else
		buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
}

void PlotProperties::applyClicked(){
	((PlotPropTab *)tabs->currentWidget())->applyChanges(plot);
}

void PlotProperties::okClicked(){
	if (tabs->currentWidget()!=0 && ((PlotPropTab *)tabs->currentWidget())->isModified())
		((PlotPropTab *)tabs->currentWidget())->applyChanges(plot);
	accept();
}


//:-)End of PlotProperties-------------------------------------------------------------------


SettingsTab::SettingsTab(QWidget * parent) : PlotPropTab(parent){

	// TOP
	QGridLayout * topLayout = new QGridLayout;
	
	   // Metrics
	QGridLayout * metricsLayout = new QGridLayout;
	QGroupBox * metricsBox = new QGroupBox("Metrics");
	gridSpace=new QLineEdit(this);
	gridSpace->setMaxLength (2);
	gridSpace->setMaximumWidth (40);
	gridSpace->setAlignment(Qt::AlignRight);
	gridSpace->setValidator(new QIntValidator(2,100,gridSpace));
	connect(gridSpace,SIGNAL(textChanged(const QString &)),this,SLOT(setModified()));
	
	border=new QLineEdit(this);
	border->setAlignment(Qt::AlignRight);
	border->setMaximumWidth (40);
	border->setMaxLength (2);
	border->setValidator(new QIntValidator(0,50,border));
	connect(border,SIGNAL(textChanged(const QString &)),this,SLOT(setModified()));

	animSpeed = new QSlider(Qt::Horizontal,this);
	animSpeed->setMinimum(10);
	animSpeed->setMaximum(200);
	connect(animSpeed, SIGNAL(sliderMoved(int)), this, SLOT(animSpeedChanged(int)));
	
	metricsLayout->addWidget(new QLabel("Grid Space "),0,0);
	metricsLayout->addWidget(gridSpace,0,1);
	metricsLayout->addWidget(new QLabel("Border "),1,0);
	metricsLayout->addWidget(border,1,1);
	metricsLayout->addWidget(new QLabel("Animation Speed"),2,0);
	metricsLayout->addWidget(animSpeed,2,1);
	
	metricsBox->setLayout(metricsLayout);
	
	   // Colors
	QGridLayout * colorsLayout = new QGridLayout;
	QGroupBox * colorsBox = new QGroupBox("Colors");
	QButtonGroup *colorGroup = new QButtonGroup(this);
	
	signalColor = new QPushButton(this);
	signalColor->setMaximumSize(40,15);
	signalColor->setAutoFillBackground(true);
	
	bgColor = new QPushButton(this);
	bgColor->setMaximumSize(40,15);
	bgColor->setAutoFillBackground(true);
	
	axesColor = new QPushButton(this);
	axesColor->setMaximumSize(40,15);
	axesColor->setAutoFillBackground(true);

	gridColor = new QPushButton(this);
	gridColor->setMaximumSize(40,15);
	gridColor->setAutoFillBackground(true);

	linesColor = new QPushButton(this);
	linesColor->setMaximumSize(40,15);
	linesColor->setAutoFillBackground(true);

	colorGroup->addButton(signalColor);
	colorGroup->addButton(bgColor);
	colorGroup->addButton(axesColor);
	colorGroup->addButton(gridColor);
	colorGroup->addButton(linesColor);
	connect(colorGroup,SIGNAL(buttonClicked(QAbstractButton *)),this,SLOT(choseColor(QAbstractButton *)));
	
	// Set Default Button Color
	defButColor=new QColor(linesColor->palette().color(linesColor->backgroundRole()));

	colorsLayout->addWidget(new QLabel("Signal Color"),0,0);
	colorsLayout->addWidget(signalColor,0,1);
	colorsLayout->addWidget(new QLabel("Background Color"),1,0);
	colorsLayout->addWidget(bgColor,1,1);
	colorsLayout->addWidget(new QLabel("Axes Color"),2,0);
	colorsLayout->addWidget(axesColor,2,1);
	colorsLayout->addWidget(new QLabel("  Grid Color"),0,2);
	colorsLayout->addWidget(gridColor,0,3);
	colorsLayout->addWidget(new QLabel("  Lines Color"),1,2);
	colorsLayout->addWidget(linesColor,1,3);

	colorsBox->setLayout(colorsLayout);
	//
	topLayout->addWidget(metricsBox,0,0);

	topLayout->addWidget(colorsBox,1,0);
	setLayout(topLayout);
}
void SettingsTab::chColor(QPushButton *but,QColor c){
	QPalette palette;
	palette.setColor(but->backgroundRole(),c);
	but->setPalette(palette);
}

QColor SettingsTab::getButColor(QPushButton * but){
	return but->palette().color(but->backgroundRole());
}

void SettingsTab::updateSettings(Plot *plot){
	gridSpace->setText(QString::number(plot->getGridSpace()));
	border->setText(QString::number(plot->getBorder()));

	chColor(signalColor,plot->getFgColor());
	chColor(bgColor,plot->getBgColor());
	chColor(axesColor,plot->getAxesColor());
	chColor(gridColor,plot->getGridColor());
	chColor(linesColor,plot->getLinesColor());
	
	animSpeed->setValue(200+10-plot->getAnimSleepTime());
	
	// Set mod to false ... plot 'n' settings say the same thing
	mod=false;
	emit modified();
}

void SettingsTab::choseColor(QAbstractButton *but){
	QColor selCol=QColorDialog::getColor(but->palette().color(but->backgroundRole()));
	if (!selCol.isValid()) return;
	chColor((QPushButton*)but,selCol);
	setModified();
}

void SettingsTab::setModified(){
	mod=true;
	emit modified();
}

void SettingsTab::applyChanges(Plot * plot){
	plot->setGridSpace(gridSpace->text().toInt());
	plot->setBorder(border->text().toInt());
	//plot->setXDist(xDist->text().toInt());
	plot->setFgColor(getButColor(signalColor));
	plot->setBgColor(getButColor(bgColor));
	plot->setAxesColor(getButColor(axesColor));
	plot->setGridColor(getButColor(gridColor));
	plot->setLinesColor(getButColor(linesColor));
	
	plot->redrawScene();
	mod=false;
	emit modified();

}

void SettingsTab::animSpeedChanged(int value){
	emit speedChanged(200+10-value);
}

SettingsTab::~SettingsTab(){}

//:-) End of SettingsTab---------------------------------------------------------------------

EditTab::EditTab(QWidget * parent) : PlotPropTab(parent){
	mod=false;
	// Top
	QVBoxLayout * topLayout =new QVBoxLayout;
	
	   // Move
	QGroupBox * moveBox =new QGroupBox("Move Signal");
	QGridLayout * moveLayout = new QGridLayout;

	currentPos = new QLabel("");

	horMove = new QLineEdit(this);
	horMove->setMaximumWidth (60);
	horMove->setAlignment(Qt::AlignRight);
	horMove->setMaxLength (7);
	horMove->setValidator(new QDoubleValidator(horMove));
	connect(horMove,SIGNAL(textChanged(const QString &)),this,SLOT(setModified()));
	
	
	verMove = new QLineEdit(this);
	verMove->setMaximumWidth (60);
	verMove->setAlignment(Qt::AlignRight);
	verMove->setValidator(new QDoubleValidator(verMove));
	verMove->setMaxLength (7);
	connect(verMove,SIGNAL(textChanged(const QString &)),this,SLOT(setModified()));

	moveLayout->addWidget(new QLabel("Current Position:  "),0,0);
	moveLayout->addWidget(currentPos,0,1);
	moveLayout->addWidget(new QLabel("Horizontally per "),1,0);
	moveLayout->addWidget(horMove,1,1);
	moveLayout->addWidget(new QLabel("Vertically per "),2,0);
	moveLayout->addWidget(verMove,2,1);
	moveBox->setLayout(moveLayout);
	
	   // Noise
	QGroupBox * noiseBox =new QGroupBox("Add Noise");
	QGridLayout * noiseLayout = new QGridLayout;
	
	currentNoise = new QLabel("");
	
	percent = new QLineEdit(this);
	percent->setAlignment(Qt::AlignRight);
	percent->setValidator(new QDoubleValidator(0.0,100.0,2,percent));
	percent->setMaximumWidth (40);
	percent->setMaxLength (5);
	connect(percent,SIGNAL(textChanged(const QString &)),this,SLOT(setModified()));
	
	noiseLayout->addWidget(new QLabel("Current Noise: "),0,0);
	noiseLayout->addWidget(currentNoise,0,1);
	noiseLayout->addWidget(new QLabel("Maximum Noise: "),1,0);
	noiseLayout->addWidget(percent,1,1);
	noiseLayout->addWidget(new QLabel("% * Max Amp"),1,2);
	
	noiseBox->setLayout(noiseLayout);
	
	//
	topLayout->addWidget(moveBox);
	topLayout->addWidget(noiseBox);
	setLayout(topLayout);

}

void EditTab::setModified(){
	if (verMove->text() !="") mod=true;
	else if (horMove->text() != "") mod = true;
	else if (percent->text() != "") mod =true;
	else mod = false;
	emit modified();
}

void EditTab::applyChanges(Plot * plot){
	
	if (horMove->text() != "") {
		plot->getSignal().moveHor(horMove->text().toDouble());
		plot->getSignalProperties().setXMove(plot->getSignalProperties().getXMove()+horMove->text().toDouble());
		horMove->setText("");
	}
	
	if (verMove->text() != "") {
		plot->getSignal().moveVer(verMove->text().toDouble());
		plot->getSignalProperties().setYMove(plot->getSignalProperties().getYMove()+verMove->text().toDouble());
		verMove->setText("");
	}
	
	if (percent->text() != ""){
		plot->getSignal().addNoise(percent->text().toDouble());
		plot->getSignalProperties().setNoise(plot->getSignalProperties().getNoise()+percent->text().toDouble());
		percent->setText("");
	}

	plot->redrawScene();
	
	mod=false;
	emit modified();
}

void EditTab::updateSignalProperties(SignalProperties &prop){
	currentPos->setText(" x: "+QString::number(prop.getXMove())+",  y: "+QString::number(prop.getYMove()));
	currentNoise->setText(QString::number(prop.getNoise())+"%");
}

EditTab::~EditTab(){}
//:-)End of EditTab -------------------------------------------------------------------------

StatsTab::StatsTab(QWidget * parent) : PlotPropTab(parent){
	
	QGridLayout * statsLayout=new QGridLayout;
	mean=new QLabel(this);
	variance=new QLabel(this);
	stdDeviation=new QLabel(this);
	avgDeviation=new QLabel(this);
	skewness=new QLabel(this);
	kurtosis=new QLabel(this);
	maxY=new QLabel(this);
	maxX=new QLabel(this);
	minY=new QLabel(this);
	minX=new QLabel(this);
	
	statsLayout->addWidget(new QLabel("Mean: "),0,0);
	statsLayout->addWidget(mean,0,1);
	statsLayout->addWidget(new QLabel("Variance: "),0,2);
	statsLayout->addWidget(variance,0,3);
	statsLayout->addWidget(new QLabel("Std Deviation: "),1,0);
	statsLayout->addWidget(stdDeviation,1,1);
	statsLayout->addWidget(new QLabel("Avg Deviation: "),1,2);
	statsLayout->addWidget(avgDeviation,1,3);
	statsLayout->addWidget(new QLabel("Skewness: "),2,0);
	statsLayout->addWidget(skewness,2,1);
	statsLayout->addWidget(new QLabel("Kurtosis: "),2,2);
	statsLayout->addWidget(kurtosis,2,3);
	
	statsLayout->addWidget(new QLabel("Min X: "),3,0);
	statsLayout->addWidget(minX,3,1);
	statsLayout->addWidget(new QLabel("Max X: "),3,2);
	statsLayout->addWidget(maxX,3,3);
	statsLayout->addWidget(new QLabel("Min Y: "),4,0);
	statsLayout->addWidget(minY,4,1);
	statsLayout->addWidget(new QLabel("Max Y: "),4,2);
	statsLayout->addWidget(maxY,4,3);

	setLayout(statsLayout);


}

void StatsTab::updateForSignal(Signal &sig){
	mean->setNum(sig.getMean());
	variance->setNum(sig.getVariance());
	stdDeviation->setNum(sig.getStdDeviation());
	avgDeviation->setNum(sig.getAvgDeviation());
	skewness->setNum(sig.getSkewness());
	kurtosis->setNum(sig.getKurtosis());
	maxY->setNum(sig.getMaxY());
	maxX->setNum(sig.getMaxX());
	minY->setNum(sig.getMinY());
	minX->setNum(sig.getMinX());
}


StatsTab::~StatsTab(){}
//:-) End of StatsTab ------------------------------------------------------------------



PlotPropTab::PlotPropTab(QWidget * parent): QWidget(parent){mod=false;}
PlotPropTab::~PlotPropTab(){}
		
bool PlotPropTab::isModified(){return mod;}
void PlotPropTab::applyChanges(Plot *){mod=false;}

//:-) End Of MyTab ---------------------------------------------------------------------

