/***************************************************************************
 *   Copyright (C) 2004 by Stefano                                         *
 *   stefano@xiaprojects.com                                               *
 *                                                                         *
 *   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, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "xeplugin_mouse.h"
#include <xeobject.h>
#include <xeconfiguration.h>
#include <xgdocker.h>
#include <qevent.h> 
#include <kapplication.h>
//#include <kmainwindow.h>
#include <stdlib.h>

#include <kxdocker_setup_sources.h>
//#undef ENABLE_FINAL
XEPlugin_Mouse::XEPlugin_Mouse(QObject *parent, const char *name)
 : QObject(parent, name)
{
	XEObject::xPluginAdd(this);
	display = kapp->getDisplay();
	root = RootWindow(display,DefaultScreen(display));
}


XEPlugin_Mouse::~XEPlugin_Mouse()
{
}


#include "xeplugin_mouse.moc"


/*!
    \fn XEPlugin_Mouse::xSetup()
 */
void XEPlugin_Mouse::xSetup()
{
#ifndef ENABLE_FINAL
	qWarning("Mouse::xSetup");
#endif
	XEConfiguration *Configurator=(XEConfiguration *)XEObject::xGetConfiguration();
	xGDocker=(XGDocker *)XEObject::xGetDocker();
	if(Configurator==NULL || xGDocker==NULL)
	{
#ifndef ENABLE_FINAL
	// Emits Signal of warning
	//xWarningMsg(this,"error while searching for plugin");
	qWarning("error while searching for plugin");
#endif
		return;
	}
	ActiveConfiguration=Configurator->xGetConfiguration();

}


/*!
    \fn XEPlugin_Mouse::xStart()
 */
void XEPlugin_Mouse::xStart()
{
#ifndef ENABLE_FINAL
	qWarning("Mouse::xStart");
#endif
	connect(xGDocker,SIGNAL(xEventMouseMoved(int,int)),
		this,SLOT(xEventMouseMoved(int,int)));
	
	connect(xGDocker,SIGNAL(xEventDockerHidden()),
		this,SLOT(xEventDockerHidden()));
	
	connect(this,SIGNAL(xGetWidget(QWidget*& )),
		xGDocker,SLOT(xGetWidget(QWidget*& )));
	
	connect(this,SIGNAL(mouseMoveSoftware(int, int )),
		xGDocker,SLOT(xMouseMoveSoftware(int, int )));
	xGetWidget(xGDockerWindow);
	
}


/*!
    \fn XEPlugin_Mouse::xStop()
 */
void XEPlugin_Mouse::xStop()
{
    /// @todo implement me
}


/*!
    \fn XEPlugin_Mouse::xEventMouseMoved(int x, int y, int button)
 */
void XEPlugin_Mouse::xEventMouseMoved(int nx,int ny)
{
//	MouseTimer.singleShot(10, this, SLOT(stepMouseTimer()));
	x=nx;
	y=ny;
#ifndef ENABLE_FINAL
	qWarning("MouseTracking");
#endif
	stepMouseTimer();
}


/*!
    \fn XEPlugin_Mouse::stepMouseTimer()
 */
void XEPlugin_Mouse::stepMouseTimer()
{
	if(MousePollingMutex.tryLock()==false)return;
	QPoint pos, mouse, vect;
	int WinX, WinY;
	int XCoord,YCoord;
	XQueryPointer(display, root, &RootIDRet, &ChildIDRet, &XCoord,&YCoord, &WinX, &WinY, &StateMask);
	//mouse = xGDocker->mapFromGlobal(QPoint(XCoord,YCoord));
	mouse = xGDockerWindow->mapFromGlobal(QPoint(XCoord,YCoord));
	//if(mouse.x()==x||mouse.y()==y)return;
	if(mouse.y()>=0)
	{
		MousePollingMutex.unlock();
		return;
	}
	mouseMoveSoftware(mouse.x(),mouse.y());
//	xGDocker->mouseMoveSoftware(mouse.x(),mouse.y());
#ifndef ENABLE_FINAL
	qWarning("MouseTracking:End");
#endif
	MousePollingMutex.unlock();
	
}


/*!
    \fn XEPlugin_Mouse::xEventDockerHidden()
 */
void XEPlugin_Mouse::xEventDockerHidden()
{
#ifndef ENABLE_FINAL
	qWarning("XEPlugin_Mouse::xEventDockerHidden()");
#endif
	stepMouseTracking();
}


