/**
 * UGENE - Integrated Bioinformatics Tools.
 * Copyright (C) 2008-2023 UniPro <ugene@unipro.ru>
 * http://ugene.net
 *
 * 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.
 *
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 */

#pragma once

#include <QObject>

#include "global.h"

namespace U2 {

template<class T>
class IdRegistry;
class AlignmentAlgorithmsRegistry;
class AnnotationSettingsRegistry;
class AppFileStorage;
class AppGlobalObject;
class AppSettings;
class AppSettingsGUI;
class AssemblyConsensusAlgorithmRegistry;
class AutoAnnotationsSupport;
class CDSearchFactoryRegistry;
class CMDLineRegistry;
class ConvertFactoryRegistry;
class CredentialsAsker;
class DBXRefRegistry;
class DNAAlphabetRegistry;
class DNATranslationRegistry;
class DashboardInfoRegistry;
class DataBaseRegistry;
class DnaAssemblyAlgRegistry;
class DocumentFormatRegistry;
class ExternalToolRegistry;
class GObjectViewFactoryRegistry;
class GenomeAssemblyAlgRegistry;
class IOAdapterRegistry;
class MSAConsensusAlgorithmRegistry;
class MSADistanceAlgorithmRegistry;
class MainWindow;
class MolecularSurfaceFactoryRegistry;
class MsaColorSchemeRegistry;
class MsaHighlightingSchemeRegistry;
class OPCommonWidgetFactoryRegistry;
class OPWidgetFactoryRegistry;
class PWMConversionAlgorithmRegistry;
class PasswordStorage;
class PasteFactory;
class PhyTreeGeneratorRegistry;
class PluginSupport;
class PluginViewer;
class Project;
class ProjectFilterTaskRegistry;
class ProjectLoader;
class ProjectService;
class ProjectView;
class ProtocolInfoRegistry;
class QDActorPrototypeRegistry;
class RecentlyDownloadedCache;
class RemoteMachineMonitor;
class RepeatFinderTaskFactoryRegistry;
class ResourceTracker;
class SWMulAlignResultNamesTagsRegistry;
class SWResultFilterRegistry;
class ScriptingToolRegistry;
class SecStructPredictAlgRegistry;
class ServiceRegistry;
class Settings;
class SmithWatermanTaskFactoryRegistry;
class SplicedAlignmentTaskRegistry;
class StructuralAlignmentAlgorithmRegistry;
class SubstMatrixRegistry;
class TaskScheduler;
class TmCalculatorRegistry;
class TestFramework;
class U2DataPathRegistry;
class U2DbiRegistry;
class UGUITestBase;
class UdrSchemaRegistry;
class VirtualFileSystemRegistry;
class WelcomePageAction;
class WorkflowScriptRegistry;

class U2CORE_EXPORT AppContext : public QObject {
    Q_OBJECT
public:
    static PluginSupport* getPluginSupport() {
        return getInstance()->_getPluginSupport();
    }

    static ServiceRegistry* getServiceRegistry() {
        return getInstance()->_getServiceRegistry();
    }

    static ProjectLoader* getProjectLoader() {
        return getInstance()->_getProjectLoader();
    }

    static Project* getProject() {
        return getInstance()->_getProject();
    }

    static ProjectService* getProjectService() {
        return getInstance()->_getProjectService();
    }

    static PluginViewer* getPluginViewer() {
        return getInstance()->_getPluginViewer();
    }

    /** admin level, readonly settings*/
    static const Settings* getGlobalSettings() {
        return getInstance()->_getGlobalSettings();
    }

    /** per-user settings*/
    static Settings* getSettings() {
        return getInstance()->_getSettings();
    }

    /** structured and preloaded settings */
    static AppSettings* getAppSettings() {
        return getInstance()->_getAppSettings();
    }

    /** GUI for structured and preloaded settings */
    static AppSettingsGUI* getAppSettingsGUI() {
        return getInstance()->_getAppSettingsGUI();
    }

