import java.awt.*;
import java.io.*;
import java.net.*;
import Raster;

class ppmDecoder {
    private Raster imgRaster;
    private int width, height, range;

    /**
     * ppmDecoder(): default constructor does nothing
     */
    public ppmDecoder() {
    }

    public Image getImage(URL url, String filename) {
        Image img = null;
        try {
            img = getImage(new URL(url, filename));
        } catch (MalformedURLException e) {
            System.err.println("Malformed URL Exception: " + e.getMessage());
        }
        return img;
    }

    public Image getImage(URL url) {
        Image img = null;
        try {
            InputStream is = url.openStream();
    	    StreamTokenizer st = new StreamTokenizer(is);
        	st.eolIsSignificant(false);
        	st.commentChar('#');
        	String type;

            type = getString(st);
            width = getNumber(st);
            height = getNumber(st);
            range = getNumber(st);
            imgRaster = new Raster(width, height);

            int pix;
            if ("P2".equals(type)) {     // gray ascii
                for (int y = 0; y < height; y++) {
                    for (int x = 0; x < width; x++) {
                        pix = getNumber(st);
                        pix = ((((0xff00 + pix) << 8) + pix) << 8) + pix;
                        imgRaster.setPixel(pix, x, y);
                    }
                }
            } else
            if ("P3".equals(type)) {     // rgb ascii
               for (int y = 0; y < height; y++) {
                    for (int x = 0; x < width; x++) {
                        pix = 0xff00 + getNumber(st);
                        pix = (pix << 8) + getNumber(st);
                        pix = (pix << 8) + getNumber(st);
                        imgRaster.setPixel(pix, x, y);
                    }
                }
            } else
            if ("P5".equals(type)) {     // gray binary
                for (int y = 0; y < height; y++) {
                    for (int x = 0; x < width; x++) {
                        pix = is.read();
                        pix = ((((0xff00 + pix) << 8) + pix) << 8) + pix;
                        imgRaster.setPixel(pix, x, y);
                    }
                }
            } else
            if ("P6".equals(type)) {     // rgb binary
                for (int y = 0; y < height; y++) {
                    for (int x = 0; x < width; x++) {
                        pix = 0xff00 + is.read();
                        pix = (pix << 8) + is.read();
                        pix = (pix << 8) + is.read();
                        imgRaster.setPixel(pix, x, y);
                    }
                }
            } else
                System.err.println("Invalid format: " + type);
            is.close();
            img = imgRaster.toImage();
        } catch (IOException e) {
            System.err.println("IO Exception: " + e.getMessage());
        }
        return img;
    }

   private String getString(StreamTokenizer st) throws IOException {
        if (st.nextToken() != StreamTokenizer.TT_WORD)
            throw new IOException("Unexpected symbol");
        return st.sval;
    }

    private int getNumber(StreamTokenizer st) throws IOException {
        if (st.nextToken() != StreamTokenizer.TT_NUMBER)
            throw new IOException("Unexpected symbol");
        return ((int) st.nval);
    }
}