import java.applet.Applet;

import java.awt.*;

import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.StringBufferInputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.io.StreamCorruptedException;

import java.net.URL;
import java.net.MalformedURLException;

import java.util.Vector;
import java.util.Enumeration;
import java.util.Hashtable;

import com.extropia.net.JavaCGIBridge;
import com.extropia.net.JavaCGIBridgeExtension;
import com.extropia.net.JavaCGIBridgeTimeOutException;

public class Example6Applet extends Applet {
    private Button _displayImageButton = new Button("Display Image");
    private List _chooseFileList = new List();

    private Example6DrawPanel _drawPanel = new Example6DrawPanel(this);

    private String _cgiURL = null;
    private String _makeImageURL = null;

    private byte [] _imageType1;
    private byte [] _imageData1;

    private byte [] _imageType2;
    private byte [] _imageData2;

    private Image _currentImage;

    public void init() {

        this.setBackground(Color.white);
        setLayout(new BorderLayout());

        Panel p = new Panel();
        p.setLayout(new BorderLayout());
        add("South", p);
        add("Center", _drawPanel);
        
        p.add("North", _chooseFileList);
        p.add("South", _displayImageButton);
       
        getSetupFile();        
        getImageData();
        repaint();
        // The following is done to fix a Mac NS 3.0 refresh problem
        hide();
        show();

    } // end of init method

    public boolean handleEvent(Event e) {
        if (e.id == Event.ACTION_EVENT && e.target == _displayImageButton) {
            clicked_imageDisplayButton();
        }
        return super.handleEvent(e);
    }

    private void clicked_imageDisplayButton() {
        JavaCGIBridgeExtension jcbe = new JavaCGIBridgeExtension();
        byte [] returnedData = null;
        URL u = null;

        try {
            if (_cgiURL.startsWith("http")) {
                 u = new URL(_makeImageURL); 
            } else {
                 u = new URL(getDocumentBase(), _makeImageURL);
            }
            
            ByteArrayOutputStream baos = jcbe.getByteArrayOutputStream();
            String file = _chooseFileList.getSelectedItem();
            byte [] type;
            byte [] data;
            if (file.indexOf("gif") != -1) {
                type = _imageType1;
                data = _imageData1;
            } else {
                type = _imageType2;
                data = _imageData2;
            }

            baos.write(type,0,type.length);
            baos.write('\n');
            baos.write(data,0,data.length);

            returnedData = jcbe.getRawData(u);

            if (file.indexOf("gif") != -1) {
              _currentImage = getImage(getDocumentBase(),"TempImage/temp.gif");
            } else {
              _currentImage = getImage(getDocumentBase(),"TempImage/temp.jpg");
            }
            try {
                MediaTracker tracker = new MediaTracker(this);
                tracker.addImage(_currentImage,0);
                tracker.waitForID(0);
            } catch (InterruptedException e) {
                System.out.println("Caught interrupted exception:" + e);
            }
            _drawPanel.setCurrentImage(_currentImage);
            _drawPanel.repaint();

        } catch (MalformedURLException e) {
            System.out.println("Malformed URL Exception:" + e);
        } catch (JavaCGIBridgeTimeOutException e) {
            System.out.println("JavaCGIBridge Timed Out:" + e);
        } catch (IOException e) {
            System.out.println("IOException: " + e);
        }

    }

    private void getSetupFile() {

        JavaCGIBridge jcb = new JavaCGIBridge();
        // Since we are reading a setup file, we just want
        // to make it into a variable=value format instead of the
        // funky ~|~ seperator that is the default. This makes the
        // setup file easier to read at the risk of making sure a 
        // particular variable does not have an equal symbol in its
        // value.
        jcb.setFieldSeparator("=");

        Vector returnedDataSet = null;
        Hashtable keyValuePairs = null;

        try {
            URL u = new URL(getDocumentBase(), "setup.html");
            returnedDataSet = jcb.getParsedData(u);

            if (returnedDataSet == null) {
                System.out.println("returned data set is null for some reason, probably a missing setup file");
            }

            // We call the function below since the vectors that 
            // are returned contain setup information in the form of
            // the first field being a key (variable) and the second
            // field being a value to the key

            keyValuePairs = jcb.getKeyValuePairs(returnedDataSet);

        } catch (MalformedURLException e) {
            System.out.println("Malformed URL Exception:" + e);
        } catch (JavaCGIBridgeTimeOutException e) {
            System.out.println("JavaCGIBridge Timed Out:" + e);
        }
 
        _cgiURL = (String)keyValuePairs.get("cgiURL");
        _makeImageURL = (String)keyValuePairs.get("makeImageURL");

    } // end of getSetupFile

    private void getImageData() {

        JavaCGIBridge jcb = new JavaCGIBridge();
        jcb.setRecordSeparator("__CabbageNeck_Peter_Joe_Erik_Mark_Anthony_David_987XxX\n");
        jcb.setFieldSeparator("__XxXxXxXxXxXx__");
        jcb.setParseAsRaw(true);

        URL u = null;
        Vector returnedDataSet = null;

        try {
            if (_cgiURL.startsWith("http")) {
                 u = new URL(_cgiURL);
            } else {
                 u = new URL(getDocumentBase(), _cgiURL);
            }

            // Increase timeout for old slow Macs
            jcb.setTimeOut(30000);

            returnedDataSet = jcb.getParsedData(u);

            if (returnedDataSet == null) {
                System.out.println("returned data set is null for some reason, probably a missing setup file");
            }

            // Now we set up the image data

            byte [] b = (byte []) ((Vector)returnedDataSet.elementAt(0)).elementAt(0);
            _imageType1 = b;

            b = (byte []) ((Vector)returnedDataSet.elementAt(1)).elementAt(0);
             _imageData1 = b;

            _chooseFileList.addItem("java.gif");
     
            b = (byte []) ((Vector)returnedDataSet.elementAt(2)).elementAt(0);
            _imageType2 = b;

            b = (byte []) ((Vector)returnedDataSet.elementAt(3)).elementAt(0);
            _imageData2 = b;
  
            _chooseFileList.addItem("cgi.jpg");
            _chooseFileList.select(0);

        } catch (MalformedURLException e) {
            System.out.println("Malformed URL Exception:" + e);
        } catch (JavaCGIBridgeTimeOutException e) {
            System.out.println("JavaCGIBridge Timed Out:" + e);
        }

    } // end of getImageData

} // end of ExampleApplet
