import * as contextMenus from './extensions/EditorContextMenuProvider.js'
import {XGEEPublicAPI, XGEEPrivateAPI} from './lib/libapi.js'
import * as mxGraphIntegration from './graph/mxGraphIntegration.js' //sets global mxGraph variables and overwrites mxGraph functions

import GraphViewMenu from './view/GraphViewMenu.js'


import { serialPromise } from './lib/libaux.js'
//Editor main plugin 

export async function init(pluginAPI) {      
    
    
    var contextMenu=pluginAPI.require('contextMenu');
    var keyHandler=pluginAPI.require('keyHandler');
    var eventBroker=pluginAPI.require('eventBroker');
    var editorResourceSet = Ecore.ResourceSet.create();
    
    //Read meta model
    try{
        let xmlResources=await pluginAPI.loadXMLResources(["model/editorModel.ecore"]) 
        var metaModel=xmlResources[0];             
        var metaModelResource = editorResourceSet.create({ uri: 'EditorModels' });             
        metaModelResource.parse(metaModel.txt,Ecore.XMI); 
        Ecore.EPackage.Registry.register(metaModelResource.get("contents").array()[0])
    }
    catch(e)
    {
        throw 'XGEE meta-model initialization failed: '+e
    }    

   

    // Initialize API
    var privateAPI=new XGEEPrivateAPI(pluginAPI);
    privateAPI.setResourceSet(editorResourceSet);
    privateAPI.setMetaModel(metaModel);
    privateAPI.setApplication(pluginAPI.getGlobal('app'));

    var publicAPI=new XGEEPublicAPI();

    //Compatibility hack (TODO: remove these global functions)
    window["serialPromise"]=serialPromise

  
    let stylesSheets=await pluginAPI.loadStylesheets(["css/loading.css", "css/xgeeJsaIntegration.css"]);



        var editorRegistry=[]; 
        var editorContextMenuRegistry=[];
    
        var editorModels=pluginAPI.provide('xgee.models',null,function(event){
                ///register editor
                 privateAPI.registerEditorFromModelPath(event.extension.modelPath);
        });
        


        //automatically provide edit entries for editable objects
        class EditorGenericMenuProvider extends pluginAPI.getInterface('ecoreTreeView.menus'){
            constructor(){
                super();
            }

            isApplicableToNode(node)
            {
                return publicAPI.canOpen(node.data.eObject);
            }

            getContextMenu(node)
            {
                var cMenu=false;
                if(publicAPI.canOpen(node.data.eObject))
                {
                    
                    cMenu=contextMenu.createContextMenu('xgee-context-menu','XGEE Context Menu',100);
                    var editors=publicAPI.getEditors(node.data.eObject);

                    if(editors.length==1)
                    {
                        cMenu.addNewEntry('xgee-edit','Edit',function(){
                            publicAPI.open(node.data.eObject,true);
                        },'edit')
                    } else if(editors.length>1)
                    {
                        var editMenu=contextMenu.createContextMenu('xgee-edit-with-submenu','Edit with...',100,'edit');
                        editors.forEach(function(editor,i){
                            editMenu.addNewEntry('xgee-edit-'+i,editor.get('name'),function(){
                                publicAPI.open(node.data.eObject,true,i);
                            },'edit')
                        });
                        cMenu.addSubMenu('xgee-edit-with',editMenu);    
                    }
                }
                return cMenu;
            }

        }
        pluginAPI.implement('ecoreTreeView.menus',new EditorGenericMenuProvider());
            
        
        
  

        // XGEE context menu extension point
        var menuProviders=[];
        menuProviders.push(new GraphViewMenu(contextMenu)) //Built-In XGEE Menu Entries
        pluginAPI.provide('editor.menus',contextMenus.EditorContextMenuProvider,function(event){
           menuProviders.push(event.extension);
        });
        

        //the eventBroker may need some sort of permissions for events in order to allow this kind of architecture?
        eventBroker.subscribe('XGEE/CONTEXTMENU',function(evt){
            var applicableMenuProviders=menuProviders.filter(function(p){
                return p.isApplicableToTarget(evt.data.target);
            });
            if(applicableMenuProviders.length > 0)
            {
                contextMenu.showContextMenu({x:evt.data.event.pageX,y:evt.data.event.pageY},contextMenu.util.collectAndMerge(applicableMenuProviders,evt.data.target));        
            }                       
        });

        // XGEE key handler extension point
        var keyHandlers=[];
        pluginAPI.provide('editor.keys',keyHandler.GenericKeyHandler,function(event){
           keyHandlers.push(event.extension);
        });

        eventBroker.subscribe('XGEE/KEYPRESS',function(evt){
           for(const keyHandler of keyHandlers){
                if(keyHandler.isApplicableToEvent(evt.data.key,evt.data.ctrlKey,evt.data.altKey,evt.data.shiftKey,evt.data.target)){
                    keyHandler.action(evt.data.target);
                    if(keyHandler.preventPropagation){ 
                        break;
                    }
                }
           }     
        });
        


        pluginAPI.expose(publicAPI); 
      
        return true;       

};

export var meta={
    "id":"editor",
    "description":"A model-based Graphical Editor for Ecore Models",
    "author":"Matthias Brunner",
    "version":"0.1.0",
    "requires":["ecore","ecoreSync",'eventBroker',"plugin.ecoreTreeView",'contextMenu','keyHandler']
};



