package irr;

/*
 * Copyright (c) 1997, 1998
 *      The Regents of the University of Michigan ("The Regents").
 *      All rights reserved.
 *
 * Contact: ipma-support@merit.edu
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by the University of
 *      Michigan and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *    
 */   

/* Options Menu
 *
 * Basic per session options such as Query server, submit server, password, 
 * databases.
 *
 * 5/3/99
 * Jon Poland
 */

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;
import java.io.*;
import ipma.Window.*;
import netscape.security.PrivilegeManager;

public class OptionsMenu extends CWindow{
  
  GetRequest gr;   /* passed in during creation, used to change servers */
  IRRWindow irrw; /* the parent IRRWindow */
  private Font f = new Font("Courier", Font.PLAIN, 12);
  
    Label      DBLabel = new Label("Query Databases");
    Label      QportLabel = new Label("Query Port  ");
    Label      QserverLabel = new Label("Query Server  ");
    Label      SserverLabel = new Label("Submit Server");
    Label      SportLabel = new Label("Submit port");
    Label      pwdLabel = new Label("Mntner Password");
    Label      pgpPwdLabel = new Label("PGP Password     ");
    Label      pgpUidLabel = new Label("PGP User ID        ");
    Label      pgpExecLabel = new Label("PGP executable   ");
    Label      pgpPathLabel = new Label("Absolute path to PGP rings");
    redLabel   statLabel = new redLabel();
  
  TextField  QtfServer = new TextField(20);
  TextField  QtfPort   = new TextField(5);
  TextField  StfServer = new TextField(20);
  TextField  StfPort   = new TextField(5);
  TextField  Passwd    = new TextField(15);
  TextField  pgpPwd = new TextField(15);
  TextField  pgpUid  = new TextField(15);
  TextField  pgpExec = new TextField(15);
  TextField  pgpPath = new TextField(25);
  // Connection stuff
  private InetAddress ia;
  
  // Listener stuff
  protected ActionListener al = new InnerActionListener();
  
  // String constants
  private String SUBMIT_STRING = "Ok";
  private String CLOSE_STRING  = "Cancel";
  private String DEFAULT_STRING = "Load Defaults";
  static final String WINDOW_TITLE = "General Options";
  
  private final String DEFAULT_SERVER = "radb1.merit.edu";
  private final String DEFAULT_QPORT = "43";
  private final String DEFAULT_SPORT = "8888";
  private final String DB_REQUEST = "!s-lc";
  private final String DB_RESET = "!s-*";
  private final String DB_SELECT = "!s";

    //Strings for saving state, for cancel button
    private String old_qserver;
    private String old_sserver;
    private String old_qport;
    private String old_sport;
    private String old_pwd;

  Vector v = new Vector();
  boolean b[];
  boolean old_b[];
  int old_size;

  Panel DB;

  protected ItemListener il = new InnerItemListener ();;
  
  public OptionsMenu(GetRequest g_r, IRRWindow irr_win){
    super.setTitle(WINDOW_TITLE);
    gr = g_r;
    irrw = irr_win;
   
    Passwd.setEchoChar('*');
    pgpPwd.setEchoChar('*');

    int bytes = gr.getNewRequest(DB_REQUEST);
    if (bytes < 1) return;
    String s = gr.getBuffer();
    if (s == null) return;
    BuildLayout(s.trim());
    addWindowListener(new InnerWindowAdapter ());
    old_qserver = QtfServer.getText();
    old_sserver = StfServer.getText();
    old_qport = QtfPort.getText();
    old_sport = StfPort.getText();
    old_pwd = Passwd.getText();
    for(int i=0;i<v.size();i++){
      old_b[i] = b[i];
    }
    old_size = v.size();
    pack();
    show();
  }
  
