/*
 *  T-Mass simulation model class
 *
 *  2004 - 2011 Frantisek Zboril jr.
 *  Faculty of Information Technology
 *  zborilf@fit.vutbr.cz
 *  http://www.fit.vutbr.cz/~zborilf
 *
 * (C) Brno University of Technology
 * Freeware licence VUT v Brně
 * https://wis.fit.vutbr.cz/FIT/db/dir.php/dr/VZ2007/externiInformace/softwareNaWebu/Priloha2_rozh23.pdf

 */

package jTMass.core.jTMassModel;

import java.util.Hashtable;
import java.util.Enumeration;
import java.util.LinkedList;

public class TModel {
	
    String PModelName;
    Enumeration PIterator;
    Hashtable<String,TModelElement> PUniverse;
    Hashtable<String,TModelConnection> PCharacteristic;
    Hashtable<String,Integer> PElementTypesCounts;

    // ===== ELEMENTS READERS =====

    public TModelElement getElement(){
        if(PIterator!=null)
            if(PIterator.hasMoreElements())
                return((TModelElement)PIterator.nextElement());
        PIterator=PUniverse.elements();
        return(null);
    }

    public void resetElementList(){
        PIterator=PUniverse.elements();
    }

    TModelElement elementExists(TModelElement element){
        TModelElement pElement;

        resetElementList();
	pElement=getElement();
	while(pElement!=null)
            if(element==pElement)
                return(element);
            else
                pElement=getElement();

        return(null);
    }

    public TModelElement getElementByName(String name){
        TModelElement element=PUniverse.get(name);
	return(element);
    }

    // ===== OTHER MODEL/UNIVERSE WRITER AND READERS =====

    public void setModelName(String s){
        PModelName=s;
    }

    public String getModelName(){
        return(PModelName);
    }

    public int getnoElements(){
        return(PUniverse.size());
    }

    public LinkedList getTypeNames(){
        LinkedList typeList=new LinkedList();
        TModelElement element;

        for(String elementName:PUniverse.keySet()){
            element=PUniverse.get(elementName);
            if(!typeList.contains(element.getTypeName()))
                typeList.add(element.getTypeName());
        }
        return(typeList);
    };

    public LinkedList getElementNames(){
        LinkedList elementList=new LinkedList();

        for(String elementName:PUniverse.keySet())
            elementList.add(elementName);

        return(elementList);
    }

    public LinkedList getElementsOfTypes(LinkedList typeList){
        LinkedList elementList=new LinkedList();

        for(String elementName:PUniverse.keySet())
            if(typeList.contains((PUniverse.get(elementName).getTypeName())))
                elementList.add(elementName);

        return(elementList);
    }

    // ===== UNIVERSE MODIFICATION =====

    public void addElement(TModelElement element){
        String key=element.getElementName();
        String typeKey=element.getTypeName();
        Integer count=PElementTypesCounts.get(typeKey);

        if(count==null)
            count=1;
        else
            count++;

        PElementTypesCounts.remove(typeKey);
        PElementTypesCounts.put(typeKey,count);
        if(PUniverse.get(key)!=null)PUniverse.remove(key);
            PUniverse.put(element.getElementName(),element);

        Hashtable<Integer,TModelConnection> gates=element.getOutputGates();
	Enumeration newConnections=gates.elements();
	TModelConnection connection;
	while(newConnections.hasMoreElements()){
            connection=(TModelConnection)newConnections.nextElement();
            addConnection(connection);
	}

        return;
    }

    public boolean removeElement(TModelElement element){
        // not implemented yet
        return(true);
    }

    // ===== CHARACTERISTIC MODIFICATION =====
	
    public void connectElements(TModelElement elementOut, TModelElement elementIn){
	// not implemented yet
	return;
    }
	
    public void disconnectElements(TModelElement elementOut, TModelElement elementIn){
	elementOut=elementExists(elementOut);
	elementIn=elementExists(elementIn);
	if((elementOut==null)||(elementIn==null))
            return;

        elementOut.disconnectElement(elementIn);
	return;
    }

    public void addConnection(TModelConnection connection){
    	PCharacteristic.put(connection.getConnectionName(), connection);
    }

    // ===== CONSTRUCTOR =====

    public TModel(){
        PUniverse=new Hashtable<String,TModelElement>();
	PCharacteristic=new Hashtable<String,TModelConnection>();
        PElementTypesCounts=new Hashtable<String,Integer>();
    }

}