/*
 * $Log$
 */


package gui;

// Standard packages.
import java.applet.Applet;
import java.awt.*;
import java.util.*;
import java.net.URL;
import java.net.MalformedURLException;

// Network Design Tool Packages.
import network.*;
import general.GeneralProperties;
import general.Set;		// for network.switches
import gui.FramedPanel;
//////////////////////////////////////////////////
public class dWindowConstraints extends GridBagDialog {
  // swtArray references to the switch array of the network
  private Object[] cstArray;
  private GeneralProperties gpData;
  private Network network;
  private List list;		// Scrolling list of switches
  private int sel = -1;		// item in the list selected
  private Button bAdd, bRemove, bOk, bUpdate, bHelp;
  private Canvas c;
  private TextField tfName, tfSet1, tfSet2, tfAlpha, tfOmega;
  private Panel pButtons, pEdit, pSets;

  //--------------------------------------------------------
  public dWindowConstraints(Frame parent, GeneralProperties gp) {
    super(parent, "Constraints", false);
    gpData = gp;
    network = (Network)gpData.get("Network");

    // add pButtons panel
    pButtons = new Panel();
    pButtons.setLayout(new GridLayout(1,5));
    pButtons.add(bAdd = new Button("Add"));
    pButtons.add(bRemove = new Button("Remove"));
    pButtons.add(bOk = new Button("Ok"));
    pButtons.add(bUpdate = new Button("Update"));
    pButtons.add(bHelp = new Button("Help"));
    gbc.weightx = 0;
    gbc.weighty = 0;
    gbc.fill = GridBagConstraints.NONE;
    gbc.anchor = GridBagConstraints.CENTER;
    add(pButtons, 0, 8, 1, 1);

    // add pEdit Panel
    pEdit = new Panel();
    gbc.weightx = 100;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    pEdit.setLayout ( new GridLayout (2, 3));
    pEdit.add (new Label("Name"));
    pEdit.add (new Label("percent(set1->set2)"));
    pEdit.add (new Label("percent(set2->set1)"));
    tfName = new TextField ();
    tfAlpha = new TextField ();
    tfOmega = new TextField ();
    pEdit.add (tfName);
    pEdit.add (tfAlpha);
    pEdit.add (tfOmega);
    add(pEdit, 0, 4, 1, 2);

    // add pSets Panel
    pSets = new Panel();
    GridBagLayout pSetsGBL = new GridBagLayout();
    pSets.setLayout( pSetsGBL);
    GridBagConstraints pSetsGBC = new GridBagConstraints();
    pSetsGBC.gridx = 1;
    pSetsGBC.gridy = 1;
    pSetsGBC.gridwidth = 1;
    pSetsGBC.gridheight = 1;
    Label lSet1 = new Label("Set1");
    pSetsGBL.setConstraints(lSet1, pSetsGBC);
    pSets.add(lSet1);
    pSetsGBC.gridy = 2;
    Label lSet2 = new Label("Set2");
    pSetsGBL.setConstraints(lSet2, pSetsGBC);
    pSets.add(lSet2);

    tfSet1 = new TextField ();
    tfSet2 = new TextField ();
    pSetsGBC.gridx = 2;
    pSetsGBC.weightx = 100;
    pSetsGBC.fill = GridBagConstraints.HORIZONTAL;
    pSetsGBL.setConstraints(tfSet2, pSetsGBC);
    pSets.add(tfSet2);
    pSetsGBC.gridy = 1;
    pSetsGBL.setConstraints(tfSet1, pSetsGBC);
    pSets.add(tfSet1);
    add(pSets, 0, 6, 1, 2);

    // add List of Constraints
    list = new List(10, false);
    update();
    gbc.fill = GridBagConstraints.BOTH;
    gbc.weightx = 100;
    gbc.weighty = 100;
    add(list, 0, 0, 1, 4);  

    pack();
    show();
  }


  /**
   * update the contents in the list from Network.constraints
   */
  public void update() {
    network = (Network)gpData.get("Network");
    cstArray = network.constraints.getArray();
    list.clear();
    for( int i = 0; i < cstArray.length; i++ )
      list.addItem( cstArray[i].toString() ); 
    list.select(sel);
  }