  protected void BuildLayout(String s){

    
    Panel p = new Panel();
    GridBagLayout  g = new GridBagLayout();
    p.setLayout(g);
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    gbc.anchor = GridBagConstraints.WEST;

    String str;
    int index=0;
   

    StringTokenizer st = new StringTokenizer(s,",");
    DB = new Panel();
    DB.setLayout(g);
    g.setConstraints(DBLabel, gbc);
    /*DB.add(DBLabel);*/
   
    b = new boolean[st.countTokens()];
    old_b = new boolean[st.countTokens()];
    Checkbox CB;
    while (st.hasMoreTokens()){
      str = st.nextToken();
      v.addElement(str);
      b[index++] = true;
      CB = new Checkbox(str,null,true);
      g.setConstraints(CB, gbc);
      DB.add(CB);
      CB.addItemListener(il);
    }
  
    add(DB, "North");

    Panel serverP = new Panel();
    serverP.add(QserverLabel);
    QtfServer.setText(gr.getSockInfo());
    serverP.add(QtfServer);
    QtfPort.setText(gr.getPort());
    serverP.add(QportLabel);
    serverP.add(QtfPort);
    
    g.setConstraints(serverP, gbc);
    p.add(serverP);
  
    
    Panel S = new Panel();
    S.add(SserverLabel);
    StfServer.setText(gr.getSockInfo());
    StfPort.setText(DEFAULT_SPORT); 
    S.add(StfServer);
    S.add(SportLabel);
    S.add(StfPort);
    g.setConstraints(S, gbc);
    p.add(S);
 
    
    Panel Pass = new Panel();
    Pass.add(pwdLabel);
    Pass.add(Passwd);
    g.setConstraints(Pass, gbc);
    p.add(Pass);
     Pass = new Panel();
    Pass.add(pgpPwdLabel);
    Pass.add(pgpPwd);
    g.setConstraints(Pass, gbc);
    p.add(Pass);
     Pass = new Panel();
    Pass.add(pgpUidLabel);
    Pass.add(pgpUid);
    g.setConstraints(Pass, gbc);
    p.add(Pass);
     Pass = new Panel();
    Pass.add(pgpExecLabel);
    Pass.add(pgpExec);
    g.setConstraints(Pass, gbc);
    p.add(Pass);
     Pass = new Panel();
    Pass.add(pgpPathLabel);
    Pass.add(pgpPath);
    g.setConstraints(Pass, gbc);
    p.add(Pass);
    p.add(statLabel);
    add(p);
    
    p = new Panel();
    Button tmpButton = new Button(SUBMIT_STRING);
    tmpButton.addActionListener(al);
    p.add(tmpButton);
    tmpButton = new Button(CLOSE_STRING);
    tmpButton.addActionListener(al);
    p.add(tmpButton);
    tmpButton = new Button(DEFAULT_STRING);
    tmpButton.addActionListener(al);
    p.add(tmpButton);
    add("South",p);
  }
  public void updateLayout(){
    statLabel.invalidate();
    validateTree();
  }
  public void showAgain(){
      old_qserver = QtfServer.getText();
      old_sserver = StfServer.getText();
      old_qport = QtfPort.getText();
      old_sport = StfPort.getText();
      old_pwd = Passwd.getText();
      for(int i=0;i<v.size();i++)
	old_b[i] = b[i];
      old_size = v.size();
    setVisible (true);
  }
  
  protected void changeDB(){
    String request = new String();
    try{
      for(int i=0;i<v.size();i++){
	if(b[i])
	  request += ","+(String)v.elementAt(i);
      }
      request = request.substring(1);
	  gr.getNewRequest(DB_SELECT+request);
	  setVisible (false);
    }
    catch(StringIndexOutOfBoundsException o){
      /*System.out.print("No change in DB, DB empty");
      setVisible(false);*/
      statLabel.setText("ERROR: No sources selected");
      updateLayout();
      return;
    }
    setVisible(false);
  }
  protected void handleSubmit(){
    if( !(gr.getSockInfo().equals(QtfServer.getText().trim())) ||
	!(gr.getPort().equals(QtfPort.getText().trim())) ){
      /**** Netscape Security stuff */
      try {
	PrivilegeManager.enablePrivilege ("UniversalConnect");
	//System.out.print("***Permission enable to Options****\n");
      }
      catch (netscape.security.ForbiddenTargetException err) {
	System.out.print("*Access Denied to connect, exiting*\n");
	System.exit(1);
      }
      /******************************/
      int newPort = getPort(QtfPort.getText().trim());
      if(newPort > 65535 || newPort <= 0){
	newPort = getPort(gr.getPort());
	QtfPort.setText(Integer.toString(newPort));
	return;
      }
      
      try{
	InetAddress Qserv = InetAddress.getByName(QtfServer.getText().trim());
      }
      catch(UnknownHostException e){
	statLabel.setText("Invalid Query host entered");
	updateLayout();
	return;
      }
      try{
	InetAddress Sserv = InetAddress.getByName(StfServer.getText().trim());
      }
      catch(UnknownHostException e){
	statLabel.setText("Invalid Submit host entered");
	updateLayout();
	return;
      }
      irrw.changeServer(QtfServer.getText().trim(), newPort);
      newPort = getPort(StfPort.getText().trim());
      if(newPort > 65535 || newPort <= 0){
	newPort = getPort(gr.getPort());
	StfPort.setText(Integer.toString(newPort));
	return;
      }
      gr = irrw.gr;
      updateDbList();
      setVisible(false);
    }
    else
      changeDB();
    /*setVisible(false);*/
  }

