/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/




#include <MvTemplates.h>

#include "MvQX11Application.h"

MvQX11Application::MvQX11Application(int& ac, char** av, const char* name) : 
	QApplication(ac,av)
{
}

MvQX11Application::~MvQX11Application()
{
}

#ifdef METVIEW_MOTIF
bool MvQX11Application::x11EventFilter (XEvent *event)
{
	if(event->type != ClientMessage)
		return QApplication::x11EventFilter(event);

	XClientMessageEvent *e =(XClientMessageEvent*) event;

	drop_.format(e->format);
	char *s =XGetAtomName(QX11Info::display(), e->message_type );
	
	/* On 64-bit platforms, there appears to be a problem when using the data.l[]
	   part of the XClientMessageEvent structure. This is most likely because it is
	   defined as an array of longs, but it is intended as an array of 32-bit integers
	   (e->format=32). When dealing with this array, some of the data is lost, probably
	   because the internal 'X' code assumes 32-bit values. Therefore, we explicitly
	   use an 'int' pointer to access this data structure so that we can use 32-bit
	   values in it which is what it thinks it's getting. If 'int' is ever defined
	   to be greater than 32, then this code will have to be revised. */
	
	int *iarray = (int *)&e->data.l[0];


	if(strcmp(s,"ICON_DROP_WIN_ID") == 0)
	{
		drop_.clear();
		drop_.winId(iarray[0]);
		drop_.x(iarray[1]);
		drop_.y(iarray[2]);
		drop_.iconId(iarray[3]);
	}

	if(strcmp(s,"ICON_DROP_ICON_CLASS") == 0)
	{
		drop_.className(e->data.b);
	}
	if(strcmp(s,"ICON_DROP_ICON_NAME") == 0)
	{
		drop_.name(e->data.b);
	}

	if(strcmp(s,"ICON_DROP_WIN_NAME") == 0)
	{
		//drop_.window_name(e->data.b);
	}
		
	if(strcmp(s,"ICON_DROP_BUF") == 0)
	{
		drop_.batchNumber(iarray[3]);
	}
	/*if(strcmp(s,"ICON_DROP_BUF_LEN") == 0)
	{
		cout << " buf len:" << e->data.l[0] << endl;
	}*/

	if(strcmp(s,"ICON_DROP_BUF_LEN_EXT") == 0)
	{
		drop_.fullNameLen(iarray[0]);
	}

	if(strcmp(s,"ICON_DROP_BUF_EXT") == 0)
	{
		// there seems to be a problem on 64-bit machines with the
		// size of the XClientMessageEvent structure, causing some
		// extra random bytes to be added to the string.
		// Here we just ensure that we just copy 20 bytes (which is what it should be).
		char name[25];
		strncpy (name, e->data.b, 20);
		name[20] = '\0';
		drop_.appendToFullName(name);
	}
	else if(strcmp(s,"ICON_DROP_END") == 0)
	{
		  //acquire full name
		drop_.finalizeFullName();

		//send drop info to the appropriate function
		emit sendDropInfo(&drop_);

		//notify source that drop was successfully received
		XClientMessageEvent cevent;
		int *iarrayout = (int *)&cevent.data.l[0];
		cevent.display = QX11Info::display(); //XtDisplay(widget);
		cevent.window = drop_.winId(); //cb.remote_window
		cevent.type = ClientMessage;
		cevent.format = drop_.format();    // 32
		iarrayout[0] = 1; //cb.accept_it
		iarrayout[1] = drop_.iconId();
		iarrayout[2] = e->window; //XtWindow(widget);
		iarrayout[3] = 65537; //(cb.icon_no << 16) + cb.icon_count;
		iarrayout[4] = drop_.batchNumber();	  //cb.icon_batch;
		cevent.message_type = XInternAtom(QX11Info::display(),"ICON_DROP_ACK",False);

		XSendEvent(QX11Info::display(),drop_.winId(),True,NoEventMask,(XEvent*)&cevent);
		XFlush(QX11Info::display());
		drop_.clear();
	}

	XFree(s);

	return QApplication::x11EventFilter(event);
}
#endif

