// Paul Johnson Feb.3, 2001
// This is my effort to build a class that can substitute for Swarm's ZoomRaster.
// There is a layer of pixels, accessed from agents by the same drawPointX$Y() 
// as in the objc swarm.
// I also wanted to be able to draw SHAPES and TEXT and IMAGES on TOP of the
// raster dots.  

// I ended up taking this approach that the Raster object buffers the pixels,
// strings, rectangles, filled rectangles, and images.  It does this by creating
// objects that it stores in a collection, each time it is told to add a feature
// in the picture.  Then at paint() time,
// it draws the pixels first, and then goes through the collections of shapes,
// strings, and images.

// This seemed kludgy to me, but every other way I tried would not layer
// the things in the right order.  One problem is that, as this thing runs, the 
// text, which is supposed to be shown with the dots, does not always keep up.

import swarm.Globals;
import swarm.activity.Schedule;
import swarm.activity.ScheduleImpl;
import swarm.activity.Activity;
import swarm.objectbase.Swarm;
import swarm.simtoolsgui.GUISwarmImpl;
import swarm.defobj.Zone;
import swarm.Selector;

import javax.swing.JFrame;
import javax.swing.JComponent;

import java.awt.Container;
import java.awt.Image;

import java.awt.Graphics;
import java.awt.image.MemoryImageSource;
import java.awt.Window;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Iterator;
import java.lang.Math;


public class SwarmRaster extends JComponent{
	
    JFrame frame = null;
    Image image = null;
    MemoryImageSource source = null;
    int logicalWidth = 0;
    int logicalHeight = 0;
    int zoomFactor = 1;
    int pixelWidth = 0;
    int pixelHeight = 0;
    int[] pixels;

    Color backgroundColor = Color.white;
    ArrayList rasterStringList;
    ArrayList rasterRectList;
    ArrayList rasterFRectList;
    ArrayList rasterImageList;

    public SwarmRaster (String title, int width, int height, int zf) {
	super();

	frame = new JFrame ();
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
	frame.setBounds (100, 100, 1+width*zf, 1+height*zf);
	    
	frame.show();
	    
	frame.setTitle(title);
		    
	zoomFactor = zf;
	logicalWidth = width;
	logicalHeight = height;
	pixelWidth = zoomFactor*logicalWidth;
	pixelHeight = zoomFactor*logicalHeight;
	pixels = new int[pixelWidth* pixelHeight];
    
	for (int i=0;i<pixelWidth;i++)
	  for (int j=0;j<pixelHeight;j++){
		pixels[j*pixelWidth + i] = backgroundColor.getRGB();
	  }
   	   
	repaint();

	rasterStringList= new ArrayList();
	rasterRectList= new ArrayList();
	rasterFRectList = new ArrayList();
	rasterImageList = new ArrayList();

	source = new MemoryImageSource (pixelWidth, pixelHeight, pixels, 0, pixelWidth);
	source.setAnimated (true);
	image = createImage (source);
	setVisible(true);

	frame.getContentPane().add (this);
	frame.show ();
	    
    }

    private class RasterString
    {
	public String aString;
	public int posx;
	public int posy;
	public RasterString(String s, int newx, int newy){
	    aString = s;
	    posx = newx;
	    posy = newy;
	}
    }
	
    private class RasterImage
    {
	public Image aImage;
	public int posx;
	public int posy;
	public RasterImage(Image img, int newx, int newy){
	    aImage = img;
	    posx = newx;
	    posy = newy;
	}
    }

    private class RasterRect{
	public int posx;
	public int posy;
	public int width;
	public int height;
	public int color;
	public RasterRect( int newx, int newy, int wid, int hei, int col ){
	    posx = newx;
	    posy = newy;
	    width = wid;
	    height = hei;
	    color = col;
	}
    }

	    
    public void setBackgroundColor (Color x){
	backgroundColor = x;
    }


    public void clear(){
        clearPixels();
       
	rasterStringList.clear();
	rasterImageList.clear();
	rasterFRectList.clear();
	rasterRectList.clear();
	rasterImageList.clear();
    }

    public void clearPixels() {
      setPixelBuffer(backgroundColor);
    }


    public void setPixelBuffer(Color c) {
	for (int i=0;i<pixelWidth;i++)
	  for (int j=0;j<pixelHeight;j++){
		pixels[j*pixelWidth + i] = c.getRGB();
	  }
    }

    public void rectangleX0$Y0$X1$Y1 (int x0, int y0, int x1, int y1, int color){
	RasterRect aRect = new RasterRect(zoomFactor*x0,zoomFactor*y0,zoomFactor*Math.abs(x1-x0),zoomFactor*Math.abs(y1-y0),color);  
	rasterRectList.add(aRect);
    } 

    public void fillRectangleX0$Y0$X1$Y1 (int x0, int y0, int x1, int y1, int color){
	RasterRect aRect = new RasterRect(zoomFactor*x0,zoomFactor*y0,zoomFactor*Math.abs(x1-x0),zoomFactor*Math.abs(y1-y0),color);  
	rasterFRectList.add(aRect);
    } 

    public void drawPointX$Y$Color (int lx, int ly, int c) {
	int rectangleX = lx*zoomFactor;
	int rectangleY = ly*zoomFactor;
     
	for (int i=rectangleX;i<rectangleX+zoomFactor;i++)
	    for (int j=rectangleY;j<rectangleY+zoomFactor;j++){
		pixels[j*pixelWidth+i] = c;
	    }
    }


    public void addString (String s, int lx, int ly){
	RasterString aString = new RasterString(s,zoomFactor*lx,zoomFactor*ly);
	rasterStringList.add(aString);
    }


    public void addImage (Image img, int lx, int ly){
	RasterImage anImage = new RasterImage(img,zoomFactor*lx,zoomFactor*ly);
	rasterImageList.add(anImage);
    }

    public Object drawSelf(){
        source.newPixels();
	return this;
    }
 
    public void paint (Graphics g) {
	g.drawImage (image, 0, 0, this);
	   
	for (Iterator index=rasterFRectList.iterator(); index.hasNext(); ) {
	    RasterRect aRasterRect = (RasterRect) index.next();
	    g.fillRect (aRasterRect.posx,aRasterRect.posy,aRasterRect.width,aRasterRect.height);
	    //Caution: This does not adjust the color to match user request.
	}

	for (Iterator index=rasterRectList.iterator(); index.hasNext(); ) {
	    RasterRect aRasterRect = (RasterRect) index.next();
	    g.drawRect (aRasterRect.posx,aRasterRect.posy,aRasterRect.width,aRasterRect.height);
	    //Caution: This does not adjust the color to match user request.
	}

	for (Iterator index=rasterStringList.iterator(); index.hasNext(); ) {
	    RasterString aRasterString = (RasterString) index.next();
	    g.drawString (aRasterString.aString, aRasterString.posx,aRasterString.posy);
	}

	for (Iterator index=rasterImageList.iterator(); index.hasNext(); ) {
	    RasterImage aRasterImage = (RasterImage) index.next();
	    g.drawImage (aRasterImage.aImage, aRasterImage.posx,aRasterImage.posy, this);
	}
    }
}












