package RemoteService.context;

import ImageSelector.*;
import RemoteService.agent.*;
import RemoteService.resource.*;
import JavaAgent.context.*;
import JavaAgent.resource.*;
import JavaAgent.agent.FileIO;

import java.io.*;
import java.awt.*;
import java.util.*;
import java.net.URL;

/**
 * Provides a generic interface for all agents in the RemoteService package.
 * Each AvailableService is represented by a gif thumbnail and a description 
 * file. The thumbnails are displayed in a scrollable canvas, and when 
 * selected, the description for that service is shown in the description
 * text area. Double clicks on thumbnails are detected but not acted on.<p>
 *
 * <hr>
 * Copyright (c) 1995, H. Robert Frost, Stanford University.
 * All rights reserved.<p>
 * Copyright (c) 1996, H. Robert Frost, Enterprise Integration Technologies,
 * Inc. All rights reserved.<p>
 *
 * RESTRICTED RIGHTS LEGEND: Use, duplication or disclosure by the 
 * Government is subject to restrictions as set forth in 
 * subparagraph(c)(1)(ii) of the Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 and in similar clauses in the
 * FAR and NASA FAR supplement.<p>
 * 
 * This software is bound by the terms and conditions listed in the
 * attached <a href="../LICENSE">LICENSE file</A>.
 * <hr>
 * @author <A HREF="http://cdr.stanford.edu/html/people/frost-bio.html"> Rob Frost</A>
 * @version 0.3 5/21/96 for Java(tm) Language Version 1.0.2
 */

public class RSFrame extends AgentFrame {
 
  protected PictureBrowser pb; /* link ps w/ tdc */
  protected PictureSelector ps; /* displays thumbnails */
  protected TextDisplayCanvas tdc; /* displays text descrips of thumbnails */
  protected Panel ServicePanel = new Panel();
  protected Panel BottomPanel = new Panel();
  protected Panel StatPanel = new Panel();
  protected final int CLIENT_WINDOW_TYPE=1000; /* event id for image selection */
  protected Vector names = new Vector();
 
  /**
   * Constructor for an RS Frame. Creates GUI components.
   * @param context AgentContext which created this gui.
   * @param title Title for the frame.
   */

  public RSFrame(AgentContext context, String title){
    super(context,title);
  
    setMenuBar(Controls);
    Controls.add(Action);
    Action.add(Quit);
    Controls.add(Messages);
    Messages.add(ComposeMessage);
    Messages.add(ViewMessage);
    Messages.add(LoadMessage);
    Controls.add(Resources);
    Resources.add(ViewResource);
    Resources.add(LoadResource);
    Controls.add(Help);
    Help.add(HelpAbout);
    Controls.setHelpMenu(Help);
    setLayout(new BorderLayout());
    tdc=new TextDisplayCanvas("Service Description",RSContextParams.TD_WIDTH,
			      RSContextParams.TD_HEIGHT);
    ps=new PictureSelector("Services",RSContextParams.PS_WIDTH,
			   RSContextParams.PS_HEIGHT);
    try{
      pb= new PictureBrowser(tdc,ps);
    } catch (IOException e){
      addSystemMessage("Could not create the PictureBrowser.");
    }
 
    /* set up event forwarding */
    pb.toNotify=this;
    pb.notification=new Event(pb,CLIENT_WINDOW_TYPE,null);

    ServicePanel.setLayout(new BorderLayout());
    ServicePanel.resize(new Dimension(RSContextParams.PS_WIDTH,
				      RSContextParams.PS_HEIGHT + 
				      RSContextParams.TD_HEIGHT));
    BottomPanel.setLayout(new BorderLayout());
    BottomPanel.add("Center",StatPanel);
    BottomPanel.add("South",new Button("System Messages"));
    StatPanel.setLayout(new GridLayout(1,4));
    StatPanel.add(new Label("Received:"));
    StatPanel.add(NumReceived);
    NumReceived.setBackground(Color.white);
    StatPanel.add(new Label("Sent:"));
    NumSent.setBackground(Color.white);
    StatPanel.add(NumSent);
    add("South",BottomPanel);
    add("Center",ServicePanel);
    ServicePanel.add("North",ps);
    ServicePanel.add("South",tdc);
  }

