//
// $Source: /nfs/elm/d3/home/cur/djb1/java/javat/RCS/ScrollbarCh.java,v $
//
// $Id: ScrollbarCh.java,v 1.1 1997/06/23 17:04:34 djb1 Exp $
//
// Scrollbar with Object_Channel interface class
//
// (C) Copyright 1997 Dave Beckett <D.J.Beckett@ukc.ac.uk>
// University of Kent at Canterbury
//

import java.awt.*;
import Object_Channel;

import AWTProtocol;

public class ScrollbarCh extends Scrollbar implements Runnable
{
  private Object_Channel toScrollbarCh, fromScrollbarCh, event_Object_Channel;
  private AWTProtocol pending_message=null;
  private Thread my_thread;
  private ScrollbarEventHandler Scrollbar_event_handler;
  
  // Constructor
  public ScrollbarCh(Object_Channel toScrollbarCh, Object_Channel fromScrollbarCh, Object_Channel event_Object_Channel) 
  {
    super();
    init_scrollbar(toScrollbarCh, fromScrollbarCh, event_Object_Channel);
  }
  
  // Constructor
  public ScrollbarCh(Object_Channel toScrollbarCh, Object_Channel fromScrollbarCh, Object_Channel event_Object_Channel, int orientation) 
  {
    super(orientation);
    init_scrollbar(toScrollbarCh, fromScrollbarCh, event_Object_Channel);
  }
  
  // Constructor
  public ScrollbarCh(Object_Channel toScrollbarCh, Object_Channel fromScrollbarCh, Object_Channel event_Object_Channel, int orientation, int value, int visible, int minimum, int maximum) 
  {
    super(orientation, value, visible, minimum, maximum);
    init_scrollbar(toScrollbarCh, fromScrollbarCh, event_Object_Channel);
  }

  
  private void init_scrollbar (Object_Channel toScrollbarCh, Object_Channel fromScrollbarCh, Object_Channel event_Object_Channel) 
  {
    this.toScrollbarCh=toScrollbarCh;
    this.fromScrollbarCh=fromScrollbarCh;
    this.event_Object_Channel=event_Object_Channel;
    
    Scrollbar_event_handler = new ScrollbarEventHandler(event_Object_Channel, this);

    my_thread=new Thread(this, "ScrollbarCh");
    
    // Start my thread (configuration handler)
    my_thread.start();
  }
  
  public boolean handleEvent(Event e) {
    int type=AWTProtocol.NONE;
    
    //System.err.println("ScrollbarCh.handleEvent: Got event "+e);
    if (e.id== Event.SCROLL_ABSOLUTE) {
      type=AWTProtocol.SCROLL_ABSOLUTE;
    } else if (e.id == Event.SCROLL_LINE_DOWN) {
      type=AWTProtocol.SCROLL_LINE_DOWN;
    } else if (e.id == Event.SCROLL_LINE_UP) {
      type=AWTProtocol.SCROLL_LINE_UP;
    } else if (e.id == Event.SCROLL_PAGE_DOWN) {
      type=AWTProtocol.SCROLL_PAGE_DOWN;
    } else if (e.id == Event.SCROLL_PAGE_UP) {
      type=AWTProtocol.SCROLL_PAGE_UP;
    } else if (e.id == Event.MOUSE_DOWN) {
      super.handleEvent(e);
      set_pending_message(AWTProtocol.MOUSE_DOWN, null);
      return true;
    } else if (e.id == Event.MOUSE_UP) {
      super.handleEvent(e);
      set_pending_message(AWTProtocol.MOUSE_UP, null);
      return true;
    } else {
      //System.out.println("ScrollbarCh.handleEvent: Ignoring event "+e);
      return false;
    }
    
    super.handleEvent(e);
    set_pending_message(type, new Integer(((Integer)e.arg).intValue()));
    return true;
  }
  
  public void set_pending_message(int message, Object arg) 
  {
    synchronized (this) 
      {
	pending_message=new AWTProtocol(message, arg);
      }
  }

  public AWTProtocol test_and_reset_pending_message()
  {
    AWTProtocol result;
    
    synchronized (this) 
      {
	result=pending_message;
	pending_message=null;
      }
    return result;
  }

  public void run() 
  {
    //System.err.println("ScrollbarCh.run: Thread active ");
    for(;;) {
      try 
	{
	  AWTProtocol message=(AWTProtocol) toScrollbarCh.read(); // BLOCKs
	  switch (message.get_type()) {
	    case AWTProtocol.SET_VALUE:
	      int i=((Integer)message.get_arg()).intValue();
	      //System.err.println("ScrollbarCh.run: Got message SET_VALUE to "+i);
	      setValue(i);
	      repaint();
	      break;
	    default:
	      System.err.println("ScrollbarCh.run: Got unknown / unsupported message "+message.get_type());
	  }
	  my_thread.sleep(100);
	}
      catch (InterruptedException e)
	{
	  //System.err.println ("ScrollbarCh.run: Thread ending");
	  break;
	}
    } // for (;;)
  }
  
}



class ScrollbarEventHandler implements Runnable 
{
  private Thread my_thread;
  private Object_Channel event_Object_Channel;
  private ScrollbarCh scrollbarch;
  private AWTProtocol message=null;
  
  public ScrollbarEventHandler (Object_Channel event_Object_Channel, ScrollbarCh scrollbarch) 
  {
    my_thread=new Thread(this, "ScrollbarEventHandler");
    this.event_Object_Channel=event_Object_Channel;
    this.scrollbarch=scrollbarch;
    
    // Start my thread (configuration handler)
    my_thread.start();
  }
  
  public void run () 
  {
    //System.err.println("ScrollbarEventHandler.run: Thread active ");
    for(;;) {
      try 
	{
	  if (message == null) {
	    message=scrollbarch.test_and_reset_pending_message ();
	  }
	  if (message != null) {
	    event_Object_Channel.write(message);
	    message=null;
	  }
	  my_thread.sleep(100);
	}
      catch (InterruptedException e)
	{
	  //System.err.println ("ScrollbarEventHandler.run: Thread ending");
	  break;
	}
    } // for (;;)
  }


}
