/* $Id$
 *
 * Copyright (c) 1999 Xenonsoft Limited. All Rights Reserved.
 *
 * This software is protected by copyright. You are hereby notified from
 * now by reading this message. This software is also the confidential 
 * and proprietary information of Xenonsoft Limited.  ("Confidential
 * Information"). 
 *
 * This software is distributed under the Xenonsoft Public end user 
 * License ("XPeL"), where the machine-readable source code is provided 
 * under the "Open Source" model.
 * For more information, please read the file "LICENSE-XPL.txt" 
 */

// Filename:`HumanoidApplet.java'
//
//
// Description:
//	  
//	Proof of concept.
//	Humanoid Applet
//
//	  
// Author:
//	Peter Pilgrim Fri Jun 25 17:04:02 BST 1999
//	  
// RCS HEADER
// 
// $Author$
// $Date$
// $Source$
// $Revision$    $State$    $Locker$
//
// ================================================================================
// History
//	  $Log$
// 
//
package xenon.humanoid;

import java.applet.*;				// for Applet, AppletContext
import java.beans.*;				// for PropertyChangeListener
import java.awt.*;				// for Component, Graphics
import java.awt.event.*;			// for ActionEvent, ActionListener

import xenon.gamekit.*;				// for GameEngine, WorldObject, etc
import xenon.soundkit.*;			// for SoundEngine, PPMCAudioPlayer, etc