  /**
   * add a new Constraint to the network.
   */
  public void addConstraint() {
    network.addConstraint();
    update();			// update the display
  }

  /**
   * remove the selected Constraint from the network.
   */
  public void removeConstraint() {
   if (sel < 0 || sel >= list.countItems())
     return;
   network.removeConstraint( ((SetPairConstraint)cstArray[sel]).getName() );
   update();
  }

  /** change the name of the selected switch */
  public boolean changeName() {
    SetPairConstraint spc = (SetPairConstraint)cstArray[sel];
    String newName = tfName.getText();
    return network.changeName(spc, newName);
  }

  public boolean action(Event evt, Object arg) {
    if (evt.target == bAdd) {
      addConstraint();
    }
    else if (evt.target == bRemove) {
      removeConstraint();
    }
    else if (evt.target == bOk) {
      hide();
      return true;
    }
    else if (evt.target == bUpdate) {
      update();
      return true;
    }
    else if (evt.target == bHelp) {
      String HelpURL = (String)gpData.
	get("Help URL for Window|Constraints Dialog Box"); 
      if( ((Boolean)gpData.get("In Applet?")).equals(Boolean.TRUE) ) {
	// Open connection to URL & display help. 
	try {
	  Applet app = (Applet)gpData.get("Applet");
	  app.getAppletContext().showDocument(new URL(HelpURL)); 
	}
	catch(MalformedURLException mfue) {
	  new dMessageBox((Frame)getParent(), "Help", "Help URL " + HelpURL
			  + " doesn't exist!", gpData, false, null);
	}
      }
      else {
	// Display Help Message in a Dialog Box.
	String HelpMsg = "Please visit " + HelpURL + " for help.";
	new dMessageBox((Frame)getParent(), "Help", HelpMsg, gpData, false,
			null); 
      }
      return true;
    }
    else if (evt.target instanceof TextField) {
      SetPairConstraint sltdSpc = (SetPairConstraint)cstArray[sel];
      if (evt.target == tfName) {
	if ( !changeName() ) {
	  String ErrMsg = "Can not change name. " + 
	    "Maybe this name is used by another Constraint";
	  new dMessageBox((Frame)getParent(), "Error", ErrMsg, gpData, false,
			  null); 	
	}
      }
      else if (evt.target == tfSet1) {
	Set set1 = network.readSwitchSet("{ " + tfSet1.getText() + " }");
	sltdSpc.setA(set1);
      }
      else if (evt.target == tfSet2) {
	Set set2 = network.readSwitchSet("{ " + tfSet2.getText() + " }");
	sltdSpc.setB(set2);
      }
      else if (evt.target == tfAlpha)
	sltdSpc.setOut ( (Double.valueOf(tfAlpha.getText())).doubleValue() );
      else if (evt.target == tfOmega)
	sltdSpc.setIn ( (Double.valueOf(tfOmega.getText())).doubleValue() );
      list.replaceItem(sltdSpc.toString(), sel);
    }
    return false;
  }

//---------------------------------------------
public boolean handleEvent(Event e) {
  if(e.id == Event.KEY_PRESS) {// To let components handle keyboard
				    // events. (required due to bug in java).
    return false;
  }
  else if(e.id == Event.WINDOW_DESTROY && 
     e.target == this)
    hide();
  else if (e.id == Event.LIST_SELECT) {
    sel = list.getSelectedIndex();
    SetPairConstraint sltdSpc = (SetPairConstraint)cstArray[sel];
    if (sel != -1) {
      tfName.setText (sltdSpc.getName());
      String str = String.valueOf(sltdSpc.getA());
      tfSet1.setText (str.substring(1, str.length()-1));
      str = String.valueOf(sltdSpc.getB());
      tfSet2.setText (str.substring(1, str.length()-1));
      tfAlpha.setText (String.valueOf(sltdSpc.getOut()));
      tfOmega.setText (String.valueOf(sltdSpc.getIn()));
    }
  }
  else
    super.handleEvent(e);
  return true;			    // No need to pass event to parent as
				    // the dialog box is anyway model. 
}

//************************************************
} // end of class dWindowConstraints

