/*
 *  Model connection 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 jTMass.TMass;
import jTMass.core.jTMassModel.jModelData.*;
import java.util.LinkedList;

public class TModelConnection{

    // ===== MULTIPLE MESSAGES POLICIES =====
    public static final int _MA_Buffer=1;  // only used
    public static final int _MA_LastMessage=2;
    public static final int _MA_FirstMessage=3;
    public static final int _MA_Conflict=4;

    int PInputType;
    int POutputType;
    int PInputGate,POutputGate;
    int PAccessPolicy;
    int PBufferSize=0;
    Long PConnectionTime=new Long(0);
    String PName;
    LinkedList<TModelData> PMessageBuffer;
    TModelElement PInputElement;
    TModelElement POutputElement;
    TModelData PData=null;

    // ===== TERMINAL =====

    public void printConnection(){
        String ielement,oelement;

        oelement=getOutputElement().getElementName();
        if(getInputElement()==null)
            ielement="noElement";
        else
            ielement=getInputElement().getElementName();

        TMass._Terminal.printlnSystemInfo(POutputType+";"+PInputType+"; "+oelement+"["+POutputGate+"] -> "+ielement+"["+PInputGate+"] \t name:  "+getConnectionName());
    }

    // ===== READERS, WRITERS =====

    public Long getConnectionTime(){
        return(PConnectionTime);
    }

    public String getConnectionName(){
        return(PName);
    }

    public TModelElement getInputElement(){
        return(PInputElement);
    }
	
    public TModelElement getOutputElement(){
        return(POutputElement);
    }

    public int getInputGate(){
        return(PInputGate);
    }
	
    public int getOutputGate(){
        return(POutputGate);
    }

    // ===== CONNECTION NAME GENERATOR =====

    public static String generateConnectionName(TModelElement outputElement, int outputGate,
            TModelElement inputElement, int inputGate){
        String inElName;
	String outElName;

        if (inputElement!=null)
            inElName=inputElement.getElementName();
	else
            inElName="(no element)";

        if (outputElement!=null)
            outElName=outputElement.getElementName();
	else
            outElName="(no element)";

	return("CON: "+outElName+"["+outputGate+"] -> "+inElName+"["+inputGate+"]"+" ");
    }

    // ===== DATA MANIPULATION =====

    public String getDataContent(){
        if(PData==null)
            return("No Data");
        else
            return(PData.getContentS());
    }

    public String getDataContentEx(){
        String result;

        if(PData==null)
            return("No Data");

        result=PData.getContentEx();
        if(!PMessageBuffer.isEmpty())
            result=result.concat("[+"+PMessageBuffer.size()+"]");

        return(result);
    }

    public LinkedList<TModelData> getDataList(){
        LinkedList<TModelData> list=new LinkedList<TModelData>();

        if(PData!=null)
            list.add(PData);
        for(TModelData data:PMessageBuffer)
            list.add(data);
        return(list);
    }

    public TModelData getData(){
        return(PData);
    }

    public boolean dataPresent(){
        return(PData!=null);
    }

    public TModelData popData(){
        TModelData data=PData;

        if(!PMessageBuffer.isEmpty()){
            PData=PMessageBuffer.getFirst();
            PMessageBuffer.removeFirst();
        }
        else
            PData=null;

        return(data);
    }

    public void clearData(){
        PData=null;
        PMessageBuffer.clear();
    }

    public void setData(TModelData data){
        switch (PAccessPolicy){
            case _MA_Buffer:{
                if(PData==null){
                    PData=data;
                    break;
                }

                PMessageBuffer.addFirst(PData);
                PData=data;
                if(PBufferSize>0)
                    while(PMessageBuffer.size()>PBufferSize)
                        PMessageBuffer.removeLast();
            }
        }
        PInputElement.refreshConnectionsPanel();
        POutputElement.refreshConnectionsPanel();
    }

    //============= CONNECTING/SETTING/SUPPORT =================

    public boolean typeMatch(TModelElement element){
        if(element.getType()==PInputType)
            return(true);
	else
            return(false);
    }

    public boolean setInputElement(TModelElement element,int gate){
        if(element.getType()==PInputType){
            PInputElement=element;
            PInputGate=gate;

            if(TMass.getSimulator()!=null)
                PConnectionTime=new Long(TMass.getSimulator().getModelTime());
            else
                PConnectionTime=new Long(0);
            
            return(true);
	}
	return(false);
    };
	
    public boolean setOutputElement(TModelElement element,int gate){
        if(element.getType()==POutputType){
            POutputElement=element;
            PInputGate=gate;
            return(true);
	}
	return(false);
    };

    public void setBufferSize(int size){
        PBufferSize=size;
    }

    public void setMAPolicy(int policy){
        PAccessPolicy=policy;
    }

    // ===== CONSTRUCTOR =====
	
    public TModelConnection(TModelElement fromElement,
        int fromGate, int outType, int inType,String name){
        PName=name;
	POutputGate=fromGate;
	POutputElement=fromElement;
	PInputType=inType;   
	POutputType=outType;
        PInputGate=0;
        PInputElement=null;
        PAccessPolicy=_MA_Buffer; 
        PMessageBuffer=new LinkedList<TModelData>();
    }

}