/****************************************************************************
****************************************************************************/

#include "Window.h"
#include "Environment.h"
#include "Client.h"

#include <QtGui>
#include <QToolButton>
#include <QThread>
#include <QScrollBar>
#include <QGridLayout>
#include <QPushButton>
#include <QGroupBox>
#include <QCheckBox>
#include <QSpinBox>
#include <QLineEdit>
#include <QLCDNumber>
#include <string>
#include <iostream>


#include "RenderArea.h"

using namespace std;

//static const QSize resultSize(128, 128);
static const QSize resultSize(100, 100);


Window::Window(QWidget *parent)
  : QWidget(parent)
{
  
	QVBoxLayout *vvbox = new QVBoxLayout;
	

	mClient = new Client("127.0.0.1", 2727);

	cerr<<"H1"<<endl;
	
  //vvbox->addWidget(grid);
	QGroupBox *groupBox;
	QHBoxLayout *hbox = new QHBoxLayout;
	
	groupBox = new QGroupBox(tr("&Controls"));
	groupBox->setLayout(hbox);
	vvbox->addWidget(groupBox);
	
  QPushButton *button;

	button = new QPushButton(tr("&Accelerate"));
	connect(button, SIGNAL(pressed()), mClient, SLOT(Accelerate()));
	connect(button, SIGNAL(released()), mClient, SLOT(ResetControls()));
  
	hbox->addWidget(button);
	hbox->addStretch(1);
	
  button = new QPushButton(tr("&Break"));
	connect(button, SIGNAL(pressed()), mClient, SLOT(Break()));
	connect(button, SIGNAL(released()), mClient, SLOT(ResetControls()));
	hbox->addWidget(button);
	hbox->addStretch(1);

	button = new QPushButton(tr("&Left"));
	connect(button, SIGNAL(pressed()), mClient, SLOT(Left()));
	connect(button, SIGNAL(released()), mClient, SLOT(ResetControls()));
	hbox->addWidget(button);
	hbox->addStretch(1);

	button = new QPushButton(tr("&Right"));
	connect(button, SIGNAL(pressed()), mClient, SLOT(Right()));
	connect(button, SIGNAL(released()), mClient, SLOT(ResetControls()));
	hbox->addWidget(button);
	hbox->addStretch(1);

	button = new QPushButton(tr("&Tempomat ON"));
	connect(button, SIGNAL(clicked()), mClient, SLOT(TempoOn()));
	hbox->addWidget(button);
	hbox->addStretch(1);

	button = new QPushButton(tr("&Tempomat OFF"));
	connect(button, SIGNAL(clicked()), mClient, SLOT(TempoOff()));
	hbox->addWidget(button);
	hbox->addStretch(1);
	
	button = new QPushButton(tr("&Faster"));
	connect(button, SIGNAL(clicked()), mClient, SLOT(Faster()));
	hbox->addWidget(button);
	hbox->addStretch(1);
	
	button = new QPushButton(tr("&Slower"));
	connect(button, SIGNAL(clicked()), mClient, SLOT(Slower()));
	hbox->addWidget(button);
	hbox->addStretch(1);

	button = new QPushButton(tr("&Left Blinker On"));
	connect(button, SIGNAL(clicked()), mClient, SLOT(LeftBlinkerOn()));
	hbox->addWidget(button);
	hbox->addStretch(1);

		button = new QPushButton(tr("&Left Blinker Off"));
	connect(button, SIGNAL(clicked()), mClient, SLOT(LeftBlinkerOff()));
	hbox->addWidget(button);
	hbox->addStretch(1);

	button = new QPushButton(tr("&Right Blinker On"));
	connect(button, SIGNAL(clicked()), mClient, SLOT(RightBlinkerOn()));
	hbox->addWidget(button);
	hbox->addStretch(1);
	
	button = new QPushButton(tr("&Right Blinker Off"));
	connect(button, SIGNAL(clicked()), mClient, SLOT(RightBlinkerOff()));
	hbox->addWidget(button);
	hbox->addStretch(1);
	
	
	button = new QPushButton(tr("Quit"));
  button->setAutoDefault(false);
	hbox->addWidget(button);
	//  grid->addWidget(button, 2, 1);
  connect(button, SIGNAL(clicked()), this, SLOT(close()));

	QSpinBox *spinBox = new QSpinBox(this);
	spinBox->setToolTip("Controller ID");
	connect(spinBox, SIGNAL(valueChanged(int)), mClient, SLOT(SetControllerId(int)));
	
	vvbox->addWidget(spinBox);

	spinBox = new QSpinBox(this);
	spinBox->setToolTip("Profile ID");
	connect(spinBox, SIGNAL(valueChanged(int)), mClient, SLOT(SetProfileId(int)));
	
	vvbox->addWidget(spinBox);
	
	mCbSpeed = new QCheckBox(tr("Show Speed"));
	mCbSpeed->setCheckState(Qt::Checked);
	vvbox->addWidget(mCbSpeed);
  connect(mCbSpeed, SIGNAL(stateChanged(int)), this, SLOT(UpdateCombi(int)));
	
	mCbSigns = new QCheckBox(tr("Show Signs"));
	mCbSigns->setCheckState(Qt::Checked);
	vvbox->addWidget(mCbSigns);
  connect(mCbSigns, SIGNAL(stateChanged(int)), this, SLOT(UpdateCombi(int)));

	mCbAcc = new QCheckBox(tr("Show ACC"));
	mCbAcc->setCheckState(Qt::Checked);
	vvbox->addWidget(mCbAcc);
  connect(mCbAcc, SIGNAL(stateChanged(int)), this, SLOT(UpdateCombi(int)));


	mCbLaneAssist = new QCheckBox(tr("Show Lane Assist"));
	mCbLaneAssist->setCheckState(Qt::Checked);
	vvbox->addWidget(mCbLaneAssist);
  connect(mCbLaneAssist, SIGNAL(stateChanged(int)), this, SLOT(UpdateCombi(int)));

	mSpinLaneLeft = new QSpinBox(this);
	mSpinLaneLeft->setMinimum(0);
	mSpinLaneLeft->setMaximum(2);
	vvbox->addWidget(mSpinLaneLeft);
  connect(mSpinLaneLeft, SIGNAL(valueChanged(int)), this, SLOT(UpdateCombi(int)));

	mSpinLaneRight = new QSpinBox(this);
	mSpinLaneRight->setMinimum(0);
	mSpinLaneRight->setMaximum(2);
	vvbox->addWidget(mSpinLaneRight);
  connect(mSpinLaneRight, SIGNAL(valueChanged(int)), this, SLOT(UpdateCombi(int)));
	
	mCbLaneAssistVehicle = new QCheckBox(tr("Show Lane Assist Vehicle"));
	mCbLaneAssistVehicle->setCheckState(Qt::Checked);
	vvbox->addWidget(mCbLaneAssistVehicle);
  connect(mCbLaneAssistVehicle, SIGNAL(stateChanged(int)), this, SLOT(UpdateCombi(int)));

	mSpinVehicleDistance = new QSpinBox(this);
	mSpinVehicleDistance->setMinimum(0);
	mSpinVehicleDistance->setMaximum(4);
	vvbox->addWidget(mSpinVehicleDistance);
  connect(mSpinVehicleDistance, SIGNAL(valueChanged(int)), this, SLOT(UpdateCombi(int)));


	mCbRoadDistanceBars = new QCheckBox(tr("Show Road Distance Bars"));
	mCbRoadDistanceBars->setCheckState(Qt::Unchecked);
	vvbox->addWidget(mCbRoadDistanceBars);
  connect(mCbRoadDistanceBars, SIGNAL(stateChanged(int)), this, SLOT(UpdateCombi(int)));
	
	
	mCbRoadLeftStrip = new QCheckBox(tr("Show Road Left Strip"));
	mCbRoadLeftStrip->setCheckState(Qt::Unchecked);
	vvbox->addWidget(mCbRoadLeftStrip);
  connect(mCbRoadLeftStrip, SIGNAL(stateChanged(int)), this, SLOT(UpdateCombi(int)));

	mCbRoadRightStrip = new QCheckBox(tr("Show Road Right Strip"));
	mCbRoadRightStrip->setCheckState(Qt::Unchecked);
	vvbox->addWidget(mCbRoadRightStrip);
  connect(mCbRoadRightStrip, SIGNAL(stateChanged(int)), this, SLOT(UpdateCombi(int)));
	
	
	mCbRoadVehicleHighlight = new QCheckBox(tr("Show Road Car Highlight"));
	mCbRoadVehicleHighlight->setCheckState(Qt::Unchecked);
	vvbox->addWidget(mCbRoadVehicleHighlight);
  connect(mCbRoadVehicleHighlight, SIGNAL(stateChanged(int)), this, SLOT(UpdateCombi(int)));

	mSpinVehicleHighlight = new QSpinBox(this);
	mSpinVehicleHighlight->setMinimum(0);
	mSpinVehicleHighlight->setMaximum(2);
	vvbox->addWidget(mSpinVehicleHighlight);
  connect(mSpinVehicleHighlight, SIGNAL(valueChanged(int)), this, SLOT(UpdateCombi(int)));

	mCbShowNavigation = new QCheckBox(tr("Show Navigation"));
	mCbShowNavigation->setCheckState(Qt::Unchecked);
	vvbox->addWidget(mCbShowNavigation);
  connect(mCbShowNavigation, SIGNAL(stateChanged(int)), this, SLOT(UpdateCombi(int)));

	mCbShowRoadNavigation = new QCheckBox(tr("Show Road Navigation"));
	mCbShowRoadNavigation->setCheckState(Qt::Unchecked);
	vvbox->addWidget(mCbShowRoadNavigation);
  connect(mCbShowRoadNavigation, SIGNAL(stateChanged(int)), this, SLOT(UpdateCombi(int)));

	mSpinHeightOffset = new QSpinBox(this);
	mSpinHeightOffset->setMinimum(-127);
	mSpinHeightOffset->setMaximum(127);
	vvbox->addWidget(mSpinHeightOffset);
  connect(mSpinHeightOffset, SIGNAL(valueChanged(int)), this, SLOT(UpdateCombi(int)));

	
	mLcd = new QLCDNumber(3);
	mLcd->setSegmentStyle(QLCDNumber::Flat);
	mLcd->setMinimumSize(QSize(100, 100));
	
	vvbox->addWidget(mLcd);
	
	mLogWidget = new QPlainTextEdit;

	mLogWidget->setMinimumSize(QSize(300, 100));
	//  grid->addWidget(logWidget, 3, 1);
	vvbox->addWidget(mLogWidget);


	mRenderArea = new RenderArea(this, *mClient);
	vvbox->addWidget(mRenderArea);
	//  QTimer *timer = new QTimer(this);
	//  connect(timer, SIGNAL(timeout()), this, SLOT(UpdateRaspiCamPreview()));
	//  timer->start(200);
  
  // GLOBAL SETTING
	//  setLayout(grid);
	setLayout(vvbox);
  setWindowTitle(tr("TCP Drive"));
	//  resize(800, 480);

	cerr<<"Window created"<<endl;

	cerr<<"H2"<<endl;

	connect(mClient, SIGNAL(Message(const QString&)), this, SLOT(Message(const QString&)));
	connect(mClient, SIGNAL(Speed(const float)), this, SLOT(SetSpeed(const float)));

  if (Environment::GetSingleton()->GetBool("Drive.fullScreen"))
    showFullScreen();
}