    static MainWindow* getMainWindow() {
        return getInstance()->_getMainWindow();
    }

    static ProjectView* getProjectView() {
        return getInstance()->_getProjectView();
    }

    static DocumentFormatRegistry* getDocumentFormatRegistry() {
        return getInstance()->_getDocumentFormatRegistry();
    }

    static IOAdapterRegistry* getIOAdapterRegistry() {
        return getInstance()->_getIOAdapterRegistry();
    }

    static DNATranslationRegistry* getDNATranslationRegistry() {
        return getInstance()->_getDNATranslationRegistry();
    }

    static DNAAlphabetRegistry* getDNAAlphabetRegistry() {
        return getInstance()->_getDNAAlphabetRegistry();
    }

    static GObjectViewFactoryRegistry* getObjectViewFactoryRegistry() {
        return getInstance()->_getObjectViewFactoryRegistry();
    }

    static TaskScheduler* getTaskScheduler() {
        return getInstance()->_getTaskScheduler();
    }

    static ResourceTracker* getResourceTracker() {
        return getInstance()->_getResourceTracker();
    }

    static AnnotationSettingsRegistry* getAnnotationsSettingsRegistry() {
        return getInstance()->_getAnnotationsSettingsRegistry();
    }

    static TestFramework* getTestFramework() {
        return getInstance()->_getTestFramework();
    }

    static DBXRefRegistry* getDBXRefRegistry() {
        return getInstance()->_getDBXRefRegistry();
    }

    static SubstMatrixRegistry* getSubstMatrixRegistry() {
        return getInstance()->_getSubstMatrixRegistry();
    }

    static SmithWatermanTaskFactoryRegistry* getSmithWatermanTaskFactoryRegistry() {
        return getInstance()->_getSmithWatermanTaskFactoryRegistry();
    }

    static SWMulAlignResultNamesTagsRegistry* getSWMulAlignResultNamesTagsRegistry() {
        return getInstance()->_getSWMulAlignResultNamesTagsRegistry();
    }

    static MolecularSurfaceFactoryRegistry* getMolecularSurfaceFactoryRegistry() {
        return getInstance()->_getMolecularSurfaceFactoryRegistry();
    }

    static SWResultFilterRegistry* getSWResultFilterRegistry() {
        return getInstance()->_getSWResultFilterRegistry();
    }

    static MsaColorSchemeRegistry* getMsaColorSchemeRegistry() {
        return getInstance()->_getMsaColorSchemeRegistry();
    }

    static MsaHighlightingSchemeRegistry* getMsaHighlightingSchemeRegistry() {
        return getInstance()->_getMsaHighlightingSchemeRegistry();
    }

    static SecStructPredictAlgRegistry* getSecStructPredictAlgRegistry() {
        return getInstance()->_getSecStructPredictAlgRegistry();
    }

    static RecentlyDownloadedCache* getRecentlyDownloadedCache() {
        return getInstance()->_getRecentlyDownloadedCache();
    }

    static ProtocolInfoRegistry* getProtocolInfoRegistry() {
        return getInstance()->_getProtocolInfoRegistry();
    }

    static RemoteMachineMonitor* getRemoteMachineMonitor() {
        return getInstance()->_getRemoteMachineMonitor();
    }

    static PhyTreeGeneratorRegistry* getPhyTreeGeneratorRegistry() {
        return getInstance()->_getPhyTreeGeneratorRegistry();
    }

    static CMDLineRegistry* getCMDLineRegistry() {
        return getInstance()->_getCMDLineRegistry();
    }

    static MSAConsensusAlgorithmRegistry* getMSAConsensusAlgorithmRegistry() {
        return getInstance()->_getMSAConsensusAlgorithmRegistry();
    }

    static MSADistanceAlgorithmRegistry* getMSADistanceAlgorithmRegistry() {
        return getInstance()->_getMSADistanceAlgorithmRegistry();
    }

    static AssemblyConsensusAlgorithmRegistry* getAssemblyConsensusAlgorithmRegistry() {
        return getInstance()->_getAssemblyConsensusAlgorithmRegistry();
    }

