/*
 * Java Network Programming, Second Edition
 * Merlin Hughes, Michael Shoffner, Derek Hamner
 * Manning Publications Company; ISBN 188477749X
 *
 * http://nitric.com/jnp/
 *
 * Copyright (c) 1997-1999 Merlin Hughes, Michael Shoffner, Derek Hamner;
 * all rights reserved; see license.txt for details.
 */

import java.io.*;
import java.util.*;

public class Demultiplexer extends Thread {
  static private int plexerNumber;
  static private synchronized int nextPlexerNum () { return plexerNumber ++; }

  protected MultiplexInputStream multiplexIn;
  protected Hashtable targets;

  public Demultiplexer (MessageInput messageIn) {
    super ("Demultiplexer-" + nextPlexerNum ());
    multiplexIn = new MultiplexInputStream (messageIn);
    targets = new Hashtable ();
  }

  public void register (String label, MessageOutput messageOut) {
    targets.put (label, messageOut);
  }

  public void deregister (String label) {
    targets.remove (label);
  }

  protected boolean finished;
  
  public void finish () {
    finished = true;
    interrupt ();
  }

  public void run () {
    try {
      while (!interrupted ()) {
        multiplexIn.receive ();
        String label = multiplexIn.getLabel ();
        MessageOutput messageOut = (MessageOutput) targets.get (label);
        if (messageOut != null) {
          byte[] message = new byte[multiplexIn.available ()];
          multiplexIn.readFully (message);
          synchronized (messageOut) {
            messageOut.write (message);
            messageOut.send ();
          }
        }
      }
    } catch (IOException ex) {
      if (!finished)
        ex.printStackTrace ();
    }
  }
}
