import java.awt.*;
import java.awt.event.*;

        // Implement a Search Dialog to enable strings to be searched
        // for in the current file. A text field contains the string
        // to be searched for, or one may be selected from a list
        // of previous strings. Checkboxes select either forward
        // or backward direction and case sensitivity.

class SearchDialog extends Dialog implements ItemListener, ActionListener {
    public SearchDialog(Frame frame){
        super(frame,"Search",true);
        final int width = 325, height = 200;
        setSize(width,height);
        setBackground(Color.white);

        final int rows = 5, cols = 1;
        setLayout(new GridLayout(rows,cols));
        setBackground(Color.white);

        // Setup the five panels.
        setupSearchPanel();
        setupPreviousPanel();
        setupCheckBoxes();
        setupButtonPanel();

        pack();
    }

        // Return the string to be searched for.
    public String getSearchString(){
        String s = "";
        TextField field = getSearchField();

        if(field != null){
            s = field.getText();
        }
        return s;
    }

        // Return true if the search should be forward, and false otherwise.
        // Do this by comparing the label of the selected box against
        // forwardLabel.
    public boolean searchIsForward(){
        CheckboxGroup direction = getDirection();
        Checkbox dir = direction.getSelectedCheckbox();
        return forwardLabel.equals(dir.getLabel());
    }

        // Return true if the search is case sensitive, and false otherwise.
    public boolean isCaseSensitive(){
        Checkbox sensitive = getCaseSensitive();
        return sensitive.getState();
    }

        // Implementation of ItemListener.
        // A selection has been made from the Choice.
        // Copy the selected string to the search field.
    public void itemStateChanged(ItemEvent e){
        if((e.getStateChange() & ItemEvent.SELECTED) == ItemEvent.SELECTED){
            Object o = e.getItem();
            if(o instanceof String){
                String s = (String) o;
                TextField field = getSearchField();
                field.setText(s);
            }
            else{
                System.err.println("Item isn't a string.");
            }
        }
        else{
            System.err.println("Choice wasn't selected.");
        }
    }

    // Implementation of ActionListener.
    public void actionPerformed(ActionEvent e){
        // The command to be acted on.
        String command;

        // Separate an event generated by typing Return in a
        // text component from one generated by a button.
        if(e.getSource() instanceof TextComponent){
            command = startFindString;
        }
        else{
            command = e.getActionCommand();
        }

        // Obey the command.
        if(command == null){
        }
        else if(command.equals("")){
        }
        else if(command.equals(startFindString)){
            // Get things ready for Find.
            String s = getSearchString();
            if((s != null) && !s.equals("")){
                // Copy the latest string to the list of previous strings.
                // Don't add if it is already there.
                Choice choiceList = getPreviousStrings();
                int numItems = choiceList.getItemCount();
                int index;
                for(index = 0; index < numItems; index++){
                    String previous = choiceList.getItem(index);
                    if(s.equals(previous)){
                        // Found it.
                        break;
                    }
                }
                if(index == numItems){
                    // It wasn't found.
                    choiceList.add(s);
                }
            }
            // Hide the dialog.
            setVisible(false);
        }
        else if(command.equals(cancelFindString)){
            setSearchString("");
            // Hide the dialog.
            setVisible(false);
        }
        else{
            System.err.println("Unknown action command: "+command);
        }
    }

        // Set up the Search text field.
    protected void setupSearchPanel(){
        // The string and previous strings.
        Panel searchTextPanel = new Panel();
        final int searchLength = 20;
        TextField searchField = new TextField("",searchLength);
        searchField.setBackground(Color.white);
        // Let the dialog know when the Return key is pressed.
        searchField.addActionListener(this);
        searchTextPanel.add(new Label("Search for:"));
        searchTextPanel.add(searchField);
        setSearchField(searchField);
        add(searchTextPanel);
    }

        // Set up the Choice component for previous strings.
    protected void setupPreviousPanel(){
        Panel searchPreviousPanel = new Panel();
        Choice previousStrings = getPreviousStrings();
        searchPreviousPanel.add(new Label("Previous:"));
        searchPreviousPanel.add(previousStrings);
        // The dialog needs to know when an item is selected,
        // so that it can copy it to the search field.
        previousStrings.addItemListener(this);
        add(searchPreviousPanel);
    }

        // Set up the check boxes for search direction and
        // case sensitivity.
    protected void setupCheckBoxes(){
        // The case-sensitive check box in its own panel.
        // Placing it in a panel improves the layout.
        Checkbox caseSensitive = new Checkbox("Case sensitive",false);
        setCaseSensitive(caseSensitive);
        Panel caseSensitivePanel = new Panel();
        caseSensitivePanel.add(caseSensitive);
        add(caseSensitivePanel);

        // Group the direction boxes in a panel.
        Panel checkPanel = new Panel();
        CheckboxGroup direction = new CheckboxGroup();
        Checkbox forward = new Checkbox(forwardLabel,direction,true);
        Checkbox backward = new Checkbox(backwardLabel,direction,false);
        checkPanel.add(forward);
        checkPanel.add(backward);
        setDirection(direction);
        add(checkPanel);
    }

        // Set up the buttons for Find and Cancel.
    protected void setupButtonPanel(){
        Panel buttonPanel = new Panel();
        Button find = new Button("Find");
        find.setActionCommand(startFindString);
        // The dialog needs to know when the Find button is pressed
        // so that it can transfer the string to the previous
        // strings Choice.
        find.addActionListener(this);
        Button cancel = new Button("Cancel");
        cancel.setActionCommand(cancelFindString);
        cancel.addActionListener(this);
        buttonPanel.add(find);
        buttonPanel.add(cancel);
        add(buttonPanel);
    }

                // Accessors and mutators for the components.
        // Set the text of the search field.
    protected void setSearchString(String s){
        if(s != null){
            TextField field = getSearchField();
            field.setText(s);
        }
    }

    protected TextField getSearchField(){
        return searchField;
    }

    protected void setSearchField(TextField f){
        searchField = f;
    }

    protected Choice getPreviousStrings(){
        return previousStrings;
    }

    protected void setPreviousStrings(Choice c){
        previousStrings = c;
    }

    protected CheckboxGroup getDirection(){
        return direction;
    }

    protected void setDirection(CheckboxGroup d){
        direction = d;
    }

    protected Checkbox getCaseSensitive(){
        return caseSensitive;
    }

    protected void setCaseSensitive(Checkbox c){
        caseSensitive = c;
    }

    // The field containing the search string.
    private TextField searchField;
    // The previous search strings.
    private Choice previousStrings = new Choice();
    // Group the forward and backward Checkboxes.
    private CheckboxGroup direction;
    // Labels for the Forward and Backward Checkboxes
    private String forwardLabel = "Forward", backwardLabel = "Backward";
    // The case-sensitive Checkbox.
    private Checkbox caseSensitive;
    // Action commands for the button actions.
    private String startFindString = "StartFind",
                   cancelFindString = "CancelFind";
}
