// Purpose.  Mediator and Observer demo
// 
// Observer -
// 1. Sender is coupled to a Receiver interface
// 2. Receivers register with Sender
// 3. Sender broadcasts to all Receivers
// 
// Mediator -
// 4. Mediator implements Receiver interface
// 5. Mediator registers with Senders
// 6. Receivers register with Mediator
// 7. Senders send to Mediator
// 8. Mediator sends to Receivers

import java.awt.*;
import java.awt.event.*;

public class MediatorObserverDemo {
   static final int ODD = 1, EVEN = 2, THRE = 3;

   interface Observer { public void update( String s ); }

   static class Mediator extends FrameClose implements ActionListener { // 4 \\
      private Observer[] odd = new Observer[2], even = new Observer[2], // 1 \\
         thre = new Observer[2];
      private int numO = 0, numE = 0, numT = 0;
      public Mediator( String str ) { super( str ); }
      public void register( Observer o, int type ) {
         if (type == ODD)       odd[numO++]  = o;
         else if (type == EVEN) even[numE++] = o;
         else if (type == THRE) thre[numT++] = o;
      }
      public void actionPerformed( ActionEvent e ) {
         if (Integer.parseInt(e.getActionCommand()) % 2 == 1)         // 3,8 \\
            for (int i=0; i < numO; i++) odd[i].update( e.getActionCommand() );
         else if (Integer.parseInt(e.getActionCommand()) % 2 == 0)
            for (int i=0; i < numE; i++) even[i].update( e.getActionCommand() );
         if (Integer.parseInt(e.getActionCommand()) % 3 == 0)
            for (int i=0; i < numT; i++) thre[i].update( e.getActionCommand() );
   }  }

   static class Subscriber extends TextArea implements Observer {
      public void update( String s ) { append( s + '\n' ); } }

   public static void main( String[] args ) {
      Mediator   mediator = new Mediator( "MediatorObserverDemo" );
      Subscriber sub;

      Panel top = new Panel();
      Button btn;
      for (int i=1; i < 10; i++) {
         btn = new Button( "" + i );
         btn.addActionListener( mediator );                           // 5,7 \\
         top.add( btn ); }
      Panel center = new Panel();
      center.setLayout( new GridLayout( 1, 3 ) );                     // 2,6 \\
      sub = new Subscriber(); center.add( sub ); mediator.register( sub, ODD );
      sub = new Subscriber(); center.add( sub ); mediator.register( sub, EVEN );
      sub = new Subscriber(); center.add( sub ); mediator.register( sub, THRE );

      mediator.add( top, BorderLayout.NORTH );
      mediator.add( center, BorderLayout.CENTER );
      mediator.setSize( 250, 200 );
      mediator.setVisible( true );
}  }

