#ifndef _MDI_H
#define _MDI_H

//$Id: mdi.h,v 1.4 1997/11/30 02:14:25 parallax Exp $

#include <qwidget.h>
#include <qevent.h>
#include <qframe.h>
#include <qlabel.h>
#include <qpushbt.h>
#include <qmenubar.h>
#include <qlist.h>
#include <qpixmap.h>

class MDIManager;


//MDILabel: so we can recieve mouse events (to move window)
class MDILabel: public QLabel
{
    Q_OBJECT
public:
    MDILabel(QWidget *parent=0, const char *name=0)
            : QLabel(parent, name) { }
    virtual ~MDILabel();
signals:
    void Moving ();
    void PopupMenu(QPoint);
protected:
    void mousePressEvent ( QMouseEvent *);
};


// MDIWindow is a basic window that can appear in an MDIManager
class MDIWindow : public QWidget
{
    Q_OBJECT
public:
    MDIWindow ( QWidget *parent=0, const char *name=0);
    virtual ~MDIWindow();
    bool IsMinimized () { return isMinimized; }
    bool IsMaximized () { return isMaximized; }
    bool IsSelected () { return isSelected; }
    void DrawRect ( QRect &rt, bool fancy=false ); //draws an xor resize/move rect
    QLabel *Caption();
public slots:
    void Minimize();
    void Maximize();
    void Restore();
    void Close(); // the PROPER way to close a window QWidget::close() should not be used
    void MoveTo ( int x, int y);
    void SetCaption ( const char * );
    void Select(bool restoreIfMinimized = true); // makes this window the currently selected one
    void Detach(); // makes the window global
    void Attach(); // reattaches the window to its parent
    void SetChild(QWidget *);
    QWidget *Child();
 signals: 
    void Minimized (MDIWindow *);
    void Maximized (MDIWindow *);
    void Restored (MDIWindow *);
    void Closed (MDIWindow *);
    void Selected(MDIWindow *); 
    void Moved( int x, int y);
    void Moved(MDIWindow *, int x, int y);
    void CaptionChanged(MDIWindow *, const char *);
protected:
    virtual void focusInEvent(QFocusEvent*);
    virtual void focusOutEvent(QFocusEvent*);
    virtual bool eventFilter ( QObject *, QEvent *);
    virtual void resizeEvent ( QResizeEvent *);
    virtual void mousePressEvent ( QMouseEvent *);
    virtual void mouseMoveEvent ( QMouseEvent *);
    virtual void mouseReleaseEvent ( QMouseEvent *);
    void LinkChildren(QWidget *);
    void DrawResizeAnimation(QRect &, QRect &);
    void DoResizing();
    void DoMove();
    QWidget *clientArea; // the only piece of geometry anybody should need to worry about
    int isInResizeArea ( int x, int y);
    QPoint ClipPoint (QPoint);
    QMenuBar *menu;
    QFrame *captionFrame;
    QFrame *outerFrame;
    MDILabel *caption;
    QPoint anchorPoint;
    QPoint popupPoint;
    int restoreX;
    int restoreY;
    int restoreWidth;
    int restoreHeight;
    // QRect resizeRect;
    bool eraseResizeRect;
    bool moving;
    int resizeMode;
    int corner;
    bool isMinimized;
    bool isMaximized;
    bool isSelected;
    bool isAttached;
    QWidget *oldParent;
    WFlags oldWFlags;
    QPixmap *attachPic;
    QPixmap *detachPic;
    QWidget *child;
private slots:
    void Moving();
};


// MDIManager manages a collection of MDIWindows, and provides for minimizing, maximizing,
// closing, resizing and moving these windows
class MDIManager : public QWidget
{
    Q_OBJECT
    friend class MDIWindow;
public:
    MDIManager ( QWidget* parent=0, const char *name = 0, const char *detachButton=0, \
                const char *attachButton=0, const char *minimizeButton=0, \
                const char *maximizeButton=0, const char *closeButton=0 );
    virtual ~MDIManager();
    MDIWindow *SelectedWindow() { return selectedWin; }
    QList<MDIWindow> *WindowList() { return windowList; }
signals:
    void WindowRemoved(MDIWindow *);
    void WindowAdded(MDIWindow *);
public slots:
    MDIWindow *GetWindowByName ( const char *name, bool caseSensitive = false );
    MDIWindow *GetWindowByIndex ( int index );
    int NumberOfWindows () { return numWindows; }
    void AddWindow ( MDIWindow * ); // adds a window to be managed
    void AddWindow (QWidget *, bool showIt = TRUE); 
    void RemoveWindow ( MDIWindow * ); // removes window from management. Does NOT close it
    void Tile (); // tiles the windows
    void Cascade (); // cascades the windows from the upper left corner
    void SetDefaultWindowSize ( int w, int h);
    void SetDefaultWindowPos ( int x, int y);
    void SetSmartPlacement(bool);
    void NextWindow(); // switches focus to the next window
    void PrevWindow(); // switches focus to the previous window
    bool SetWindowFocus(); // finds a window to give focus to, returns false if it can't
protected:
    bool IsPointTaken ( int x, int y); // true if point is not already occupied
    void PrintWindowList (); // for debugging purposes
    MDIWindow *selectedWin;
    int numWindows;
    int defaultWindowWidth;
    int defaultWindowHeight;
    int defaultWindowPosX;
    int defaultWindowPosY;
    bool smartPlacement;
    QList <MDIWindow> *windowList; // list of windows being managed
    static QString attachPic;
    static QString detachPic;
    static QString minimizePic;
    static QString maximizePic;
    static QString closePic;
 protected slots:
     void HandleWindowSelect ( MDIWindow *);
};



#endif
