import java.util.*;

public class SessionInfo {
   private Vector vSSRC;
   private Vector vInfo;
   private static final boolean Debug=true;
   private static boolean We_sent=false;
   private int    senders=0;
   private int    members=1;
   private int    packet_size;
   private int    avg_rtcp_size;
   private boolean initial=true;
   private double rtcp_bw=625;
   private final double RTCP_MIN_TIME=5;
   private final double RTCP_SENDER_BW_FRACTION = 0.25;
   private final double RTCP_RCVR_BW_FRACTION = 1-RTCP_SENDER_BW_FRACTION;
   private final double RTCP_SIZE_GAIN = 1/16;
   private Random r = new Random();
   
   
   public SessionInfo(){
      vSSRC = new Vector();
      vInfo = new Vector();
   }
   
   public boolean addParticipant(ParticipantInfo pi){
      if (vSSRC.contains(new Integer(pi.SSRC)))   return false;
      vInfo.addElement(pi);
      vSSRC.addElement(new Integer(pi.SSRC));
      if (Debug){
         System.out.println("SessionInfo.addParticipant: SSRC-->"+pi.SSRC);
      }
      return true;
   }
   
   public boolean removeParticipant(int ssrc){
      if (!vSSRC.contains(new Integer(ssrc)))   return false;
      vInfo.removeElementAt(vSSRC.indexOf(new Integer(ssrc)));
      vSSRC.removeElement(new Integer(ssrc));
      return true;
   }
   
   public ParticipantInfo getInfo(int ssrc){
      if (vSSRC.contains(new Integer(ssrc)))
         return (ParticipantInfo)
            (vInfo.elementAt(vSSRC.indexOf(new Integer(ssrc))));
      else return null;
   }
   
   public synchronized void setWe_sent(boolean b){
      We_sent = b;
   }
   
   public synchronized boolean we_sent(){
      return We_sent;
   }
   
   public int rtcp_interval(){
      double t;
      double rtcp_min_time= RTCP_MIN_TIME;
      int   n;
   
      if (initial){
         rtcp_min_time /= 2;
         avg_rtcp_size = 128;
         initial = false;
      }
      
      n = members;
      if (senders > 0 && senders < members * RTCP_SENDER_BW_FRACTION){
         if (We_sent){
            rtcp_bw *= RTCP_SENDER_BW_FRACTION;
            n = senders;
          } else {
            rtcp_bw *=RTCP_RCVR_BW_FRACTION;
            n -= senders;
         }
      }
      
      avg_rtcp_size += (packet_size - avg_rtcp_size)*RTCP_SIZE_GAIN;
      t = avg_rtcp_size * n / rtcp_bw;
      if (t<rtcp_min_time)
         t = rtcp_min_time;
      
      return (int) (1000*(t * (r.nextDouble()+ 0.5)));
   } 
   
   public synchronized void resetSenders(){
      senders = 0;
   }
   
   public synchronized void addMembers(int n){
      members += n;
   }
   
   public synchronized void addSenders(int n){
      senders += n;
   }
   
   public void updatePacketSize(int sz){
      packet_size = sz;
   }   
}
   

