/*
 * QT Client for X2GoKDrive
 * Copyright (C) 2018-2023 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de>
 * Copyright (C) 2018-2023 phoca-GmbH
 *
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 *
 */
#ifndef EXTWIN_H
#define EXTWIN_H

#include <QMainWindow>
#ifdef Q_OS_LINUX
#include <QX11Info>
#include <xcb/xproto.h>
#endif

#include "client.h"

class DisplayArea;
class Client;
class ExtWin : public QMainWindow
{
    Q_OBJECT
public:
    enum {MOD_NONE,MOD_SINGLE, MOD_GROUP};
    ExtWin(uint32_t extWinId, Client *client, QWidget* parent, uint8_t wt, Qt::WindowFlags flags = Qt::WindowFlags());
    uint32_t getPtr(){return extWinId;}
    void setWinSize(int w, int h);
    void setParentId(uint32_t id){parentId=id;}
    void setTransWinId(uint32_t id){transWinId=id;}
    void setNextSibId(uint32_t id){nextSibId=id;}
    uint8_t getWindowType(){return windowType;}
    void setWindowType(uint8_t tp){windowType=tp;}
    uint64_t getParentId(){return parentId;}
    uint64_t getNextSibId(){return nextSibId;}
    uint64_t getExtWinId(){return extWinId;}
    uint32_t getTransWinId(){return transWinId;}
    DisplayArea* getDisplayArea(){return displayArea;}
    void setModality(int mod){modality=mod;}
    QPoint virtualToKdrivePosition(QPoint virtPos);
    QPoint kdriveToVirtualPosition(QPoint kdrPos);
    void setHasFocus( bool f){focus=f;}
    uint8_t getHasFocus(){return focus;}
    void moveWinFromServer(QPoint pos);

private:
#ifdef Q_OS_LINUX
    ExtWin* findWinByTopWinId(xcb_window_t topWinId, QList<ExtWin*> &siblings);
#endif
#ifdef Q_OS_WIN
    ExtWin* findWinByHWND(HWND hwnd, QList<ExtWin*> &siblings);
#endif
    ExtWin* findWinByZInd(int zInd, QList<ExtWin*> &siblings);
    bool checkModality(QList<ExtWin*> &siblings);
    DisplayArea* displayArea;
    Client* client;
    uint32_t extWinId;
    uint32_t parentId=0;
    uint32_t nextSibId=0;
    uint32_t transWinId=0;
    uint8_t windowType=WINDOW_TYPE_NORMAL;
#ifdef Q_OS_LINUX
    xcb_window_t topWinId=0;
#endif
    int zOrderInd;
    int modality=MOD_NONE;
    bool focus=0;
    bool ignoreGeometryChangeEvent=false;
    bool isChanging=false;
    QTimer* changeTimer;

private slots:
    void slotChangeWin();
    void slotCheckStackOrder();
#ifdef Q_OS_WIN
    void slotSetTaskbar();
    void slotSetWinWindow();
    void slotRestoreWin();
#endif
protected:
    void closeEvent(QCloseEvent*);
    void resizeEvent(QResizeEvent*);
    void moveEvent(QMoveEvent*);
    void showEvent(QShowEvent *event);
    void hideEvent(QHideEvent *event);
    void focusInEvent(QFocusEvent *event);
    void focusOutEvent(QFocusEvent *event);
    bool nativeEvent(const QByteArray &eventType, void *message, long *result);
};
#endif //EXTWIN_H
