import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;

        // This applet connects to a CGI script, sends a
        // QUERY_STRING to it and reads the response.
        // The URL of the script is specified by the "server" parameter.
        // The key of the query string to send is specified by the "key"
        // parameter.
        // The value of the query to be sent is input to a TextLine
        // and the response is displayed in a second TextLine when
        // the applet's Send button is pressed.
        // The applet uses a CGIClient object to conduct the interaction
        // with the CGI server.
public class CGIApplet extends Applet {
        // Setup the visual appearance of the applet.
    public void init() throws RuntimeException {
        // Provide rows for a header Label, two TextFields and a pair
        // of buttons.
        final int rows = 5, cols = 1;
        setBackground(Color.white);
        setLayout(new GridLayout(rows,cols));
        setupHeader();
        setupTextFields();
        setupButtons();
        // Check that all of the parameters are present.
        for(int i = 0; i < parameterInfo.length; i++){
            checkParameter(parameterInfo[i][0]);
        }
    }

        // Supply information on the parameters used.
    public String[][] getParameterInfo(){
        return parameterInfo;
    }
        
        // Create a CGIClient to send line as a query string to
        // a server. Both the server and they key for the query string
        // are supplied as parameters (server and key) to the applet.
        // Normal network restrictions apply to the applet's ability
        // to connect to the server.
    protected void sendLineToServer(String line){
        try{
            // Obtain the server URL and CGI key to use from the
            // parameters of this applet.
            String server = getParameter(parameterInfo[serverParameter][0]);
            if(server == null){
                throw new RuntimeException("Missing `server' parameter.");
            }
            String serverKey = getParameter(parameterInfo[keyParameter][0]);
            // Encode the line to be sent as the key's value.
            String keyValue = URLEncoder.encode(line);
            if(keyValue == null){
                throw new RuntimeException("Missing `key' parameter.");
            }

            // Create a client of the server and send the query.
            CGIClient client = new CGIClient(
                                server+"?"+serverKey+"="+keyValue);
            // Obtain and store the server's response in the reply line.
            String reply = client.getResponse();
            // Replace newline characters with spaces.
            reply = reply.replace('\n',' ');
            getReplyLine().setText(reply);
        }
        catch(Exception e){
            // Something went wrong. Show the exception as the reply.
            getReplyLine().setText(e.toString());
        }
    }

    protected void setupHeader(){
        String server = getParameter(parameterInfo[serverParameter][0]);
        if(server != null){
            Label header = new Label("Send a message to:",Label.CENTER);
            header.setBackground(Color.white);
            add(header);
            header = new Label(server,Label.CENTER);
            add(header);
        }
    }

        // Provide Send and Reply lines of text.
    protected void setupTextFields(){
        Panel sendPanel = new Panel();
        sendPanel.add(new Label("Send: "));
        TextField sendLine = getSendLine();
        sendPanel.add(sendLine);
        // Pressing Enter in the field should cause the line to be sent.
        sendLine.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                TextField send = getSendLine();
                sendLineToServer(send.getText());
            }
        });
        add(sendPanel);

        Panel replyPanel = new Panel();
        replyPanel.add(new Label("Reply: "));
        replyPanel.add(getReplyLine());
        add(replyPanel);
    }

       // Provide Send and Clear buttons. The Send action attempts
       // to send its contents to a server.
    protected void setupButtons(){
        Panel buttonPanel = new Panel();

        Button sendButton = new Button("Send");
        // Pressing this button should cause the line to be sent.
        sendButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                TextField send = getSendLine();
                sendLineToServer(send.getText());
            }
        });
        buttonPanel.add(sendButton);

        Button clearButton = new Button("Clear");
        clearButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                getSendLine().setText("");
                getReplyLine().setText("");
            }
        });
        buttonPanel.add(clearButton);

        add(buttonPanel);
    }

        // Retrieve the given parameter from the applet's properties.
    protected String checkParameter(String parameter) throws RuntimeException {
        String value = getParameter(parameter);
        if(value == null){
            throw new RuntimeException("Parameter: "+parameter+" is missing.");
        }
        return value;
    }

    protected TextField getSendLine(){
        return sendLine;
    }

    protected TextField getReplyLine(){
        return replyLine;
    }

    final int lineWidth = 40;
    private final Font font = new Font("SansSerif",Font.BOLD,10);
    {
        setFont(font);
    }

    private final TextField sendLine = new TextField("",lineWidth),
                            replyLine = new TextField("",lineWidth);
    {
        sendLine.setFont(font);
        replyLine.setFont(font);
    }
    // Provide information on the parameters expected by this applet.
    private final int serverParameter = 0, keyParameter = 1;
    private final String[][] parameterInfo = {
        { "server", "URL", "The server URL of the CGI script to contact.",
        },
        { "key",    "String",
          "The query string key name expected by the CGI script for input.",
        },
    };
}
