package org.mwc.debrief.dis.providers.network;

import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.mwc.debrief.dis.listeners.IDISGeneralPDUListener;
import org.mwc.debrief.dis.providers.IPDUProvider;

import edu.nps.moves.dis.Pdu;
import edu.nps.moves.disutil.PduFactory;
import edu.nps.moves.examples.EspduSender;

/**
 * data provider that listens for data on a network multicast socket
 * 
 * @author Ian
 * 
 */
public class NetworkDISProvider implements IPDUProvider
{
  @SuppressWarnings("unused")
  private final IDISNetworkPrefs _myPrefs;
  private List<IDISGeneralPDUListener> _gen = new ArrayList<IDISGeneralPDUListener>();
  private boolean _running;

  /**
   * Max size of a PDU in binary format that we can receive. This is actually
   * somewhat outdated--PDUs can be larger--but this is a reasonable starting
   * point
   */
  public static final int MAX_PDU_SIZE = 8192;

  public NetworkDISProvider(IDISNetworkPrefs prefs)
  {
    _myPrefs = prefs;
  }

  @Override
  public void addListener(IDISGeneralPDUListener listener)
  {
    _gen.add(listener);
  }

  /**
   * start listening
   * 
   */
  public void attach()
  {
    
    Job job = new Job("Handle incoming") {
      @Override
      protected IStatus run(IProgressMonitor monitor) {
        // set the running flag to true
        _running = true;
        
        startListening();
        // use this to open a Shell in the UI thread
        return Status.OK_STATUS;
      }

    };
    job.setUser(false);
    job.schedule();    
  }


  /**
   * stop listening
   * 
   */
  public void detach()
  {
    // set the flag, so we naturally stop
    _running = false;
  }
  
  /**
   * start listening
   * 
   */
  private void startListening()
  {
    MulticastSocket socket;
    DatagramPacket packet;
    InetAddress address;
    PduFactory pduFactory = new PduFactory();

    try
    {
      // Specify the socket to receive data
      socket = new MulticastSocket(EspduSender.PORT);
      address = InetAddress.getByName(EspduSender.DEFAULT_MULTICAST_GROUP);
      socket.joinGroup(address);

      // Loop infinitely, receiving datagrams
      while (_running)
      {
        byte buffer[] = new byte[MAX_PDU_SIZE];
        packet = new DatagramPacket(buffer, buffer.length);

        socket.receive(packet);

        Pdu pdu = pduFactory.createPdu(packet.getData());

        // share the good news
        Iterator<IDISGeneralPDUListener> gIter = _gen.iterator();
        while (gIter.hasNext())
        {
          IDISGeneralPDUListener git = (IDISGeneralPDUListener) gIter.next();
          git.logPDU(pdu);
        }

      } // end while
      
      // ok, we've finished
      socket.leaveGroup(address);
      
    } // End try
    catch (Exception e)
    {

      System.out.println(e);
    }
  }

//
//  public static void main(String[] args)
//  {
//
//    IDISPreferences prefs = new TestPrefs(true, "file.txt");
//    IDISModule subject = new DISModule(prefs);
//    IDISNetworkPrefs netPrefs = new CoreNetPrefs(
//        EspduSender.DEFAULT_MULTICAST_GROUP, EspduSender.PORT);
//    IPDUProvider provider = new NetworkDISProvider(netPrefs);
//    subject.setProvider(provider);
//
//    // tell the network provider to start
//    provider.attach();
//  }

}
@@ -574,51 +574,8 @@
 ory;
-%0Aimport edu.nps.moves.examples.EspduSender;
 %0A%0A/*
@@ -734,38 +734,8 @@
 r%0A%7B%0A
-  @SuppressWarnings(%22unused%22)%0A
   pr
@@ -818,16 +818,22 @@
 %3E _gen =
+%0A     
  new Arr
@@ -978,21 +978,16 @@
 actually
-%0A   *
  somewha
@@ -987,16 +987,21 @@
 somewhat
+%0A   *
  outdate
@@ -1056,21 +1056,16 @@
 starting
-%0A   *
  point%0A 
@@ -1370,20 +1370,16 @@
 h()%0A  %7B%0A
-    
 %0A    Job
@@ -1411,16 +1411,20 @@
 coming%22)
+%0A   
  %7B%0A     
@@ -1487,16 +1487,22 @@
 monitor)
+%0A     
  %7B%0A     
@@ -1561,24 +1561,16 @@
 = true;%0A
-        
 %0A       
@@ -1737,19 +1737,14 @@
 e();
-    
 %0A  %7D%0A%0A
-%0A
   /*
@@ -1872,18 +1872,16 @@
 se;%0A  %7D%0A
-  
 %0A  /**%0A 
@@ -2168,32 +2168,34 @@
 tSocket(
-EspduSender.PORT
+_myPrefs.getPort()
 );%0A     
@@ -2231,43 +2231,31 @@
 ame(
-EspduSender.DEFAULT_MULTICAST_GROUP
+_myPrefs.getIPAddress()
 );%0A 
@@ -2841,22 +2841,16 @@
 d while%0A
-      
 %0A      /
@@ -2904,22 +2904,16 @@
 dress);%0A
-      
 %0A    %7D /
@@ -2993,22 +2993,25 @@
  %7D%0A  %7D%0A%0A
+  
 //%0A
+  
 //
- 
  public 
@@ -3046,22 +3046,24 @@
 gs)%0A
+  
 //
- 
  %7B%0A
+  
 //%0A
-// 
   
+//
  IDI
@@ -3116,21 +3116,20 @@
 .txt%22);%0A
-// 
   
+//
  IDISMod
@@ -3164,21 +3164,20 @@
 prefs);%0A
+  
 //
-   
  IDISNet
@@ -3219,17 +3219,12 @@
 fs(%0A
+  
 //
-       
  Esp
@@ -3276,21 +3276,20 @@
 .PORT);%0A
+  
 //
-   
  IPDUPro
@@ -3339,21 +3339,20 @@
 Prefs);%0A
-// 
   
+//
  subject
@@ -3379,16 +3379,17 @@
 r);%0A
+  
 //%0A
-// 
   
+//
  // 
@@ -3427,13 +3427,12 @@
 art%0A
-// 
   
+//
  pro
@@ -3447,16 +3447,17 @@
 tach();%0A
+  
 //
- 
  %7D%0A%0A%7D

use correct prefs