#include <QApplication>
#include <QPainter>
#include <QPixmap>
#include <QSocketNotifier>
#include <PythonQt.h>
#include <PythonQtGui.h>
#include <qlabelfactory.h>
#include <canvasfactory.h>
#include <qtimerfactory.h>
#include <qsocketnotifierfactory.h>
#include <pythonoutput.h>
#include <locale.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#include <sys/mman.h>

PythonOutput::PythonOutput(QObject* parent) : QObject(parent)
{
  connect(PythonQt::self(), SIGNAL(pythonStdOut(const QString&)), this, SLOT(stdOut(const QString&)));
  connect(PythonQt::self(), SIGNAL(pythonStdErr(const QString&)), this, SLOT(stdErr(const QString&)));
}

void PythonOutput::stdOut(const QString& s)
{
    std::cout << s.toLatin1().data();
}

void PythonOutput::stdErr(const QString& s)
{
    std::cout << s.toLatin1().data();
}

int main(int argc, char *argv[])
{

    {
	// Blank the screen
	const int fb_size = 480*272*2;
	int fd = ::open("/dev/fb0", O_RDWR);
	if (fd > 0) {
		printf("opened fb0\n");
		void *fbmem = ::mmap(0, fb_size, PROT_WRITE, MAP_SHARED, fd, 0);
		if (fbmem != (void*)-1) {
			printf("mapped fb0\n");
			int filefd = ::open("/usr/opt/Qtopia/fb_dump", O_RDWR);
			if (filefd > 0) {
				printf("opened /usr/opt/Qtopia/fb_dump file\n");
				void *filemem = ::mmap(0, fb_size, PROT_READ, MAP_SHARED, filefd, 0);
				if (filemem != (void*)-1) {
					printf("mapped fb_dump file\n");
					memcpy(fbmem, filemem, fb_size);
					printf("copied the memory\n");
					::munmap(filemem, fb_size);
				}
				::close(filefd);
			} else {
				printf("clearing the framebuffer memory\n");
				memset(fbmem,0,fb_size);
			}
			struct { unsigned int a, b; } rows = { 0, 271 };
			printf("flushing the framebuffer memory to the LCD\n");
			::ioctl(fd, 0x46ff, &rows);
			::munmap(fbmem, fb_size);
		}
		::close(fd);
		printf("done splash\n");
    	}
    }

    QApplication app(argc,argv);

    PythonQt::init(PythonQt::IgnoreSiteModule | PythonQt::RedirectStdOut);
    PythonQtGui::init();

    PythonQtObjectPtr mainContext = PythonQt::self()->getMainModule();

    // register c++ classes so they can be instantiated in python code
    PythonQt::self()->registerCPPClassNames(QStringList() << "SocketNotifier");
    PythonQt::self()->addDecorators(new SocketNotifierFactory());
    PythonQt::self()->registerClass(&SocketNotifier::staticMetaObject);

    PythonQt::self()->registerCPPClassNames(QStringList() << "Timer");
    PythonQt::self()->addDecorators(new TimerFactory());
    PythonQt::self()->registerClass(&Timer::staticMetaObject);

    PythonQt::self()->registerCPPClassNames(QStringList() << "Canvas");
    PythonQt::self()->addDecorators(new CanvasFactory());
    PythonQt::self()->registerClass(&Canvas::staticMetaObject);

    PythonQt::self()->registerCPPClassNames(QStringList() << "CanvasItem");
    PythonQt::self()->addDecorators(new CanvasItemFactory());
    PythonQt::self()->registerClass(&CanvasItem::staticMetaObject);

    PythonQt::self()->registerCPPClassNames(QStringList() << "QLabel");
    PythonQt::self()->addDecorators(new QLabelFactory());

    PythonQt::self()->registerCPPClassNames(QStringList() << "QTimer");
    PythonQt::self()->addDecorators(new QTimerFactory());
    PythonQt::self()->registerClass(&QTimer::staticMetaObject);
    PythonOutput *output = new PythonOutput(0);

    ::setlocale(LC_ALL,"");

    QStringList scriptPaths;
    scriptPaths += "/usr/local/lgvp";
    PythonQt::self()->setModuleImportPath(mainContext, scriptPaths);
    mainContext.evalFile("/usr/local/lgvp/vphone.py");
    // start the Qt event loop
    return app.exec();
}


