/*
 * Copyright (c) 2015-2018 Dzikoysk
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.panda_lang.panda.language.structure.overall.module;

import org.panda_lang.panda.language.structure.prototype.structure.ClassPrototype;

import java.util.HashMap;
import java.util.Map;

public class ModuleRegistry {

    private static final ModuleRegistry instance = new ModuleRegistry();
    private final Map<String, Module> groups;

    public ModuleRegistry() {
        this.groups = new HashMap<>();
    }

    public Module getOrCreate(String groupName) {
        return groups.computeIfAbsent(groupName, Module::new);
    }

    public Module get(String groupName) {
        return groups.get(groupName);
    }

    public Map<String, Module> getGroups() {
        return groups;
    }

    public static ModuleRegistry getDefault() {
        return instance;
    }

    public static ClassPrototype forName(String prototypePath) {
        ModuleRegistry registry = getDefault();
        String[] parts = prototypePath.split(":");
        Module module = registry.get(parts[0]);

        if (module == null) {
            return null;
        }

        return module.get(parts[1]);
    }

    public static ClassPrototype forClass(Class<?> clazz) {
        ModuleRegistry registry = ModuleRegistry.getDefault();
        Package clazzPackage = clazz.getPackage();

        if (clazzPackage == null) {
            System.out.println("[static-indev-debug] ModuleRegistry.forClass called for class without package: " + clazz.getName());
            return null;
        }

        Module module = registry.get(clazzPackage.getName());

        if (module == null) {
            return null;
        }

        return module.get(clazz.getSimpleName());
    }

}

@@ -701,52 +701,187 @@
 age.
-structure.prototype.structure.ClassPrototype
+runtime.PandaRuntimeException;%0Aimport org.panda_lang.panda.language.structure.prototype.structure.ClassPrototype;%0Aimport org.panda_lang.panda.utilities.commons.objects.StringUtils
 ;%0A%0Ai
@@ -1028,24 +1028,93 @@
 Registry();%0A
+    private static final String DEFAULT_MODULE = StringUtils.EMPTY;%0A%0A
     private 
@@ -1146,16 +1146,56 @@
  groups;
+%0A    private final Module defaultModule;
 %0A%0A    pu
@@ -1253,24 +1253,142 @@
 ashMap%3C%3E();%0A
+        this.defaultModule = new Module(DEFAULT_MODULE);%0A        this.groups.put(DEFAULT_MODULE, this.defaultModule);%0A
     %7D%0A%0A    p
@@ -1581,32 +1581,108 @@
 upName);%0A    %7D%0A%0A
+    public Module getDefaultModule() %7B%0A        return defaultModule;%0A    %7D%0A%0A
     public Map%3CS
@@ -1984,16 +1984,163 @@
 t(%22:%22);%0A
+%0A        switch (parts.length) %7B%0A            case 1:%0A                return registry.getDefaultModule().get(parts%5B0%5D);%0A            case 2:%0A        
         
@@ -2176,24 +2176,32 @@
 parts%5B0%5D);%0A%0A
+        
         if (
@@ -2222,32 +2222,40 @@
 ) %7B%0A            
+     
+   
 return null;%0A   
@@ -2255,35 +2255,48 @@
 ll;%0A        
-%7D%0A%0A
+        %7D%0A%0A     
         
 return modul
@@ -2275,32 +2275,35 @@
 %7D%0A%0A             
+   
 return module.ge
@@ -2311,24 +2311,148 @@
 (parts%5B1%5D);%0A
+            default:%0A                throw new PandaRuntimeException(%22Invalid prototype path: %22 + prototypePath);%0A        %7D%0A
     %7D%0A%0A    p
@@ -2569,24 +2569,25 @@
 ault();%0A
+%0A
         
 Package 
@@ -2578,23 +2578,22 @@
         
-Package
+String
  clazzPa
@@ -2622,167 +2622,42 @@
 ge()
-;%0A%0A        if (clazzPackage == null) %7B%0A            System.out.println(%22%5Bstatic-indev-debug%5D ModuleRegistry.forClass called for class without package: %22 + clazz
+ == null ? %22%22 : clazz.getPackage()
 .get
@@ -2666,47 +2666,10 @@
 me()
-)
 ;%0A
-            return null;%0A        %7D%0A%0A
     
@@ -2713,26 +2713,16 @@
 zPackage
-.getName()
 );%0A%0A    

Improve registry