//
// $Source: /nfs/elm/d3/home/cur/djb1/java/javat/RCS/BounceOne.java,v $
//
// $Id: BounceOne.java,v 1.1 1997/06/23 17:04:34 djb1 Exp $
//
// Object_Channel AWT test Applet/Application - Bounce Three
//
// (C) Copyright 1997 Dave Beckett <D.J.Beckett@ukc.ac.uk>
// University of Kent at Canterbury
//

import java.awt.*;
import java.applet.Applet;
import java.util.Vector;
import java.net.URL;
import java.net.MalformedURLException;

import Object_Channel;
import Alternative;

import ImageButtonCh;
import ScrollbarCh;

class BounceOne extends Panel implements Runnable {
  private Thread my_thread;
  
  // Image storage
  private Image[] images;
  private Label label;
  private int nFrames;
  
  // Active objects with Channel interfaces
  private ImageButtonCh imagebutton_ch;
  private ScrollbarCh scrollbar_ch;  
  
  // Channels
  private Object_Channel toImageButtonCh, fromImageButtonCh, eventImageButtonCh;
  private Object_Channel toScrollbarCh, fromScrollbarCh, eventScrollbarCh;
  
  // Translation of occam constants
  static final int ticks_per_second = 1000;
  static final int max_fps = 100;
  static final int min_fps = 1;
  static final int span_fps = (max_fps - min_fps)+1;
  static final int max_scale = 200; // bananas?
  static final int minfps_maxscale = min_fps * max_scale;
  static final int initial_value = 0; // initial value of what?
  
  public BounceOne (Image[] images) 
  {
    this.images=images;
    this.nFrames=images.length;
    
    setLayout(new BorderLayout());
    
    // Init channels to/from image button
    toImageButtonCh=new Object_Channel();
    fromImageButtonCh=new Object_Channel();
    eventImageButtonCh=new Object_Channel();
    // Init channels to/from scrollbar
    toScrollbarCh=new Object_Channel();
    fromScrollbarCh=new Object_Channel();
    eventScrollbarCh=new Object_Channel();
    
    // Create the new ImageButton for my images
    imagebutton_ch=new ImageButtonCh(toImageButtonCh, fromImageButtonCh, eventImageButtonCh, images, this, 64, 64);
    add("Center", imagebutton_ch);
    
    // Create the Scrollbar
    scrollbar_ch=new ScrollbarCh(toScrollbarCh, fromScrollbarCh, eventScrollbarCh, Scrollbar.VERTICAL,1,1,0,100);
    add("West", scrollbar_ch);
    
    // Create the message line
    label=new Label();
    add("South", label);
    
    // Start me up
    my_thread=new Thread(this, "ImagebuttonTest");
    my_thread.start();
  }
  
  public void message(String s)
  {
    label.setText(s);
  }
  
  
  // Thread main loop
  public void run() 
  {
    // Translation of occam variables
    int value     = initial_value; // well that cleared that up
    int frame     = 0;
    int direction = 1;
    int interval  = 0;
    Alternative alt=new Alternative();
    boolean[] channel_guards = {true, true};
    Object_Channel[] oc = {eventScrollbarCh, eventImageButtonCh};
  
    try 
      {
	// MAIN LOOP
	while(true) {
	  // ALT on the channels or timeout after 'interval' msec
	  int index = alt.select(oc, channel_guards, interval, (value>0));
	  
	  if (index==0) {
	    // eventScrollbar (index 0)
	    AWTProtocol message=(AWTProtocol) oc[index].read(); // Should not BLOCK
	    switch (message.get_type()) {
	      
	      // Dragging the scrollbar
	      case AWTProtocol.SCROLL_ABSOLUTE:
		value = ((Integer)message.get_arg()).intValue();
		message("Dragged to "+value);
		
		if (value > 0) {
		  int fps = (((value - 1 ) * span_fps ) + minfps_maxscale)/max_scale;
		  interval = ticks_per_second/fps;
		}
		break;
		
	      // Clicking to move scrollbar
	      case AWTProtocol.SCROLL_LINE_DOWN:
	      case AWTProtocol.SCROLL_LINE_UP:
	      case AWTProtocol.SCROLL_PAGE_DOWN:
	      case AWTProtocol.SCROLL_PAGE_UP:
		value = ((Integer)message.get_arg()).intValue();
		message("Moved to "+value);
		
		if (value > 0) {
		  int fps = (((value - 1 ) * span_fps ) + minfps_maxscale)/max_scale;
		  interval = ticks_per_second/fps;
		}
		break;
		
	      default:
		message("ImagebuttonTest.run: Received unknown / unsupported message "+message.get_type()+" from Scrollbar");
	    } // switch
	  }
	  
	  else if (index==1) {
	    // eventImageButton (index 1)
	    AWTProtocol message=(AWTProtocol) oc[index].read(); // Should not BLOCK
	    
	    switch (message.get_type()) {
	      case AWTProtocol.MOUSE_DOWN:
		message("Reversing direction");
		direction = -direction;
		break;
	      default:
		message("ImagebuttonTest.run: Received unknown / unsupported message "+message.get_type()+" from ImageButton");
	    } // switch
	  }
	  
	  else {
	    // timeout (index > oc.length)
	    frame = ((frame + direction) + nFrames)% nFrames;
	    
	    toImageButtonCh.write (new AWTProtocol(AWTProtocol.SET_FRAME, new Integer(frame)));
	  }
	  
	}
      }
    catch (InterruptedException e)
      {
	System.err.println ("ImagebuttonTest.run: Thread ending");
	return; // end this thread
      }
  }
  
}
