#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <gtk/gtk.h>
#include <lv2.h>
#include "lv2_ui.h"
#include "../audio/qtdummy.h"
#include <QtGui/QPushButton>
#include <QtGui/QVBoxLayout>
#include <QtGui/QApplication>
#include <QtGui/QMessageBox>
#include <QtGui/QX11EmbedWidget>
#include <QtCore/QFile>
#include <QtCore/QDir>
#include <QtUiTools/QUiLoader>
#include <iostream>


#define QTDUMMY_GUI_URI "http://barcelonamedia.org/plugins/lv2/qtdummy/gui"

typedef struct {
	GtkWidget *  widgetSocket;
	QWidget   *  qtWidget;

	LV2UI_Write_Function 	write_function;
	LV2UI_Controller 	controller;

	const char * bundlePath;

} GuiData;


static void on_socket_realized(
	GtkWidget *widget,
	gpointer   user_data)
{
	GuiData * pluginGui = (GuiData*) user_data;

	int id = gtk_socket_get_id (GTK_SOCKET(pluginGui->widgetSocket));
	QX11EmbedWidget * plug = new QX11EmbedWidget;
	
	plug->setLayout(new QVBoxLayout);
	plug->layout()->addWidget(pluginGui->qtWidget);
	plug->embedInto(id);
	plug->show();
}

QWidget * loadUi(const QString & uiFilename)
{
    QFile file(uiFilename);
    file.open(QFile::ReadOnly);
    QUiLoader loader;
    loader.addPluginPath("/user/share/NetworkEditor/qtplugins"); //TODO Make that an option
    QDir dir(QApplication::applicationDirPath());
    loader.addPluginPath( QString(dir.absolutePath())+"/../plugins" ); //TODO do only for mac?

    QStringList paths = loader.pluginPaths();
    for (QStringList::iterator it = paths.begin(); it!=paths.end(); it++)
    {
        std::cout << "Looking for plugins at path: " << it->toLocal8Bit().constData() << std::endl;
    }
    QWidget * userInterface = loader.load(&file, 0 );
    if (userInterface)
    {
        if (userInterface->windowIcon().isNull())
            userInterface->setWindowIcon(QIcon(":/icons/images/Prototyper-icon.svg"));
    }
    file.close();
    return userInterface;
}

static LV2UI_Handle 
qtdummy_gui_instantiate(const struct _LV2UI_Descriptor* descriptor
		, const char* plugin_uri
		, const char* bundle_path
		, LV2UI_Write_Function write_function
		, LV2UI_Controller controller
		, LV2UI_Widget* widget
		, const LV2_Feature* const* features)
{
	GuiData *pluginGui = (GuiData *)malloc(sizeof(GuiData));
	if(pluginGui==NULL) return NULL;

	pluginGui->write_function = write_function;
	pluginGui->controller = controller;
	pluginGui->bundlePath = bundle_path;
	// This should be your own widget
//	pluginGui->qtWidget = new QPushButton("Qt Button!!");
	pluginGui->qtWidget = loadUi(QString(bundle_path)+"ui/qtdummy_gui.ui");
	QSize qtsize = pluginGui->qtWidget->size();

	pluginGui->widgetSocket = gtk_socket_new();
	gtk_widget_set_size_request(
		pluginGui->widgetSocket,
		pluginGui->qtWidget->width(),
		pluginGui->qtWidget->height());
	g_signal_connect(G_OBJECT(pluginGui->widgetSocket), "realize",
		G_CALLBACK(on_socket_realized), gpointer(pluginGui) );

	*widget = (LV2UI_Widget) pluginGui->widgetSocket;

	/* return the instance */
	return pluginGui;
}


static void 
qtdummy_gui_cleanup(LV2UI_Handle ui)
{
	return;
}


/// Called whenever some subscribed output port outputs data
static void 
qtdummy_gui_port_event(LV2UI_Handle ui, uint32_t port, uint32_t buffer_size, uint32_t format, const void*  buffer)
{
	GuiData *pluginGui = (GuiData *)ui;

	float value;

	if(format==0) 
	{
		value=* (float *) buffer;
		switch(port)
		{
			default: break;
		}

	}
}


static LV2UI_Descriptor MyGuiDescriptor =
{
	URI :            QTDUMMY_GUI_URI,
	instantiate :    qtdummy_gui_instantiate,
	cleanup :        qtdummy_gui_cleanup,
	port_event :     qtdummy_gui_port_event,
	extension_data : NULL,
};

const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index)
{
	printf("Init!!!\n");
	// QApplication should be created in the host to be correct, but just in case it doesn't
	static QApplication * app = 0;
	static char * argv[] = {0};
	static int argc = 0;
	if (not QApplication::instance())
		app = new QApplication(argc, argv);

	switch (index) {
		case 0:
			return & MyGuiDescriptor;
	default:
		return NULL;
	}
}




