package mv4503.lab3;

import edu.nps.moves.dis.EntityID;
import edu.nps.moves.dis.EntityStatePdu;
import edu.nps.moves.dis.EntityType;
import edu.nps.moves.dis.Vector3Double;
import edu.nps.moves.disutil.CoordinateConversions;
import edu.nps.moves.disutil.DisTime;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.*;
import java.util.Enumeration;

public class Lab3Multicast
{
  private static final int DIS_PORT = 3000;
  private static final String MCAST_GROUP = "230.0.0.0";
  
  public static void main(String[] args)
  {
    try {      
      EntityStatePdu espdu = new EntityStatePdu();
      espdu.setExerciseID((short)1); // Exercise ID
      
      // These are example values
      EntityID entityID = espdu.getEntityID();
      entityID.setSite(1);        // Site #
      entityID.setApplication(1); //Application
      entityID.setEntity(2);      //Entity id

      EntityType entityType = espdu.getEntityType();
      entityType.setEntityKind((short)1);  // Platform (vs lifeform, munition, sensor, etc.)
      entityType.setCountry(255);          // USA
      entityType.setDomain((short)1);      // Land (vs air, surface, subsurface, space)
      entityType.setCategory((short)1);    // Tank
      entityType.setSubcategory((short)1); // M1 Abrams
      entityType.setSpec((short)3);        // M1A2 Abrams

      // Set time
      espdu.setTimestamp(DisTime.getInstance().getDisAbsoluteTimestamp());

      // Set location
      double lat = 36.596620;  // Coordinates for Herrmann Hall
      double lon = -121.873627;
 
      double[] coords = CoordinateConversions.getXYZfromLatLonDegrees(lat, lon, 1.0d);
      Vector3Double location = espdu.getEntityLocation();
      location.setX(coords[0]);
      location.setY(coords[1]);
      location.setZ(coords[2]);

      // turn object into byte stream
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      DataOutputStream dos = new DataOutputStream(baos);
      espdu.marshal(dos);
      byte[] data = baos.toByteArray();
      
      MulticastSocket msocket = new MulticastSocket();
      InetAddress maddr = InetAddress.getByName(MCAST_GROUP);
      // load byte buffer into packet and send
      DatagramPacket packet = new DatagramPacket(data, data.length, maddr, DIS_PORT);
      msocket.setNetworkInterface(findIp4Interface());
      System.out.println("sending to "+maddr.getHostAddress()+":"+DIS_PORT);
      msocket.send(packet);
      System.out.println("ESPDU datagram sent");

      msocket.close();
    }
    catch (IOException ex) {
      System.out.println("Exception creating/sending DIS pdu: " + ex.getMessage());
    }
  }
  
   /* find proper interface */
  private static NetworkInterface findIp4Interface() throws SocketException
  {
    Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
    while (ifaces.hasMoreElements()) {
      NetworkInterface nif = ifaces.nextElement();
      Enumeration<InetAddress> addresses = nif.getInetAddresses();
      while (addresses.hasMoreElements()) {
        InetAddress addr = addresses.nextElement();
        if (addr instanceof Inet4Address && !addr.isLoopbackAddress()) {
          System.out.println("Using network interface "+nif.getDisplayName());
          return nif;
        }
      }
    }
    return null;
  }

}