/**
 * Copyright (C) 2023-2026 Linaro Limited (or its affiliates). All rights reserved.
 * Copyright (C) 2012-2023 Arm Limited (or its affiliates).
 * All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */

#ifndef REMOTEFILEDIALOG_H
#define REMOTEFILEDIALOG_H

#include "lgpl_gui_export.h"

#include <QFileDialog>
#include <QSortFilterProxyModel>
#include "remotefiledialog/remotefiledialogbase.h"

class QAbstractFileEngineHandler;
class QAbstractFileEngine;
class QComboBox;
class QListView;
class Portal;

class LGPL_GUI_EXPORT RemoteFileDialog : public RemoteFileDialogBase
{
    Q_OBJECT

    Q_PROPERTY(FileSystemLocation location READ location WRITE setLocation DESIGNABLE true SCRIPTABLE true STORED true)
public:
    enum FileSystemLocation { Local, Remote, LocalRemote };

    RemoteFileDialog(QWidget * parent, Qt::WindowFlags flags);
    RemoteFileDialog(QWidget * parent = 0, const QString & caption = QString(), const QString & directory = QString(), const QString & filter = QString(), FileSystemLocation location = Remote);
    virtual ~RemoteFileDialog();

    static RemoteFileDialog *instance();

    void setLocation(FileSystemLocation location);
    FileSystemLocation location() const;

    QStringList selectedFiles() const;
    QString selectedFile() const;

    QDir directory() const;
    QStringList history() const;
    void selectFile(const QString & filename);
    void setDirectory(const QString & directory);
    void setDirectory(const QDir & directory);
    void setHistory(const QStringList & paths);
    void setSidebarUrls(const QList<QUrl> & urls);
    QList<QUrl> sidebarUrls() const;

    static QString getSaveFileName(QWidget *parent = 0,
                                   const QString &caption = QString(),
                                   const QString &dir = QString(),
                                   const QString &filter = QString(),
                                   QString *selectedFilter = 0,
                                   QFileDialog::Options options = QFileDialog::Options(),
                                   FileSystemLocation location = Remote);

    static QString getOpenFileName(QWidget *parent = 0,
                                   const QString &caption = QString(),
                                   const QString &dir = QString(),
                                   const QString &filter = QString(),
                                   QString *selectedFilter = 0,
                                   QFileDialog::Options options = QFileDialog::Options(),
                                   FileSystemLocation location = Remote);

    static QStringList getOpenFileNames(QWidget *parent = 0,
                                   const QString &caption = QString(),
                                   const QString &dir = QString(),
                                   const QString &filter = QString(),
                                   QString *selectedFilter = 0,
                                   QFileDialog::Options options = QFileDialog::Options(),
                                   FileSystemLocation location = Remote);

    static QString getExistingDirectory(QWidget * parent = 0,
                                        const QString & caption = QString(),
                                        const QString & dir = QString(),
                                        QFileDialog::Options options = QFileDialog::ShowDirsOnly,
                                        FileSystemLocation location = Remote);

    QString mungePath(const QString& path) const;
    QString unmungePath(const QString& path) const;
    QStringList unmungePaths(const QStringList& paths) const;
    bool isRemotePath(const QString& path) const;

    static void setDefaultWorkingDirectory(const QString& directory);
    static QString defaultWorkingDirectory();
    static void setRemoteHomeDirectory(const QString& directory);
    static QString remoteHomeDirectory();
    static void setRemotePrefix(const QString& prefix);
    static QString remotePrefix();
    typedef void (*Hook)(RemoteFileDialog *);
    static void setHook(Hook hook);
    static Hook hook();

signals:
    void aboutToBeDestroyed();

protected:
    virtual QString tildeExpansion(const QString &path, bool *expanded = 0) const override;
    virtual QString getEnvironmentVariable(const QString &string) const override;
    virtual QStringList typedFiles() const override;

private slots:
    void delayedCheckDirectory();
    void checkDirectory();

private:
    void init();
    void checkDirectory(const QString& path);
    bool isLocalPath(const QString& path) const;

    FileSystemLocation mLocation;
    QComboBox *mLookInComboBox;
    QDir mOldDirectory;
    QList<QUrl> mOldSidebarUrls;
    QStringList mOldHistory;
    static RemoteFileDialog *mInstance;
    bool mBusy;
};

class LGPL_GUI_EXPORT RemoteProxyModel : public QSortFilterProxyModel
{
public:
    RemoteProxyModel(QObject * parent = 0);
    virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override;
    virtual bool lessThan ( const QModelIndex & left, const QModelIndex & right ) const override;
    void setLocation(RemoteFileDialog::FileSystemLocation location);
    RemoteFileDialog::FileSystemLocation location() const;
private:
    RemoteFileDialog::FileSystemLocation mLocation;
};

#endif // REMOTEFILEDIALOG_H
