@startuml

namespace MellowPlayer.Main {
    class Program {
        + main(): int
        + onInitialized()
        + onStarted()

    }
    Program --> MellowPlayer.Infrastructure.IApplication
    Program --> MellowPlayer.Presentation.IMainWindow
    Program --> MellowPlayer.Presentation.IMprisPlayer
    Program -up-> MellowPlayer.Domain.IPlayers
}

namespace MellowPlayer.Domain {
    interface IPlayers #PaleGreen
}

namespace MellowPlayer.Infrastructure {
    interface IApplication #PaleGreen {
        initialized: signal<void>
        started: signal<bool>
        initialize()
        run()
        quit()
        restart()
    }

    class ApplicationDecorator #PaleGreen {
        + initialized: signal<void>
        + started: signal<bool>
        # _application: IApplication
        + initialize()
        + run()
        + quit()
        + restart()
    }

    IApplication <|.. ApplicationDecorator

    class SingleInstance #PaleGreen {
        + initialize()
        + run()
    }
    ApplicationDecorator <|-- SingleInstance

    class WithCommandLineArguments #PaleGreen {
        + run()
    }
    ApplicationDecorator <|-- WithCommandLineArguments

    class WithLogging #PaleGreen {

    }
    ApplicationDecorator <|-- WithLogging

        interface IQtApplication #PaleGreen {
            setApplicationName(QString value)
            setApplicationDisplayName(QString value)
            setApplicationVersion(QString value)
            setOrganizationDomain(QString value)
            setOrganizationName(QString value)
            setWindowIcon(const QIcon& icon)
            exec()
            exit(int returnCode)
            installTranslator(QTranslator* translator)
            setFont(const QFont& font)
            --signals--
            aboutToQuit
            commitDataRequest
        }
        class QtApplication #PaleGreen {
        }
        IQtApplication <|- QtApplication
}

namespace MellowPlayer.Presentation {
    class Application #PaleGreen {
        + quitRequested: signal<void>
        + requestQuit()
        --
        + initialize()
        + run()
        + quit()
        + restart()
    }
    MellowPlayer.Infrastructure.IApplication <|.. Application
    QmlSingleton <|- Application
    Application -> MellowPlayer.Infrastructure.IQtApplication

    interface IQmlApplicationEngine #PaleGreen {
        setContextProperty(QString, QObject*)
        addImportPath(QString)
        load(QUrl)
    }
    class QmlApplicationEngine #PaleGreen {
        - _qQmlApplicationEngine: QQmlApplicationEngine
        + setContextProperty(QString, QObject*)
        + addImportPath(QString)
        + load(QUrl)
    }
    IQmlApplicationEngine <|.. QmlApplicationEngine

    interface IQmlSingleton #PaleGreen {
        void initialize(IQmlApplicationEngine&)
    }

    class QmlSingleton #PaleGreen {
        - name: QString
        - propertyObject: QObject*
        void initialize(IQmlApplicationEngine&)
    }
    IQmlSingleton <|.. QmlSingleton
    QmlSingleton .up.> IQmlSingletons

    interface IQmlSingletons #PaleGreen {
        add(IQmlSingleton)
    }

    class ContextProperties #PaleGreen {
        + add(IQmlSingleton)
    }
    IQmlSingletons <|.. ContextProperties
    ContextProperties --> IQmlApplicationEngine

    interface IMainWindow #PaleGreen {
        load()
        show()
        hide()
    }

    class MainWindow #PaleGreen {
        + load()
        + show()
        + hide()
    }
    IMainWindow <|.up.. MainWindow
    QmlSingleton <|-- MainWindow

    interface IMprisPlayer {
        start()
    }
    class MprisPlayer {
        + start()
    }
    IMprisPlayer <|-- MprisPlayer

    class NullMprisPlayer {
        + start()
    }
    IMprisPlayer <|-- NullMprisPlayer
}

@enduml