    static PWMConversionAlgorithmRegistry* getPWMConversionAlgorithmRegistry() {
        return getInstance()->_getPWMConversionAlgorithmRegistry();
    }

    static VirtualFileSystemRegistry* getVirtualFileSystemRegistry() {
        return getInstance()->_getVirtualFileSystemRegistry();
    }

    static DnaAssemblyAlgRegistry* getDnaAssemblyAlgRegistry() {
        return getInstance()->_getDnaAssemblyAlgRegistry();
    }

    static GenomeAssemblyAlgRegistry* getGenomeAssemblyAlgRegistry() {
        return getInstance()->_getGenomeAssemblyAlgRegistry();
    }

    static RepeatFinderTaskFactoryRegistry* getRepeatFinderTaskFactoryRegistry() {
        return getInstance()->_getRepeatFinderTaskFactoryRegistry();
    }

    static AutoAnnotationsSupport* getAutoAnnotationsSupport() {
        return getInstance()->_getAutoAnnotationsSupport();
    }

    static CDSearchFactoryRegistry* getCDSFactoryRegistry() {
        return getInstance()->_getCDSFactoryRegistry();
    }

    /** Registers application global resource */
    static void registerGlobalObject(AppGlobalObject* obj) {
        return getInstance()->_registerGlobalObject(obj);
    }

    /** Unregisters application global resource */
    static void unregisterGlobalObject(const QString& id) {
        return getInstance()->_unregisterGlobalObject(id);
    }

    /** Finds application global resource */
    static AppGlobalObject* getGlobalObjectById(const QString& id) {
        return getInstance()->_getGlobalObjectById(id);
    }

    static DataBaseRegistry* getDataBaseRegistry() {
        return getInstance()->_getDataBaseRegistry();
    }

    static ExternalToolRegistry* getExternalToolRegistry() {
        return getInstance()->_getExternalToolRegistry();
    }

    static QDActorPrototypeRegistry* getQDActorProtoRegistry() {
        return getInstance()->_getQDActorFactoryRegistry();
    }

    static StructuralAlignmentAlgorithmRegistry* getStructuralAlignmentAlgorithmRegistry() {
        return getInstance()->_getStructuralAlignmentAlgorithmRegistry();
    }

    static SplicedAlignmentTaskRegistry* getSplicedAlignmentTaskRegistry() {
        return getInstance()->_getSplicedAlignmentTaskRegistry();
    }

    static OPCommonWidgetFactoryRegistry* getOPCommonWidgetFactoryRegistry() {
        return getInstance()->_getOPCommonWidgetFactoryRegistry();
    }

    static OPWidgetFactoryRegistry* getOPWidgetFactoryRegistry() {
        return getInstance()->_getOPWidgetFactoryRegistry();
    }

    static U2DbiRegistry* getDbiRegistry() {
        return getInstance()->_getDbiRegistry();
    }

    static UdrSchemaRegistry* getUdrSchemaRegistry() {
        return getInstance()->_getUdrSchemaRegistry();
    }

    static U2DataPathRegistry* getDataPathRegistry() {
        return getInstance()->_getDataPathRegistry();
    }

    static bool isGUIMode() {
        return getInstance()->_isGUIMode();
    }

    static WorkflowScriptRegistry* getWorkflowScriptRegistry() {
        return getInstance()->_getWorkflowScriptRegistry();
    }

    static QString getActiveWindowName() {
        return getInstance()->_getActiveWindowName();
    }
    static void setActiveWindowName(const QString& name) {
        getInstance()->_setActiveWindowName(name);
    }

    static AppFileStorage* getAppFileStorage() {
        return getInstance()->_getAppFileStorage();
    }

    static AlignmentAlgorithmsRegistry* getAlignmentAlgorithmsRegistry() {
        return getInstance()->_getAlignmentAlgorithmsRegistry();
    }

    static ScriptingToolRegistry* getScriptingToolRegistry() {
        return getInstance()->_getScriptingToolRegistry();
    }

