/**
 * Wenn die Bibliothek zur Erweiterung der IDE eingebunden (`ide-lib.js`) wurde,
 * steht diese globale Variable mit Zugang zur öffentlichen Schnittstelle
 * zur Verfügung.
 */
declare const MC: MathCoach.Api;

/**
 * Der MathCoach-Namensraum ist die Sammelstelle für alle öffentlichen Schnittstellen.
 * Somit können auch externe Module (z.B. grafische Editoren) typsicher erstellt werden.
 * Als Einstiegspunkt dient das interface `MathCoach.Api` - eine Implementierung dieser Schnittstelle
 * wird von der IDE (siehe `ide-lib.js`) bereitgestellt und kann über die globale Variable 
 * `MC` zugegriffen werden. 
 */
declare namespace MathCoach {

    /**
     * Einstiegspunkt zur MathCoach API Schnittstelle 
     */
    interface Api {
        /**
         * Die Schnittstelle zur Entwicklungsumgebung (IDE) von MathCoach. 
         */
        readonly ide: IdeApi;

        /**
         * Prüft, ob die API einsatzbereit ist. Dies sollte einmalig, beim Start des Werkzeugs, 
         * geprüft werden. Dabei bedeutet der Rückgabewert `true`, dass das Werkzeug durch 
         * die IDE gestartet wurde und die Kommunikation möglich ist. `false` bedeutet, dass 
         * das Werkzeug nicht durch die IDE gestartet wurde. 
         * 
         * Somit wäre es möglich ein Tool offlinefähig zu machen, indem es ggf. eine eigene
         * Implementierung der MathCoach-API (beispielsweise unter Verwendung des LocalStorage 
         * zum Speichern von Dateien) verwendet. 
         * 
         * Anwendungsbeispiel (Prüft zusätzlich, ob die globale `MC`-Variable verfügbar ist - also
         * die `ide-lib.js` korrekt eingebunden und geladen wurde):
         *      
         *      let isReady = (typeof MC !== "undefined") ? await MC.isReady() : false;
         *      if(isReady){
         *          // MathCoach-API is ready to use!
         *      }else{
         *          // MathCoach-API is not ready...
         *      }
         *  
         * 
         */
        isReady(): Promise<boolean>;
    }


    /**
    * Schnittstelle zur IDE von MathCoach
    */
    interface IdeApi {
        /**
         * Name des aktuellen Benutzers.
         * 
         * Anwendungsbeisipiel:
         * 
         *      let user = await MC.ide.getUserName();
         * 
         */
        getUserName(): Promise<string>;
        /**
         * Verweis auf die Datei, mit der das Entwicklerwerkzeug gestartet wurde. 
         * 
         * Anwendungsbeispiel:
         * 
         *      let file = await MC.ide.getContextFile();
         *      let { owner, path, part } = file; 
         */
        getContextFile(): Promise<File>;
        /**
         * Schnittstelle zum Dateisystem
         */
        readonly fs: FileSystemApi;
        /**
         * Schnittstelle zur Vorschau
         */
        readonly navigator: NavigatorApi;
    }
    /**
     * Schnittstelle zur Navigations-Vorschau
     */
    interface NavigatorApi {
        /**
         * Navigiert die Vorschau zu einem Link.
         * 
         * Anwendungsbeispiel:
         * 
         *      await MC.ide.navigator.navigateTo("/mathcoach/www/yourName/readme.html", true)
         * 
         * 
         * @param link Web URL (z.B. zu einer Datei im WWW-Verzeichnis oder einer MathCoach-Aufgabe)
         * @param forceOpen `true` um das Anzeigen der Vorschau zu erzwingen, `false` um nur bei bereits geöffneter Vorschau zu navigieren.
         */
        navigateTo(link: string, forceOpen?: boolean): Promise<void>;

        /**
         * Navigiert die Vorschau zu einer MathCoach-Aufgabe.
         * Hinweis: Die Datei muss im `vfs`-Teil des Dateisystems liegen und
         * eine ausführbar sein (z.B. eine groovy-Datei).
         * 
         * Anwendungsbeispiel:
         *      
         *      let file = { part: "vfs", owner:"yourName", path: "/myExercise.groovy" }
         *      await MC.ide.navigator.navigateToExercise(file)
         * 
         * @param file Datei-Verweis
         */
        navigateToExercise(file: MathCoach.File, forceOpen?: boolean): Promise<void>
    }
    /**
     * Schnittstelle zum Dateisystem
     */
    interface FileSystemApi {
        /**
         * Liest eine Datei und gibt den Textinhalt zurück. 
         * 
         * Anwendungsbeispiel: Lesen der Datei, mit dem das Werkzeug gestartet wurde
         *      
         *      let file = await MC.ide.getContextFile();
         *      let text = await MC.ide.fs.readFile(file);
         *      // do something with the text, e.g. JSON.parse(text)
         * 
         * @param file Verweis auf die Datei
         */
        readFile(file: File): Promise<string>;
        /**
         * Schreibt Text in eine Datei. 
         * 
         * Anwendungsbeispiel: Schreiben der Datei, mit dem das Werkzeug gestartet wurde
         *      
         *      let file = await MC.ide.getContextFile(); // some file reference
         *      let text = "some text"; // or JSON.stringify(yourDataContainer)
         *      await MC.ide.fs.writeFile(file,text); 
         * 
         * @param file Verweis auf die Datei
         * @param text Der neue Inhalt der Datei
         */
        writeFile(file: File, text: string): Promise<void>;
    }
    /**
     * Eindeutiger Verweis auf eine Datei. 
     * 
     * Anwendungsbeispiel:
     * 
     *      let user = await MC.ide.getUserName(); // oder von einem anderen File-Objekt abgfragen...
     *      let file = { owner: user, part: "vfs", path:"/myExercise.groovy" }
     * 
     * Siehe auch: `MC.ide.getContextFile()`
     * 
     */
    interface File {
        /**
         * Name des Besitzers. Hinweis: Der Besitzter kann vom angemeldeten
         * Benutzer abweichen (z.B. wenn das Teilen von Inhalten zukünftig unterstützt wird)
         */
        owner: string;
        /**
         * Liegt die Datei im öffentlichen (www) oder verborgenen (vfs) Dateisystem?
         */
        part: "vfs" | "www";
        /**
         * Absoluter Pfad zur Datei. Mmuss immer mit einem Slash beginnen.
         */
        path: string;
    }
}