/*
 * Copyright 2009-2010  Stefan Gehn <stefan@srcbox.net>
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of 
 * the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "irtest.hpp"

#include "TouchThread.hpp"
#include "settings.hpp"
#include "TouchEvent.hpp"

#include "touchrectgroup.hpp"
#include "touchvaluegroup.hpp"
#include "touchvaluedistance.hpp"
#include "rawvaluegroup.hpp"

#include <qapplication.h>
#include <qdebug.h>
#include <qfile.h>
#include <qgl.h>
#include <qgraphicsscene.h>
#include <qgraphicsview.h>
#include <qevent.h>

using namespace IrTouch;


IrTestWindow::IrTestWindow(): QGraphicsView(), mObjectText(0)
{
  qDebug() << "IrTestWindow::IrTestWindow()";

  IrTouch::Settings *s = IrTouch::Settings::self();

	TouchDataGroup::sPpmX = 4096.0 / (double) s->physicalWidth();
	TouchDataGroup::sPpmY = 4096.0 / (double) s->physicalHeight();
	qDebug() << "ppmX:" << TouchDataGroup::sPpmX << ";  ppmY:" << TouchDataGroup::sPpmY;

  //showFullScreen();
  setViewport(new QGLWidget());
  setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
	setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

  mScene = new QGraphicsScene(this);
  mScene->setSceneRect(0, 0, 4096, 4096);
  mScene->setItemIndexMethod(QGraphicsScene::NoIndex);
	QFont f(QApplication::font());
	f.setPointSize(64);
	mScene->setFont(f);
  setScene(mScene);

	addTouchDataGroup(new RawValueGroup());
	addTouchDataGroup(new TouchValueGroup());
	addTouchDataGroup(new TouchRectGroup());
	addTouchDataGroup(new TouchValueDistance());

	resize(840, 840);
}

void IrTestWindow::addTouchDataGroup(TouchDataGroup *tdg)
{
	mScene->addItem(tdg);
	mGroups.append(tdg);
}


void IrTestWindow::resizeEvent(QResizeEvent *event)
{
  QGraphicsView::resizeEvent(event);
  resetTransform();
  scale(width() / mScene->width(), height() / mScene->height());
}


void IrTestWindow::updateTouchData(const IrTouch::TouchData data)
{
	Q_FOREACH(TouchDataGroup *group, mGroups)
	{
		if (group->isVisible())
			group->update(data);
	}

	if (!mObjectText)
	{
		mObjectText = new QGraphicsSimpleTextItem(0, mScene);
		mObjectText->setFont(mScene->font());
		mObjectText->setPos(25, 25);
	}
  mObjectText->setText(data.guessedObjectType());
}


void IrTestWindow::takeScreenshot()
{
	static int sScreenshotIndex = 0;

	QString fileName = QString("screenshot_%1.png").arg(sScreenshotIndex, 2, 10,
																											QLatin1Char('0'));
	QImage img(width(), height(), QImage::Format_ARGB32);
	QPainter painter(&img);
	mScene->render(&painter);
	img.save(fileName, "PNG", 100);
	qDebug() << "Saved screenshot to" << fileName;
	sScreenshotIndex++;
}


void IrTestWindow::keyReleaseEvent(QKeyEvent *kev)
{
	switch (kev->key())
	{
		case Qt::Key_Escape:
			close();
			break;

		case Qt::Key_1:
		case Qt::Key_2:
		case Qt::Key_3:
		case Qt::Key_4:
		case Qt::Key_5:
		case Qt::Key_6:
			int groupIdx = (kev->key() - Qt::Key_1);
			if (groupIdx < mGroups.count())
			{
				if (kev->modifiers() & Qt::AltModifier)
					mGroups[groupIdx]->toggleTextVisible();
				else
					mGroups[groupIdx]->toggleVisible();
			}
			break;

		case Qt::Key_F5:
			takeScreenshot();
			break;

		case Qt::Key_F11:
			if (isFullScreen())
				showNormal();
			else
				showFullScreen();
			break;

		default:
			QGraphicsView::keyReleaseEvent(kev);
	}
}

// ----------------------------------------------------------------------------

int main(int argc, char **argv)
{
	QThread *touchThread;
  QApplication app(argc, argv);
  IrTestWindow win;

	QStringList args = app.arguments();
	if ((args.count() > 1) && QFile::exists(args[1]))
		touchThread = new IrTouch::TouchThread(args[1]);
	else
		touchThread = new IrTouch::TouchThread();

  touchThread->start();
  QObject::connect(touchThread, SIGNAL(dataDecoded(const IrTouch::TouchData)),
      &win, SLOT(updateTouchData(const IrTouch::TouchData)),
      Qt::QueuedConnection);

  win.show();
  int ret = app.exec();

  touchThread->quit();
  if (!touchThread->wait(5000))
    qCritical() << "TouchThread still alive, exiting anyway";
  delete touchThread;

  return ret;
}

#include "moc_irtest.cpp"
