package framework.component;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.HashMap;
import framework.component.list.MultiTypeComponentList;
import framework.component.list.SingleTypeComponentList;
import framework.component.list.TypeAndIDComponentList;
import framework.component.list.UniqueIDComponentList;
import framework.component.path.ComponentPath;
import framework.io.CustomInputStream;
import framework.io.component.ComponentLoader;
public class ComponentSystem {
private final HashMap<String, ParentComponent> componentRegistry;
private final MultiTypeComponentList componentGrid;
public static ComponentSystem singleton = null;
private ParentComponent root;
private ComponentSystem(){
componentGrid = new TypeAndIDComponentList();
componentRegistry = new HashMap<String, ParentComponent>();
}
public ParentComponent getRoot(){
return root;
}
public static ComponentSystem getInstance(){
if(singleton == null){
singleton = new ComponentSystem();
singleton.root = new ParentComponent();
}
return singleton;
}
public static ComponentSystem loadFromFile(String fileName) throws IOException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException{
clearComponentSystem();
singleton = new ComponentSystem();
singleton.root = (ParentComponent) ComponentLoader.loadComponent(fileName);
return singleton;
}
public static ComponentSystem loadFromStream(CustomInputStream in) throws IOException{
clearComponentSystem();
singleton = new ComponentSystem();
try {
singleton.root = (ParentComponent) ComponentLoader.loadComponent(in, true, true);
} catch (Exception e) {
e.printStackTrace();
}
return singleton;
}
public static void clearComponentSystem(){
singleton = null;
}
public Component getComponent(ComponentPath path){
return path != null ? path.getComponentFrom(componentGrid) : null;
}
public void addComponent(Component c, boolean shouldAssignID){
if(shouldAssignID){
c.setUniqueID(componentGrid.getNextFreeSlot(c.getType(), true));
}
componentGrid.addComponent(c);
}
public void removeComponent(Component c){
if(c != null){
removeComponent(c.getType(), c.getUniqueID());
}
}
//TODO use pools to make this better
public void removeComponent(String type, int uniqueID){
Component c = componentGrid.removeComponent(type, uniqueID);
if(c != null){
ParentComponent p = c.getParent();
if(p != null){
p.removeComponent(c);
}
}
}
public int getMaxIDReached(String type){
return ((UniqueIDComponentList) componentGrid.getComponentsOfType(type)).getMaxID();
}
public HashMap<String, Integer> getSafeBaseForAllTypes(){
HashMap<String, Integer> safeIdsForTypes = new HashMap<String, Integer>();
for(String type:componentGrid.getTypeNames()){
safeIdsForTypes.put(type, getMaxIDReached(type) + 1);
}
return safeIdsForTypes;
}
public MultiTypeComponentList getAllComponents(){
return componentGrid;
}
public Collection<Component> getComponentsOfType(String type){
SingleTypeComponentList comps = componentGrid.getComponentsOfType(type);
return comps != null ? comps.getAllComponents() : null;
}
public ParentComponent getParentComponentByLabel(String label){
return componentRegistry.get(label);
}
public void setComponentLabel(ParentComponent parentComp, String label){
componentRegistry.put(label, parentComp);
}
public ParentComponent removeComponentForLabel(String label){
return componentRegistry.remove(label);
}
public Component getComponentWithTypeAndLabel(String label, Class<? extends Component> type){
return this.getComponentWithTypeAndLabel(label, type.getName());
}
public Component getComponentWithTypeAndLabel(String label, String type){
ParentComponent parent = getParentComponentByLabel(label);
if(parent != null){
return parent.getChildByType(type);
}
return null;
}
}