/*!
    \fn XEPlugin_Mouse::stepMouseTracking()
 */
void XEPlugin_Mouse::stepMouseTracking()
{
#ifndef ENABLE_FINAL
	qWarning("XEPlugin_Mouse::stepMouseTracking()");
#endif
	
	int PollingTimeout=200;
	static int CountStep=0;
	static int PollingConversion=ActiveConfiguration->Window.SendToForgroundTimeout/PollingTimeout;

	// 0.22 support send to background which is not compatible with this!
	//if(xGDocker->getRaised()>0 || !xGDocker->isHidden())return;
	if(xGDocker->getRaised()>0 )return;
	
	if(MousePollingMutex.tryLock()==false)return;
	
	QPoint pos, mouse, vect;
	int WinX, WinY;
	int XCoord,YCoord;
	XQueryPointer(display, root, &RootIDRet, &ChildIDRet, &XCoord,&YCoord, &WinX, &WinY, &StateMask);
	
	mouse = xGDocker->mapFromGlobal(QPoint(XCoord,YCoord));
	
	if(strcmp(ActiveConfiguration->Window.Align,"bottom")==0)
	{
		// idea from georg
		// raise the bar only if there are 2 corner
		int MouseIsOk=0;
		
		if(ActiveConfiguration->Window.HideMouseCornerRight)
		{
		if(XCoord>=
		QApplication::desktop()->width()-
		ActiveConfiguration->Window.HideMouseEdge
		)
		{
			MouseIsOk++;
		}
		else MouseIsOk--;

		}
		if(ActiveConfiguration->Window.HideMouseCornerLeft)
		{
		if(XCoord<=
		ActiveConfiguration->Window.HideMouseEdge
		)
		{
			MouseIsOk++;
		}
		else MouseIsOk--;
		}
		if(YCoord>=
		QApplication::desktop()->height()-
		ActiveConfiguration->Window.HideMouseEdge
		)
		{
			MouseIsOk++;

		}
		else MouseIsOk--;

		if(MouseIsOk>0)
		{
				
			if(CountStep<PollingConversion)CountStep++;
			else
			{
			CountStep=0;
			// ok than we have to raise the widget!
			
			xGDocker->showRaised();
#ifdef ENABLE_FINAL
			qWarning("MouseTracking:End RAISED!!!");
#endif
			MousePollingMutex.unlock();
			return;
			}

		}
		else CountStep=0;

	}
	if(strcmp(ActiveConfiguration->Window.Align,"top")==0)
	{
		// idea from georg
		// raise the bar only if there are 2 corner
		int MouseIsOk=0;
		
		if(ActiveConfiguration->Window.HideMouseCornerRight)
		{
		if(XCoord>=
		QApplication::desktop()->width()-
		ActiveConfiguration->Window.HideMouseEdge
		)
		{
			MouseIsOk++;
		}
		else MouseIsOk--;
		
		}
		if(ActiveConfiguration->Window.HideMouseCornerLeft)
		{
		if(XCoord<=
		ActiveConfiguration->Window.HideMouseEdge
		)
		{
			MouseIsOk++;
		}
		else MouseIsOk--;
		
		}

		if(YCoord<=ActiveConfiguration->Window.HideMouseEdge
		)
		{
			MouseIsOk++;
		}
		else MouseIsOk--;

		if(MouseIsOk>0)
		{
			if(CountStep<PollingConversion)CountStep++;
			else
			{
			CountStep=0;
			xGDocker->showRaised();
#ifdef ENABLE_FINAL
			qWarning("MouseTracking:End RAISED!!!");
#endif
			MousePollingMutex.unlock();
			return;
			}
		}
		else CountStep=0;

	}
#ifndef ENABLE_FINAL
	qWarning("MouseTracking:End");
#endif
	MousePollingMutex.unlock();
	
	QTimer::singleShot(PollingTimeout,this,SLOT(stepMouseTracking()));
}


/*!
    \fn XEPlugin_Mouse::xGetParameter(const QString,QString&)
 */
void XEPlugin_Mouse::xGetParameter(const QString,QString&)
{
    /// @todo implement me
}


/*!
    \fn XEPlugin_Mouse::xGetParameterList(QStringList*)
 */
void XEPlugin_Mouse::xGetParameterList(QStringList*)
{
    /// @todo implement me
}
