package FDATI;

import JavaAgent.agent.*;
import java.awt.*;
import java.io.*;
import java.net.URL;
import java.util.*;
import SModeling.*;


/**
 * Panel for the CMU Fixture Design
 * and Analysis Tool Interface (FDATI). This panel allows the user
 * to load, delete and display multiple models.<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 FDATI extends Panel {
  
  /* Constants */
  
  static final int list_size = 5; /* size of model list */
  static final int horiz_space = 10; /* horiz spacing between components */
  static final int vert_space = 10; /* vertical spacing between components */
  static final int width = 300; /* width of main window */
  static final int height = 500; /* height of main window */
  static final int md_width = 600; /* width of modeldisplay window */
  static final int md_height = 500; /* height of modeldisplay window */
  
  /* Interface Components */
  
  Panel ButtonPanel = new Panel();
  Panel ModelPanel = new Panel();
  Panel ModelButtonPanel = new Panel();
  List LoadedModels = new List(list_size, false);
  Label LoadedModelLabel = new Label("Loaded Models");
  Button DisplayModel = new Button("Display Model");
  Button DeleteModel = new Button("Delete Model");
  Choice ModelFormat = new Choice();
  Label ModelFormatLabel = new Label("Model Format");
  TextField ModelName = new TextField(20); 
  Label ModelNameLabel = new Label("Model Name");
  TextField ModelURL = new TextField(20);
  Label ModelURLLabel = new Label("Model URL");
  Button LoadModel = new Button("Load Model");
  
  Button Quit = new Button("Quit Interface");
  Button SystemMessages = new Button("System Messages");
  StringBuffer system_messages = new StringBuffer();
  SystemMessagePanel message_panel = null;
  
  Color bg_color = new Color(150,150,200);
  Color button_color = Color.lightGray;
  
  private FDATService parent;
  private Agent agent;
  private Vector model_panels = new Vector();

  /**
   * Constructor for FDATI.
   */
  
  public FDATI(FDATService parent,Agent agent){
    this.parent = parent;
    this.agent = agent;
    setBackground(bg_color);
    ButtonPanel.setLayout(new GridLayout(4,2,horiz_space, vert_space));
    addComponents();
    ButtonPanel.add(Quit);
    Enumeration e = parent.Models.keys();
    while(e.hasMoreElements()){
      LoadedModels.addItem((String)e.nextElement());
    }
  }
  
  /**
   * Adds all components common to both stand alone and applet instantiations.
   */

  void addComponents(){

    setLayout(new BorderLayout());

    DisplayModel.setBackground(button_color);
    DeleteModel.setBackground(button_color);
    LoadModel.setBackground(button_color);
    ModelFormat.setBackground(button_color);
    Quit.setBackground(button_color);

    add("North",ModelPanel);
    add("Center",ButtonPanel);
    add("South",SystemMessages);
    
    ModelPanel.setLayout(new BorderLayout());
    ModelPanel.add("West",LoadedModelLabel);
    ModelPanel.add("Center",LoadedModels);
    ModelPanel.add("South", ModelButtonPanel);
    ModelButtonPanel.setLayout(new FlowLayout());
    ModelButtonPanel.add(DisplayModel);
    ModelButtonPanel.add(DeleteModel);
  
    ButtonPanel.add(ModelNameLabel);
    ModelName.setEditable(true);
    ButtonPanel.add(ModelName);
    ButtonPanel.add(ModelURLLabel);
    ModelURL.setEditable(true);
    ButtonPanel.add(ModelURL);
    ModelFormat.addItem(".obj format");
    ButtonPanel.add(ModelFormat);
    ButtonPanel.add(LoadModel);  
  }

  /**
   *  Called by components to signify an effect has occurred. Used by buttons.
   */
  
  public boolean action(Event evt, Object arg) {
    
    if("Quit Interface".equals((String)arg)) {
      stop();
    } else if("Load Model".equals((String)arg)) {
      if(ModelName.getText().length() > 0 &&
	 ModelURL.getText().length() > 0){
	LoadModelAction(ModelName.getText(), ModelURL.getText());
      } else {
	addSystemMessage("Name and URL were not correctly entered!");
      }
    } else if("Delete Model".equals((String)arg)) {
      DeleteModelAction();
    } else if("Display Model".equals((String)arg)) {
      DisplayModelAction();
    } else if("System Messages".equals((String)arg)){
      if(message_panel == null){
	Frame f = new Frame("System Messages");
	message_panel = new SystemMessagePanel(this,bg_color, button_color);
	message_panel.addSystemMessage(system_messages.toString());
	f.add("Center", message_panel);
	f.resize(width,height);
	f.show();
      }
    }
    
    return true;  
  }  

  protected void stop(){
    Enumeration e = model_panels.elements();
    while(e.hasMoreElements()){
      ((ModelPanel)e.nextElement()).stop();
    }
    Frame f = (Frame)getParent();
    f.dispose();
    parent.killFDATI();
  }

  void LoadModelAction(String name, String location) {
    
    ObjectFormatParser ofp = new ObjectFormatParser();
    
    try {
      URL url = new URL(location);
      if(agent.localIO()){
	File local_path = new File(agent.getSharedDir(), 
				   "files" + File.separator);
	File f = 
	  FileIO.remote_copy(url,local_path,name,
			     AgentParams.OVERWRITE);
	parent.model_files.put(name,f);
	FileInputStream fis = new FileInputStream(f);
	model m = ofp.ParseInputStream(fis);
	parent.Models.put(name,m);
	LoadedModels.addItem(name);
	show();
      }
    }  catch(Exception e){
      addSystemMessage("Problem loading model, " + e.toString());
    }
    
  }
    
  void DeleteModelAction() {
    
    if(LoadedModels.getSelectedIndex() >= 0 ){
      parent.Models.remove((String)LoadedModels.getSelectedItem());
      parent.model_files.remove((String)LoadedModels.getSelectedItem());
      LoadedModels.delItem(LoadedModels.getSelectedIndex());
    } else {
      addSystemMessage("No model is selected!");
    }

  }

  /**
   * Called to submit the current fixturing plan to the FDATAgent for
   * analysis.
   * @param name Name of the fixturing plan.
   * @param dir Directionality for analysis.
   * @param dim Dimensionality for analysis.
   * @param dir_vec Direction vector for "directional" analysis.
   * @param model The model whose fixture points are being analyzed.
   */

  void submit_fixels(String name, String dir, String dim, hpoint dir_vec,
		     model M){
    parent.submit_fixels(name,dir,dim,dir_vec,M);
  }
  
  void DisplayModelAction() {
    if(LoadedModels.getSelectedIndex() >= 0 ){
      String model_name = (String)LoadedModels.getSelectedItem();
      model m = (model)(parent.Models).get(model_name);
      
      if(m != null){
	addSystemMessage("model " + model_name + " selected");
	Frame f = new Frame("Model: " + model_name);
	ModelPanel mp = new ModelPanel(this, m, model_name, 
				       bg_color,button_color);
	mp.resize(md_width, md_height);
	model_panels.addElement(mp);
	f.add("Center", mp);
	f.resize(md_width, md_height);
	f.show();
      } else {
	addSystemMessage("Selected model is not valid!");
      }
    } else {
      addSystemMessage("No model is selected!");
    }
  }

  protected void addSystemMessage(String message){
    system_messages.append(message + "\n");
    if(message_panel != null){
      message_panel.addSystemMessage(system_messages.toString());
    }
  }

  public void killMessagePanel(){
    message_panel = null;
  }

}