  /**
   * Called when an event happens in the RSFrame. Used to take action
   * on menu bar selections.
   *
   * @param evt The event which triggered the method call.
   * @param arg Who called the method. For buttons, string name of button.
   */

  public boolean action(Event evt, Object arg) {  
    return super.action(evt,arg);
  }

  /**
   * Handles double-clicks on service thumbnails.
   */

  public boolean handleEvent(Event evt) {

    /**
     * evt.y: 1 if double.
     * evt.x: index of image.
     */
    
    /* A Service image was double clicked */
    if ((evt.id==CLIENT_WINDOW_TYPE)
	&& (evt.target instanceof PictureBrowser)) {
      if (evt.y==1) {
	/* Run the selected Service */
	doubleClickAction(evt.x);
	return true;
      }
    }
    return super.handleEvent(evt);
  }

  /**
   * Terminates all of the panels.
   */

  protected void terminatePanels(){
    super.terminatePanels();
  }

  /**
   * Called when one of the Service icons is double-clicked, must be
   * overridden.
   * @param index Index of the selected icon.
   */

  protected void doubleClickAction(int index){}

  /**
   * Called when some Agent resource has changed, needs to be overridden.
   * @param type String identifying the type of the resource.
   */

  public void resourceChanged(String type){
    if(type.equals("available_service")){
      getServices();
    } else {
      super.resourceChanged(type);
    }
  }

  /**
   * Gets the available services from the DesignAgent, adds new services
   * and removes services which are no longer present.
   */

  protected void getServices(){
    AvailableServices avail_services = 
      (AvailableServices)getAgent().getResource("available_service");
    Enumeration service_names = avail_services.getElements();

    /* Add new services */
    while(service_names.hasMoreElements()){
      try {
	
	AvailableService as = 
	  (AvailableService)avail_services.getElement(service_names.nextElement(),
				    Resource.NO_RETRIEVAL);
	if(!names.contains(as.name)){
	  addService(as.name,as.gif.toString(),getDescription(as));
	}
      } catch (ResourceException e){
	addSystemMessage("Error getting services, " +  e.toString());
      }
    }
    /* Removes absent services */
    Enumeration present = names.elements();
    while(present.hasMoreElements()){
      String service = (String)present.nextElement();
      if(!avail_services.hasElement(service)){
	removeService(service);
      }
    }
  }

  /**
   * Removes the named Service from the display.
   */
  
  protected void removeService(String name){
    int n = names.indexOf(name);
    if (n!=-1) {
      names.removeElementAt(n);
      pb.deleteItem(n);
    }
    ps.forceRepaint();
  }

  /**
   * Adds the gif and descrip for a specific Service to the Window.
   */

  protected void addService(String name,String gifFile,String descr) {
    Image im=Toolkit.getDefaultToolkit().getImage(gifFile);
    pb.addItem(im,descr);
    names.addElement(name);
    ps.forceRepaint();
  }
  
  /**
   * Called to get the description String from the
   * specified service.
   * @param service name of the service.
   */
	
  protected String getDescription(AvailableService as){
    if(as.descrip == null){
      addSystemMessage("File " + as.descrip.getName() + " is null");
    }
    if(getAgent().localIO()){
      try{
	byte[] descrip_bytes = 
	  FileIO.read_from_URL(new URL("file:" + as.descrip.toString()));
   	String descrip = new String(descrip_bytes,0);
	return descrip;
      } catch (Exception e){
	addSystemMessage("Failed to read descrip file, " +
			 e.toString());
      }
    }
    return null;
  }
}



