    static ConvertFactoryRegistry* getConvertFactoryRegistry() {
        return getInstance()->_getConvertFactoryRegistry();
    }

    static IdRegistry<WelcomePageAction>* getWelcomePageActionRegistry() {
        return getInstance()->_getWelcomePageActionRegistry();
    }

    static QString getWorkingDirectoryPath() {
        return getInstance()->_getWorkingDirectoryPath();
    }

    static CredentialsAsker* getCredentialsAsker() {
        return getInstance()->_getCredentialsAsker();
    }

    static PasswordStorage* getPasswordStorage() {
        return getInstance()->_getPasswordStorage();
    }

    static ProjectFilterTaskRegistry* getProjectFilterTaskRegistry() {
        return getInstance()->_getProjectFilterTaskRegistry();
    }

    static PasteFactory* getPasteFactory() {
        return getInstance()->_getPasteFactory();
    }

    static DashboardInfoRegistry* getDashboardInfoRegistry() {
        return getInstance()->_getDashboardInfoRegistry();
    }

    static TmCalculatorRegistry* getTmCalculatorRegistry() {
        return getInstance()->_getTmCalculatorRegistry();
    }

protected:
    static AppContext* getInstance() {
        assert(instance);
        return instance;
    }

    virtual PluginSupport* _getPluginSupport() const = 0;
    virtual ServiceRegistry* _getServiceRegistry() const = 0;
    virtual ProjectLoader* _getProjectLoader() const = 0;
    virtual Project* _getProject() const = 0;
    virtual ProjectService* _getProjectService() const = 0;
    virtual PluginViewer* _getPluginViewer() const = 0;
    virtual Settings* _getSettings() const = 0;
    virtual Settings* _getGlobalSettings() const = 0;
    virtual MainWindow* _getMainWindow() const = 0;
    virtual ProjectView* _getProjectView() const = 0;
    virtual DocumentFormatRegistry* _getDocumentFormatRegistry() const = 0;
    virtual IOAdapterRegistry* _getIOAdapterRegistry() const = 0;
    virtual DNATranslationRegistry* _getDNATranslationRegistry() const = 0;
    virtual DNAAlphabetRegistry* _getDNAAlphabetRegistry() const = 0;
    virtual GObjectViewFactoryRegistry* _getObjectViewFactoryRegistry() const = 0;
    virtual TaskScheduler* _getTaskScheduler() const = 0;
    virtual ResourceTracker* _getResourceTracker() const = 0;
    virtual AnnotationSettingsRegistry* _getAnnotationsSettingsRegistry() const = 0;
    virtual AppSettings* _getAppSettings() const = 0;
    virtual AppSettingsGUI* _getAppSettingsGUI() const = 0;
    virtual TestFramework* _getTestFramework() const = 0;
    virtual DBXRefRegistry* _getDBXRefRegistry() const = 0;
    virtual SubstMatrixRegistry* _getSubstMatrixRegistry() const = 0;
    virtual SmithWatermanTaskFactoryRegistry* _getSmithWatermanTaskFactoryRegistry() const = 0;
    virtual MolecularSurfaceFactoryRegistry* _getMolecularSurfaceFactoryRegistry() const = 0;
    virtual SWMulAlignResultNamesTagsRegistry* _getSWMulAlignResultNamesTagsRegistry() const = 0;
    virtual SWResultFilterRegistry* _getSWResultFilterRegistry() const = 0;
    virtual MsaColorSchemeRegistry* _getMsaColorSchemeRegistry() const = 0;
    virtual MsaHighlightingSchemeRegistry* _getMsaHighlightingSchemeRegistry() const = 0;
    virtual SecStructPredictAlgRegistry* _getSecStructPredictAlgRegistry() const = 0;
    virtual RecentlyDownloadedCache* _getRecentlyDownloadedCache() const = 0;
    virtual ProtocolInfoRegistry* _getProtocolInfoRegistry() const = 0;
    virtual RemoteMachineMonitor* _getRemoteMachineMonitor() const = 0;
    virtual PhyTreeGeneratorRegistry* _getPhyTreeGeneratorRegistry() const = 0;
    virtual CMDLineRegistry* _getCMDLineRegistry() const = 0;
    virtual MSAConsensusAlgorithmRegistry* _getMSAConsensusAlgorithmRegistry() const = 0;
    virtual MSADistanceAlgorithmRegistry* _getMSADistanceAlgorithmRegistry() const = 0;
    virtual AssemblyConsensusAlgorithmRegistry* _getAssemblyConsensusAlgorithmRegistry() const = 0;
    virtual PWMConversionAlgorithmRegistry* _getPWMConversionAlgorithmRegistry() const = 0;
    virtual VirtualFileSystemRegistry* _getVirtualFileSystemRegistry() const = 0;
    virtual DnaAssemblyAlgRegistry* _getDnaAssemblyAlgRegistry() const = 0;
    virtual GenomeAssemblyAlgRegistry* _getGenomeAssemblyAlgRegistry() const = 0;
    virtual DataBaseRegistry* _getDataBaseRegistry() const = 0;
    virtual ExternalToolRegistry* _getExternalToolRegistry() const = 0;
    virtual RepeatFinderTaskFactoryRegistry* _getRepeatFinderTaskFactoryRegistry() const = 0;
    virtual QDActorPrototypeRegistry* _getQDActorFactoryRegistry() const = 0;
    virtual StructuralAlignmentAlgorithmRegistry* _getStructuralAlignmentAlgorithmRegistry() const = 0;
    virtual AutoAnnotationsSupport* _getAutoAnnotationsSupport() const = 0;
    virtual U2DbiRegistry* _getDbiRegistry() const = 0;
    virtual UdrSchemaRegistry* _getUdrSchemaRegistry() const = 0;
    virtual CDSearchFactoryRegistry* _getCDSFactoryRegistry() const = 0;
    virtual SplicedAlignmentTaskRegistry* _getSplicedAlignmentTaskRegistry() const = 0;
    virtual OPCommonWidgetFactoryRegistry* _getOPCommonWidgetFactoryRegistry() const = 0;
    virtual OPWidgetFactoryRegistry* _getOPWidgetFactoryRegistry() const = 0;
    virtual WorkflowScriptRegistry* _getWorkflowScriptRegistry() const = 0;
    virtual AppFileStorage* _getAppFileStorage() const = 0;
    virtual AlignmentAlgorithmsRegistry* _getAlignmentAlgorithmsRegistry() const = 0;
    virtual U2DataPathRegistry* _getDataPathRegistry() const = 0;
    virtual ScriptingToolRegistry* _getScriptingToolRegistry() const = 0;
    virtual CredentialsAsker* _getCredentialsAsker() const = 0;
    virtual PasswordStorage* _getPasswordStorage() const = 0;
    virtual ConvertFactoryRegistry* _getConvertFactoryRegistry() const = 0;
    virtual IdRegistry<WelcomePageAction>* _getWelcomePageActionRegistry() const = 0;
    virtual ProjectFilterTaskRegistry* _getProjectFilterTaskRegistry() const = 0;
    virtual PasteFactory* _getPasteFactory() const = 0;
    virtual DashboardInfoRegistry* _getDashboardInfoRegistry() const = 0;
    virtual TmCalculatorRegistry* _getTmCalculatorRegistry() const = 0;

    virtual void _registerGlobalObject(AppGlobalObject* go) = 0;
    virtual void _unregisterGlobalObject(const QString& id) = 0;
    virtual AppGlobalObject* _getGlobalObjectById(const QString& id) const = 0;
    virtual bool _isGUIMode() const = 0;
    virtual QString _getActiveWindowName() const = 0;
    virtual void _setActiveWindowName(const QString& name) = 0;
    virtual QString _getWorkingDirectoryPath() const = 0;

    static AppContext* instance;
};

}  // namespace U2
