/*
    knetd, KDE Network Daemon

    Copyright (c) 2005 by Engin AYDOGAN		<engin @ bzzzt.biz>

    *************************************************************************
    *                                                                       *
    * 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.                                   *
    *                                                                       *
    *************************************************************************
*/

#ifndef POPUP_DISPATCH_H_
#define POPUP_DISPATCH_H_

#include <qobject.h>

#include "popupmanager.h"

/**
 * This class places the widget provided in PopupInternal into a sane place and
 * takes care of popup deletions. 
 * If a PopupDispatch is deleted it let's the next node to know about it so that
 * it will replace itself, and let the other next one about the change, and so on.
 * This means it's safe to delete any popup. They'll replace their selves. It's
 * even safe to delete popups when they're animating etc.
 */
class PopupDispatch : QObject
{
Q_OBJECT
public:
	//! Position of the panel (kicker)
	enum Position{ Left, Right, Top, Bottom };

	/**
	 * @param tti popup data (the widget pointer, type of popup, etc)
	 * @param last last popup displayed before this one. i.e. previous popup node
	 * @param m PopupManager which is creating this popup node
	 */
	PopupDispatch( const PopupInternal& tti, PopupDispatch* last, PopupManager* m );

	virtual ~PopupDispatch();

	/**
	 * Tries to decide a sane place for the popup.
	 * Currently it just puts the popup next to the previous one according to the
	 * task bar position. For instance, if the panel is at left, this popup
	 * will be placed right to the previous one. Or if the panel is at the bottom
	 * this popup will be placed on top of the previous one.
	 * TODO: Implement screen border check.
	 */
	void
	selfPlace();

	/**
	 * Animation updater
	 */
	virtual void
	timerEvent( QTimerEvent* );

	/**
	 * @param next set next popup node
	 */
	virtual void
	setNext( PopupDispatch* next );

	/**
	 * @param prev set previous popup node
	 */
	virtual void
	setPrev( PopupDispatch* prev );

	/**
	 * Returns the frame size of the widget
	 */
	QSize
	size() const;

	/**
	 * PopupDispatch installs itself as the event filter of the widget
	 * it's representing, so that it can catch clicks on the widget
	 * in case we want DieOnClick, or resize events.
	 */
	virtual bool
	eventFilter( QObject*, QEvent* );

	/**
	 * Sets origin (top left x,y) of the destination
	 */
	virtual void
	setOrigin( const QPoint& );

	/**
	 * Gives the origin of this popups final position.
	 * Whether this popup is in animation or not this will return
	 * the final destination point. Based opon frameGeometry
	 */
	QPoint
	origin() const;

	/**
	 * If a previous popup node is deleted this method is called.
	 * This method calls selfPlace() for itself and for the rest of
	 * the tailing popup nodes.
	 */
	virtual void
	updateChain();

	/**
	 * @return true if the animation is over.
	 */
	virtual bool
	settled() const;

	//! FIXME: create one singe Direction type from these
	int m_position;
protected slots:
	void destroy();
	void widgetDestroyed();
private:
	double m_x, m_y;
	PopupInternal m_popupData;
	PopupDispatch *m_previous, *m_next;
	PopupManager* m_manager;
	QPoint m_dst;
	QPoint m_src;
	bool m_settled;
	bool m_new;
	QSize m_size;
};

#endif
