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);
  }
}
