 
/**
 * ScreenImpl.java
 *
 *
 * Created: Mon Dec 17 08:34:48 2001
 *
 * @author <a href="mailto: "Jan Newmarch</a>
 * @version
 */

package saver;

import saver.drawable.*;

import java.awt.*;
import javax.swing.*;
import java.rmi.Remote;

public class ScreenImpl extends JFrame
    implements RemoteScreen {

    protected static final boolean FULLSCREEN = true;

    protected static int MAX_POP = 10;
    protected Dimension screenSize;

    NextScreen next;
    JPanel panel = new JPanel();

    public ScreenImpl(NextScreen n){
	next = n;
	setUndecorated(true);

	screenSize = getToolkit().getScreenSize();

	getContentPane().setLayout(new BorderLayout());
	getContentPane().add(panel, BorderLayout.CENTER);
	panel.setLayout(null);
	panel.setBackground(Color.black);

	if (FULLSCREEN) {
	    setBounds(0, 0, 
		      (int) screenSize.getWidth(), 
		      (int) screenSize.getHeight());
	} else {
	    setBounds(200, 100, 
		      (int) screenSize.getWidth()/2, 
		      (int) screenSize.getHeight()/2);
	}
	setVisible(true);
    }

    /**
     * randomly populate the initial screen
     * take the class name from parameter so we can draw
     * different objects without changing code
     */
    public void populate(String drawableClass) {
	Class cls = null;
	try {
	    cls = Class.forName(drawableClass);
	} catch(Exception e) {
	    e.printStackTrace();
	    System.exit(1);
	}
	for (int n = 0; n < MAX_POP; n++) {
	    int xSpeed = 1 + (int) Math.floor(Math.random() * 10);
	    int x = (int) Math.round(Math.random() * this.getWidth());
	    int y = (int) Math.round(Math.random() * this.getHeight());
	    Drawable d = null;
	    try {
		d = (Drawable) cls.newInstance();
	    } catch(Exception e) {
		e.printStackTrace();
		System.exit(1);
	    }

	    d.setVelocity(new Point(xSpeed, 0));
	    d.setLocation(x - d.getWidth(), y);

	    panel.add(d);
	}
    }

    public void moveAll() {
	Component[] components = panel.getComponents();
	for (int n = 0; n < components.length; n++) {
	    if (components[n] instanceof saver.drawable.Drawable) {
		Drawable d = (Drawable) components[n];
		Point location = d.getLocation();
		Rectangle bounds = d.getBounds();
		Point velocity = d.getVelocity();
		
		Point newLoc = new Point(location.x + velocity.x,
					 location.y + velocity.y);

		/* see if we have fallen off the screen */
		if (newLoc.x > this.getWidth()) {
		    if (Saver.debug) System.out.println("Removing " + d);
		    panel.remove(d);
		    continue;
		}
		
		/* see if our outer edge needs to migrate,
		 * when the new x crosses the width boundary
		 */
		if (newLoc.x + bounds.width > this.getWidth() &&
		    location.x + bounds.width <= this.getWidth()) {
		    migrate(d);
		}
		
		bounds.setLocation(newLoc);
		d.setBounds(bounds);
	    }
	}
    }

    /** 
     * from Screen
     * add the drawable to the list of objects managed
     * by this Frame
     */
    public void add(Drawable d) {
	// the drawable will be hanging off the right hand edge of 
	// its last screen. We need to reset it to come in the left
	// side of this screen
	Point newLoc = new Point(-d.getWidth(),
				 d.getY());
	d.setLocation(newLoc);

	panel.add(d);
    }

    public void migrate(Drawable d) {
	next.migrate(d);
    }

}// ScreenImpl
