package org.ingrahamrobotics.robottables;

import java.io.IOException;
import org.ingrahamrobotics.robottables.api.RobotTablesClient;
import org.ingrahamrobotics.robottables.network.IO;
import org.ingrahamrobotics.robottables.network.Queue;
import org.ingrahamrobotics.robottables.network.Queue.QueueEvents;

public class RobotTables implements QueueEvents {

    // Make IO a package-level variable (instead of a local variable) so that it is accessible from the outside
    IO io;
    private Dispatch dispatch;
    private ProtocolHandler protocolHandler;
    private TablesInterfaceHandler tablesInterfaceHandler;

    public void run(String targetAddress) {
        // Message queue between listener and dispatch
        Queue queue = new Queue(this);

        try {
            io = new IO(targetAddress);

            // Listen for and queue incoming messages
            io.listen(queue);

            dispatch = new Dispatch(queue);

            protocolHandler = new ProtocolHandler(io);

            // Dispatch all messages from the queue to the protocol handler
            dispatch.setAllHandlers(protocolHandler);

            tablesInterfaceHandler = new TablesInterfaceHandler(protocolHandler);

            // Set the internal handler on the protocol handler
            protocolHandler.setInternalHandler(tablesInterfaceHandler);

            (new Thread(dispatch)).start();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void queueError(int size, boolean draining, int targetSize) {
        if (!draining) {
            System.err.println("Queue Warning: Large message queue size: " + size);
        } else {
            System.err.println("Queue Error: Drained to size: " + targetSize);
        }
        if (dispatch.currentMessage() == null) {
            System.err.println("\tNo dispatch handler running");
        } else {
            long now = System.currentTimeMillis();
            System.err.println("\tDispatch time: " + (now - dispatch.dispatchTime()) + " ms ago");
            System.err.println("\tDispatch message:\n" + dispatch.currentMessage().displayStr());
        }
    }

    public RobotTablesClient getClientInterface() {
        return tablesInterfaceHandler;
    }

    public void close() {
        io.close();
    }
}

@@ -653,16 +653,35 @@
 Address)
+ throws IOException
  %7B%0A     
@@ -774,26 +774,8 @@
 );%0A%0A
-        try %7B%0A    
     
@@ -815,20 +815,16 @@
         
-    
 // Liste
@@ -865,20 +865,16 @@
         
-    
 io.liste
@@ -884,36 +884,32 @@
 ueue);%0A%0A        
- 
-   
 dispatch = new D
@@ -921,28 +921,24 @@
 ch(queue);%0A%0A
-    
         prot
@@ -985,20 +985,16 @@
         
- 
-   
 // Dispa
@@ -1053,28 +1053,24 @@
 ler%0A        
-    
 dispatch.set
@@ -1108,20 +1108,16 @@
         
-  
-  
 tablesIn
@@ -1187,20 +1187,16 @@
         
-    
 // Set t
@@ -1243,28 +1243,24 @@
 ler%0A        
-  
-  
 protocolHand
@@ -1316,20 +1316,16 @@
         
-    
 (new Thr
@@ -1352,87 +1352,8 @@
 ();%0A
-        %7D catch (IOException ex) %7B%0A            ex.printStackTrace();%0A        %7D%0A
     

Throw IOException instead of catching it, so projects using the library can deal with the error as they need.