void
Window::ToggleFullScreen()
{
	if (isFullScreen())
		showNormal();
	else
		showFullScreen();
}


void
Window::SetSpeed(const float speed)
{
	if (mLcd)
		mLcd->display((int)speed);
}


void
Window::UpdateCombi(int)
{
	mClient->SendArHud(mCbSpeed->checkState() != 0,
										 mCbSigns->checkState() != 0,
										 mCbAcc->checkState() != 0,
										 mCbLaneAssist->checkState() != 0,
										 mSpinLaneLeft->value(),
										 mSpinLaneRight->value(),
										 mCbLaneAssistVehicle->checkState() != 0,
										 mSpinVehicleDistance->value(),
										 mCbRoadDistanceBars->checkState() != 0,
										 mCbRoadLeftStrip->checkState() != 0,
										 mCbRoadRightStrip->checkState() != 0,
										 mCbRoadVehicleHighlight->checkState() != 0,
										 mSpinVehicleHighlight->value(),
										 mCbShowNavigation->checkState()!=0,
										 mCbShowRoadNavigation->checkState()!=0,
										 mSpinHeightOffset->value()
										 );
}

void
Window::Message(const QString& text)
{
	QString t;
	const bool append = false;
	if (append) {
		t = mLogWidget->toPlainText();
		t.append(text);
		int l = t.length();
		int maxLen = 1000;
		if (l > maxLen)
			t.remove(0, l - maxLen);
	} else {
		t = text;
	}
	mLogWidget->setPlainText(t);
  //  appendPlainText(text); // Adds the message to the widget
  mLogWidget->verticalScrollBar()->setValue(mLogWidget->verticalScrollBar()->maximum()-1); // Scrolls to the bottom
	static int counter = 0;
	if (counter++ % 5 == 0) 
		mRenderArea->repaint();
}
