import java.awt.Color;
import java.awt.Component;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;

import java.awt.image.ImageObserver;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;

class      Playfield
extends    Raster
implements Runnable
{
    protected int x; // Position of the sprite in the PlayField
    protected int y; // Position of the sprite in the PlayField

    public  Raster    rasters[];
    public  Rectangle old_patches[][];
    private int       background[];
    private Thread    animation_thread;
    private Component component;
    
    private boolean animate = false;

    /**
     *  This constructor which takes no arguments
     *  allows for future extension.
     */
    public Playfield() 
    {
    }


    /**
     *  This constructor creates an Raster initialized
     *  with the contents of an image.
     */
    public Playfield( Image img, Component component )
    {
        super( img );
        background = new int[pixel.length];
        System.arraycopy( pixel, 0, background, 0, pixel.length );
        this.component = component;
    }


    /**
     *  Add a new raster
     */
    public void
    addRaster( Raster raster )
    {
        if ( rasters == null ) {
            rasters           = new Raster[1];
            old_patches       = new Rectangle[1][1];
            rasters[0]        = raster;
            old_patches[0][0] = new Rectangle();
            return;
        }
        
        Raster    tmp_rasters[]       = new Raster[rasters.length+1];
        Rectangle tmp_old_patches[][] = new Rectangle[rasters.length+1][1];
        
        for ( int i=0; i<rasters.length; i++ ) {
            tmp_rasters[i] = rasters[i];
            tmp_old_patches[i] = old_patches[i];
        }
        tmp_rasters[tmp_rasters.length-1]        = raster;
        tmp_old_patches[tmp_rasters.length-1][0] = new Rectangle();
        
        rasters     = tmp_rasters;
        old_patches = tmp_old_patches;
    }


    /**
     *  Draw the rasters
     */
    public void
    draw( Raster screen )
    {
        if ( rasters == null ) {
            return;
        }

        
        for ( int i=0; i<old_patches.length; i++ ) {
            for ( int c=0; c<old_patches[i].length; c++ ) {
                for ( int row=old_patches[i][c].y; 
                      ( row<old_patches[i][c].y + old_patches[i][c].height) && 
                      ( row<height ) && ( row >= 0 );
                      row++ ) {
                    for ( int col=old_patches[i][c].x;
                          ( col<old_patches[i][c].x + old_patches[i][c].width)&&
                          ( col < width ) && ( col >= 0 );
                          col++ ) {
                        pixel[row*width + col] = background[row*width + col];
                    }
                }
            }
        }
        
        for ( int i=0; i<rasters.length; i++ ) {
            if ( rasters[i] instanceof AnimatedSprite ) {
                old_patches[i] = ((AnimatedSprite)rasters[i]).draw( this );
                continue;
            }
            
            if ( rasters[i] instanceof Sprite ) {
                old_patches[i] = ((Sprite)rasters[i]).draw( this );
                continue;
            }
            
            if ( rasters[i] instanceof Raster ) {
                Raster raster = rasters[i];
                int    rows   = raster.getHeight();
                int    cols   = raster.getWidth();

                for ( int row=0; ( row<rows ) && ( row<height ); row++ ) {
                    for ( int col=0; ( col<cols ) && ( row<width ); col++ ) {
                        pixel[row*width + col] = raster.getPixel( col, row );
                    }
                }

                Rectangle result[] = new Rectangle[1];
                result[0]      = new Rectangle( 0, 0, cols, rows );
                old_patches[i] = result;
                continue;
            }
        }
                
        for ( int i=0; i<height; i++ ) {
            for ( int j=0; j<width; j++ ) {
                screen.setPixel( pixel[i*width + j], x+j, y+i );
            }
        }
    }


    /**
     *  Converts Rasters to Images
     */
    public Image 
    toImage( Component root )
    {
        System.out.println( "Width  = " + width );
        System.out.println( "Height = " + height );
        return root.createImage( new MemoryImageSource( width, 
                                                          height, 
                                                        pixel, 
                                                        0, 
                                                        width) );
    }


    /**
     *  Start animation
     */
    public void
    startAnimation()
    {
        System.out.println( "Starting the playfield MainAnimationThread" );
        animate          = true;
        animation_thread = new Thread( this, "MainAnimationThread" );
        animation_thread.start();
    }


    /**
     *  Run
     */
    public void
    run()
    {
        while ( true ) {
            try {
                animation_thread.sleep( 2500l );
            } catch ( Exception e ) {
                System.out.println( "AnimatedSprite exception in sleeping" );
                e.printStackTrace( System.out );
            }
        }
    }


    /**
     *  Stop animation
     */
    public void
    stopAnimation()
    {
        animate = false;
    }


    /**
     *  Transform the given coordinates using our position.
     */
    public Point
    toPlayfieldCoordinates( Point p )
    {
        return new Point( p.x-this.x, p.y-this.y );
    }


    /**
     *  Translate
     */
    public void
    scroll( int dx, int dy )
    {
        x += dx;
        y += dy;
        System.out.println( "Playfield translated to " + x + ", " + y );
    }
}