  /* called to rebuild the list of available databases after a server change */
  public void updateDbList(){
    int bytes = gr.getNewRequest(DB_RESET);
    bytes = gr.getNewRequest(DB_REQUEST);
    if (bytes < 1) return;
    String s = gr.getBuffer();
    //System.out.print("Updating to "+s);
    if (s == null) return;
     
    DB.invalidate();
    remove(DB);
    
    GridBagLayout g = new GridBagLayout();
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    gbc.anchor = GridBagConstraints.WEST;

    DB = new Panel();
    g.setConstraints(DBLabel, gbc);
    DB.add(DBLabel);
    StringTokenizer st = new StringTokenizer(s,",");
    DB.setLayout(g);
    b = new boolean[st.countTokens()];
    v = new Vector();
    Checkbox CB;
    String str;
    int index = 0;
    while (st.hasMoreTokens()){
      str = st.nextToken();
      v.addElement(str);
      b[index++] = true;
      CB = new Checkbox(str,null,true);
      g.setConstraints(CB, gbc);
      DB.add(CB);
      CB.addItemListener(il);
    }
    add(DB, "North");
  }


  public int getPort(String p){
    int i;
    try{
      i = Integer.valueOf(p).intValue();
    }
    catch(NumberFormatException f){
      i = getPort(gr.getPort());
    }
    return i;
  }
    
    public void Close(){
	super.Close();
    }

   class InnerActionListener implements ActionListener {
      public void actionPerformed (ActionEvent e) {
         String label = e.getActionCommand ();
         
         if (label.equals (CLOSE_STRING)) {
	     QtfServer.setText(old_qserver);
	     StfServer.setText(old_sserver);
	     QtfPort.setText( old_qport );
	     StfPort.setText(old_sport);
	     Passwd.setText(old_pwd);
	     statLabel.setText("");
	     /* Checkbox cbs[] = (Checkbox[])DB.getComponents();*/
	    
	     for(int i=0;i<old_size;i++){
	       b[i] = old_b[i];
	       Checkbox cb = (Checkbox)DB.getComponent(i);
	       cb.setState(old_b[i]);
	     }
	     setVisible (false);
         }
         else if (label.equals (SUBMIT_STRING)) {
	   statLabel.setText("");
	     handleSubmit();
         }
	 else if (label.equals ( DEFAULT_STRING)) {
	   QtfServer.setText(DEFAULT_SERVER);
	   QtfPort.setText(DEFAULT_QPORT);
	   StfServer.setText (DEFAULT_SERVER);
	   StfPort.setText (DEFAULT_SPORT);
	   updateDbList();
	   updateLayout();
       }
      }
   }
   
   class InnerWindowAdapter extends WindowAdapter {
      public void windowClosing (WindowEvent e) {
         setVisible (false);
      }
   }

   class InnerItemListener implements ItemListener {
      public void itemStateChanged (ItemEvent e) {
         Checkbox box = (Checkbox)e.getSource();
         int i = v.indexOf(box.getLabel());   
         b[i] = (boolean)box.getState();
      }
   }
     
    
   
} // End of class definition
