/****************************************************************************
	Implementation of QXEmbed class

	Copyright (C) 1999-2000 Troll Tech AS
	              2001 Charles Samuels

	This library is free software; you can redistribute it and/or
	modify it under the terms of the GNU Library General Public
	License as published by the Free Software Foundation; either
	version 2 of the License, or (at your option) any later version.

	This library 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
	Library General Public License for more details.

	You should have received a copy of the GNU Library General Public License
	along with this library; see the file COPYING.LIB.  If not, write to
	the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
	Boston, MA 02111-1307, USA.
 *****************************************************************************/

#include <noatun/video.h>
#include <noatun/app.h>
#include <noatun/player.h>
#include <noatun/engine.h>

#include <qevent.h>
#include <iostream.h>

bool Video::eventFilter(QObject *, QEvent *e)
{
	(void)e;
// not sure why it's here, but it is
//	QEvent::Type t = e->type();

	return false;
}

#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>

Video::Video(const QString &title, QWidget *parent, const char *name, WFlags f)
	: QFrame(parent, name, f)
{
	setBackgroundColor(QColor("black"));
    mWindow = 0;
	connect(napp->player(), SIGNAL(newSong()), SLOT(changed()));
}

Video::~Video()
{
	if(mWindow != 0)
	{
		XUnmapWindow(qt_xdisplay(), mWindow);
		XReparentWindow(qt_xdisplay(), mWindow, qt_xrootwin(), 0, 0);
        QApplication::flushX();
    }
}

void Video::resizeEvent(QResizeEvent *e)
{
	QWidget::resizeEvent(e);

	if(mWindow != 0)
		XResizeWindow(qt_xdisplay(), mWindow, e->size().width(), e->size().height());
}

bool Video::event(QEvent *e)
{
	switch(e->type())
	{
		case QEvent::ShowWindowRequest:
			XMapRaised(qt_xdisplay(), mWindow);
			break;
		
		default:
			break;
	}

	return QWidget::event(e);
}

void Video::focusInEvent(QFocusEvent *)
{
	if(!mWindow)
		return;

	XEvent ev;
	memset(&ev, 0, sizeof(ev));
	ev.xfocus.type = FocusIn;
	ev.xfocus.window = mWindow;

	XSendEvent(qt_xdisplay(), mWindow, true, NoEventMask, &ev);
}

void Video::focusOutEvent(QFocusEvent *)
{
	if(!mWindow)
		return;

	XEvent ev;
	memset(&ev, 0, sizeof(ev));
	ev.xfocus.type = FocusOut;
	ev.xfocus.window = mWindow;
	XSendEvent(qt_xdisplay(), mWindow, true, NoEventMask, &ev);
}

void Video::embed(WId w)
{
	if(w == 0)
	{
		setBackgroundColor(QColor("grey"));
  		return;
	}
	mWindow = w;

	setBackgroundMode(NoBackground);

	// first withdraw the mWindow
	XWithdrawWindow(qt_xdisplay(), mWindow, qt_xscreen());
	QApplication::flushX();

	// make sure we will receive destroy notifications for the embedded mWindow.
	XWindowAttributes xwattr;
	XGetWindowAttributes(qt_xdisplay(), winId(), &xwattr);
	XSelectInput(qt_xdisplay(), winId(), SubstructureNotifyMask | xwattr.your_event_mask);

	// now reparent the mWindow to be swallowed by the Video widget
	XReparentWindow(qt_xdisplay(), mWindow, winId(), 0, 0);

	// and add it to the save set in case this mWindow gets destroyed before
	XAddToSaveSet(qt_xdisplay(), mWindow);
	
	QApplication::syncX();

	// now resize it
	XResizeWindow(qt_xdisplay(), mWindow, width(), height());
	XMapRaised(qt_xdisplay(), mWindow);

	setFocus();
}

bool Video::focusNextPrevChild(bool next)
{
	if(mWindow)
		return false;
	else
		return QWidget::focusNextPrevChild(next);
}

bool Video::x11Event(XEvent *e)
{
	switch(e->type)
	{
	case DestroyNotify:
		if(e->xdestroywindow.window == mWindow)
		{
			mWindow = 0;
			destroyed();
		}

	}

	return false;
}

void Video::destroyed()
{
	resize(0,0);
}

QSizePolicy Video::sizePolicy() const
{
	return QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}

QSize Video::sizeHint() const
{
	return minimumSizeHint();
}

QSize Video::minimumSizeHint() const
{
	if(mWindow)
	{
		XSizeHints size;
		long msize;
		if(XGetWMNormalHints(qt_xdisplay(), mWindow, &size, &msize) && (size.flags & PMinSize))
			return QSize(size.min_width, size.min_height);
	}

	return QSize(0, 0);
}


Arts::VideoPlayObject Video::video() const
{
	Arts::PlayObject po=napp->player()->engine()->playObject();
	if (po.isNull()) return Arts::VideoPlayObject::null();
	Arts::VideoPlayObject vpo=Arts::DynamicCast(po);
	return vpo;
}

void Video::changed()
{
	Arts::VideoPlayObject vpo=video();
	if (vpo.isNull()) return;
	
	WId id=(WId)vpo.x11WindowId();
	
	cerr << " id " << (unsigned long)id << endl;
	if (id==-1)
		QTimer::singleShot(0, this, SLOT(changed()));
	else
		window(id);
}

bool Video::fullscreen() const
{
	Arts::VideoPlayObject vpo=video();
    if (vpo.isNull()) return false;
	return vpo.fullscreen();
}

void Video::setFullscreen(bool fs)
{
	Arts::VideoPlayObject vpo=video();
    if (vpo.isNull()) return;
	vpo.fullscreen(fs);
}

void Video::window(WId video)
{
	embed(video);
	QTimer::singleShot(0, this, SIGNAL(doItAgain()));
}

void Video::doItAgain()
{
	embed(mWindow);
}

#include "noatun/video.moc"