public class HumanoidApplet extends Applet
implements ActionListener, Runnable
{

    public final static String CORE_MESSAGE=
    "Please note this stack trace. If you see a `SecurityException'\n"+
    "here then your browser is being __restrictive__\n"+
    "------------------------------";

    // peterp@xenonsoft [109] > find xenon -name "*.class" -print | awk '/.class$/ { printf "\"%s\",\n", $0 }' | grep -v '\$'
    
    // In Emacs find & replace '.class"' to ''
    //
    private String loadClassList[] = {

	"xenon.humanoid.HumanoidGameEngine",
	"xenon.humanoid.Planetscape",
	"xenon.humanoid.Starship",
	"xenon.humanoid.ApplicationVersion",
	"xenon.humanoid.CollisionHandler",
	"xenon.humanoid.Human",
	"xenon.humanoid.Lander",
	"xenon.humanoid.PlanetExplosion",
	"xenon.humanoid.Pod",
	"xenon.humanoid.Explosion",
	"xenon.humanoid.BonusFlyer",
	"xenon.humanoid.Implosion",
	"xenon.humanoid.Bomber",
	"xenon.humanoid.Swarmer",
	"xenon.humanoid.Baiter",
	"xenon.humanoid.GameUtilities",
	"xenon.humanoid.Bomblet",
	"xenon.humanoid.LaserBlast",
	"xenon.humanoid.OvalExplosion",
//	"xenon.humanoid.HumanoidApplet",
	"xenon.gamekit.GameEngine",
	"xenon.gamekit.CollisionDetector",
	"xenon.gamekit.ImageRenderer",
	"xenon.gamekit.WorldObject",
	"xenon.gamekit.FriendObject",
	"xenon.gamekit.FriendObject",
	"xenon.gamekit.GraphicsUtils",
	"xenon.gamekit.DoubleBufferedContainer",
	"xenon.gamekit.ScoreEntry",
	"xenon.gamekit.ObjectCounter",
	"xenon.gamekit.HighScore",
	"xenon.gamekit.CollisionListener",
	"xenon.gamekit.ScoreTuple",
	"xenon.gamekit.EnemyObject",
	"xenon.gamekit.CollisionMapDispatcher",
	"xenon.gamekit.BulletinLayout",
	"xenon.gamekit.CollisionAdapter",
	"xenon.soundkit.Envelope",
	"xenon.soundkit.SoundEngine",
	"xenon.soundkit.StaticWave",
	"xenon.soundkit.Wave",
	"xenon.soundkit.DelaySoundFilter",
	"xenon.soundkit.SoundFilter",
	"xenon.soundkit.ReverseClipFilter",
	"xenon.soundkit.PPMCAudioPlayer",
	"xenon.soundkit.SoundFilterDataBuffer",
	"xenon.soundkit.WhiteNoiseWave",
	"xenon.soundkit.AudioClipWave",
    };

    protected Button		bt_start;
    protected ProgressBar	pbar;

    protected Frame		frame;
    protected HumanoidGameEngine myGameEngine;
    protected Planetscape	planet;
    protected Starship	        ship;

    public void init()
    {
	setLayout( null );
	
	setBackground( Color.blue );
	setForeground( Color.white );

	Dimension currSize = getSize();
	bt_start = new Button( "Start Game ..." );
	bt_start.setBackground( Color.blue );
	bt_start.setForeground( Color.white );
	bt_start.setFont( new Font( "Helvetica", Font.ITALIC | Font.BOLD, 14 ) );
	bt_start.setLocation( 10, 3 );
	bt_start.setSize( currSize.width-20, 40 );
	bt_start.setEnabled( true );
	add( bt_start );

	pbar = new ProgressBar( 0, 0, 100 );
	pbar.setSize( currSize.width-10, 60 );
	pbar.setLocation( 0, 50 );
        pbar.setTextFont( new Font( "Helvetica", Font.PLAIN, 14 ) );
	pbar.setTextColor( Color.white );
	pbar.setBackground( Color.blue );
	add( pbar );
	
	bt_start.addActionListener( this );
    }
    
    /** implementation defined */
    public void actionPerformed( ActionEvent evt )
    {
	Object src = evt.getSource();
	if ( src == bt_start ) {
	    bt_start.setEnabled( false );
	    Thread loaderThread = new Thread(this);
	    loaderThread.start();
	}
    }

    // Make this a loader inner class
    public void run() 
    {
	// Load classes dynamically now
	pbar.setMinimum(0);
	pbar.setValue(0);
	pbar.setMaximum(loadClassList.length);
	
	for (int k=0; k<loadClassList.length; ++k ) {
	    String className = loadClassList[k];
	    try {
		pbar.setMessage( "Loading ...  "+className );
		pbar.setValue(k);
		Class.forName( className );
		try { Thread.sleep( 25 ); } catch (InterruptedException ie ) { }
	    }
	    catch ( Exception e ) {
		System.err.println( "cannot find or load class:`"+className+"'" );
	    }
	    catch ( Throwable t ) {
		System.err.println( 
		    "Throwable caught serious failure: "+t.getMessage() );
		System.err.println( CORE_MESSAGE );
		t.printStackTrace( System.err );
		pbar.setMessage( t.getMessage() );
	    }
	}
	
 	pbar.setMessage( "Please wait a mo ..." );

	createFrame();

	pbar.setMessage( "Game loaded ..." );
	try { Thread.sleep( 500 ); } catch (InterruptedException ie ) { }
    }
    
    /** create frame */
    public void createFrame()
    {
	frame = new Frame( "Humanoid V"+ApplicationVersion.getVersionString()+
			   "  XeNoNSoFT [c] 1999");
	
	myGameEngine = new HumanoidGameEngine( 
	    600, 320, 0, 0,
	    48, Planetscape.WORLD_HEIGHT/2, 
	    Planetscape.WORLD_WIDTH, Planetscape.WORLD_HEIGHT 
	);

	// THE NEXT LINE IS VERY IMPORTANT!!
	myGameEngine.setRunningInApplet( true );
	myGameEngine.addPropertyChangeListener( new GamePropertyChangeListener() );

	//
	// Load game icon
	//
	Image gameIcon = 
	    GraphicsUtils.getImageAsClassResource( this, "images/humanoid.gif" );
	GraphicsUtils.loadImageCompletely( frame, gameIcon );
	frame.setIconImage( gameIcon );
	
	// Set the animated background object
	planet = new Planetscape( myGameEngine );
	planet.setVisible(true);
	planet.setActive(true);
	myGameEngine.setBackgroundObject( planet );

	// Set the animation hero player object
	ship = new Starship( myGameEngine );
	ship.setVisible(false);
	ship.setActive(true);
	myGameEngine.setPlayerObject( ship );
	
	Panel panel = new Panel();
	panel.setLayout( new BorderLayout( 2, 2 ) );
	panel.add( myGameEngine.getDoubleBufferedContainer() );
	frame.add( panel, BorderLayout.CENTER );
	frame.addWindowListener( new AppletWindowListener( this ) );

	frame.pack();
	myGameEngine.startGameAnimation();
	frame.setLocation( 50, 50 );
	frame.setVisible(true);

    }

    /** close the frame */
    protected void closeFrame()
    {
	// System.out.println( getClass().getName()+".closeFrame()" );
	bt_start.setEnabled( true );
	frame.setVisible(false);
	frame.dispose();
	myGameEngine.stopGameAnimation();
 	pbar.setMessage( "Game has stopped." );
	repaint();
    }
    
    /** public implementation possible bug in the compiler */
    public class GamePropertyChangeListener 
    implements PropertyChangeListener
    {
	public void propertyChange(PropertyChangeEvent evt) {
	    // DEBUG: 
	    // System.out.println( getClass().getName()+".propertyChange()" );
	    // System.out.println( "propname:"+evt.getPropertyName() );
	    if ( evt.getPropertyName().equals( 
		 GameEngine.SESSION_FINISHED_PROPERTY ) )
	    {
		closeFrame();
		System.out.println("Good Bye Humanoid (APPLET) Player!");
		// Toolkit.getDefaultToolkit().beep();
	    }
	}
    }
    
    /** public implementation possible bug in the compiler */
    public static class AppletWindowListener extends WindowAdapter 
    {
	protected HumanoidApplet	humanoid;
	
	public AppletWindowListener( HumanoidApplet humanoid )
	{
	    this.humanoid = humanoid;
	}
	
	public void windowClosing(WindowEvent e) 
	{
	    humanoid.closeFrame();
	}
    }
    
    
}

// fini
