/*
 *  Mulicase environment element 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.jTMassEnvironment;

import jTGUI.TMulticastInternalFrame;
import jTMass.TMass;
import jTMass.core.jTMassModel.TModelConnection;
import jTMass.core.jTMassModel.TModelElement;
import jTMass.core.jTMassModel.jModelData.TModelData;
import jTMass.core.jTMassSimulator.jTCalendar.TCalendarEvent;
import javax.swing.JInternalFrame;

public class TMulticast extends TEnvironment {

    Long _delayMulticast=new Long(2);

    // ===== STRING CONTENT READER =====

    public String getElementType(){
        return("Multicasts");
    }

    // ===== GUI =====

    @Override
    public void refreshConnectionsPanel(){
        try{
            if(PInternalFrame!=null)
                ((TMulticastInternalFrame)PInternalFrame).updateConnections();
        }catch(Exception e){
            TMass._Terminal.reportError("Updating multicast's connection frame");
        }
    }

    @Override
    public void refreshElementFrame(){
        refreshConnectionsPanel();
    }

    @Override
    public JInternalFrame createElementFrame(TMass tmass){
        PInternalFrame=new TMulticastInternalFrame(this, tmass);
        return(PInternalFrame);
    }

    // ===== MULTICASTING =====

    protected void multicastMessage(TModelData message){
        TModelElement element;
        TModelConnection connection;
        TCalendarEvent event;

        for(int i=2;i<=PnoOutputGates+1;i++){
            connection=getOutputConnection(i);
            if(connection!=null){
                element=connection.getInputElement();
                if((element!=null)&&(!element.getElementName().contentEquals(message.getSender()))){
                    TModelData newMessage=message.cloneData();
                    newMessage.setReceiver(element.getElementName());
                    POutputDataBuffer.add(newMessage);
                    Long genTime=new Long(TMass.getSimulator().getModelTime());
                    Long exeTime=genTime+_delayMulticast;
                    event=new TCalendarEvent(element,TCalendarEvent._EventReceiveInputs,
                                genTime, exeTime, this);
                    TMass.getSimulator().getCalendar().insertEvent(event);
                }
            }
        }
    }

   // ===== ELEMENT BEHAVIOUR =====

    @Override
    public boolean acceptableInput(TModelData data){
        // receiver - broadcast nebo na vystupech platforma(!)
        if (((data.getReceiver().contentEquals(TModelData._Broadcast)))||
                (getConnectionToElementName(data.getReceiver())!=null))
            return(true);
        return(false);
    }

    @Override
    public int setOutputs(){
        super.setOutputs();
        return(TModelElement._ESReady);
    };

    @Override
    public int evolveElement(){
        for(TModelData message:PInputDataBuffer)
            if(message.getReceiver().contentEquals(TModelData._Broadcast))
                multicastMessage(message);
                    else
                        if(getConnectionToElementName(message.getReceiver())!=null)
                            POutputDataBuffer.add(message);
        return(TModelElement._ESReady);
    };

    @Override
    public int processInputs(){
        // ACL Messages are not processed in any way here
        return(TModelElement._ESReady);
    };

    @Override
    public int readInputs(){
        super.readInputs();
        return(TModelElement._ESReady);
    };

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

    public TMulticast(String name, int noOfElements, boolean element){
        super(name, noOfElements, element);
    }

}