//******************************************************************************
// DarkStarLogo.java:	Applet
//
//******************************************************************************
import java.applet.*;
import java.awt.*;

//==============================================================================
// Main Class for applet DarkStarLogo
//
//==============================================================================
public class DarkStarLogo extends Applet implements Runnable
{
   private float intensityLevel;
   private float redLevel;
   private float blueLevel;

   private float minIntensity;
   private float maxIntensity;
   private float intensityBump;
   private final float intensityStep = (float) .33;

   private float minRed;
   private float maxRed;
   private float redBump;
   private final float redStep = (float) .66;

   private float minBlue;
   private float maxBlue;
   private float blueBump;
   private final float blueStep = (float) .99;

   private Color aColor;

   private Font theFont;

   private static final int XSIZE = 170;
   private static final int YSIZE = 30;

   private int colorScheme;

	// THREAD SUPPORT:
	//		m_DarkStarLogo	is the Thread object for the applet
	//--------------------------------------------------------------------------
	private Thread	 m_DarkStarLogo = null;

	// DarkStarLogo Class Constructor
	//--------------------------------------------------------------------------
	public DarkStarLogo()
	{
      intensityLevel = (float) 70.0;
      redLevel  = (float) 192.0;
      blueLevel = (float) 200.0;

      minIntensity   = (float) 50.0;
      maxIntensity   = (float) 100.0;
      intensityBump  = intensityStep;

      minRed   = (float) 128.0;
      maxRed   = (float) 255.0;
      redBump  = redStep;

      minBlue  = (float) 128.0;
      maxBlue  = (float) 255.0;
      blueBump = blueStep;

      rotateColor();

      theFont = new Font("Dialog", Font.PLAIN, 18);

      colorScheme = 0;

		// TODO: Add constructor code here
	}

	// APPLET INFO SUPPORT:
	//		The getAppletInfo() method returns a string describing the applet's
	// author, copyright date, or miscellaneous information.
    //--------------------------------------------------------------------------
	public String getAppletInfo()
	{
		return "Name: DarkStarLogo\r\n" +
		       "Author: John Chivian\r\n" +
		       "Created with Microsoft Visual J++ Version 1.1";
	}

    //--------------------------------------------------------------------------
	// The init() method is called by the AWT when an applet is first loaded or
	// reloaded.  Override this method to perform whatever initialization your
	// applet needs, such as initializing data structures, loading images or
	// fonts, creating frame windows, setting the layout manager, or adding UI
	// components.
    //--------------------------------------------------------------------------
	public void init()
	{
        // If you use a ResourceWizard-generated "control creator" class to
        // arrange controls in your applet, you may want to call its
        // CreateControls() method from within this method. Remove the following
        // call to resize() before adding the call to CreateControls();
        // CreateControls() does its own resizing.
        //----------------------------------------------------------------------
    	resize(XSIZE, YSIZE);

		// TODO: Place additional initialization code here
	}

	// Place additional applet clean up code here.  destroy() is called when
	// when you applet is terminating and being unloaded.
	//-------------------------------------------------------------------------
	public void destroy()
	{
		// TODO: Place applet cleanup code here
	}

	// DarkStarLogo Paint Handler
	//--------------------------------------------------------------------------
	public void paint(Graphics g)
	{
      g.setFont(theFont);
      g.setColor(aColor);
		g.drawString("Dark Star Software", 10, 20);
	}

	//		The start() method is called when the page containing the applet
	// first appears on the screen. The AppletWizard's initial implementation
	// of this method starts execution of the applet's thread.
	//--------------------------------------------------------------------------
	public void start()
	{
		if (m_DarkStarLogo == null)
		{
			m_DarkStarLogo = new Thread(this);
			m_DarkStarLogo.start();
		}
		// TODO: Place additional applet start code here
	}
	
	//		The stop() method is called when the page containing the applet is
	// no longer on the screen. The AppletWizard's initial implementation of
	// this method stops execution of the applet's thread.
	//--------------------------------------------------------------------------
	public void stop()
	{
		if (m_DarkStarLogo != null)
		{
			m_DarkStarLogo.stop();
			m_DarkStarLogo = null;
		}

		// TODO: Place additional applet stop code here
	}

	// THREAD SUPPORT
	//		The run() method is called when the applet's thread is started. If
	// your applet performs any ongoing activities without waiting for user
	// input, the code for implementing that behavior typically goes here. For
	// example, for an applet that performs animation, the run() method controls
	// the display of images.
	//--------------------------------------------------------------------------
	public void run()
	{
		while (true)
		{
			try
			{
				repaint();
            rotateColor();
				Thread.sleep(20);
			}
			catch (InterruptedException e)
			{
				// TODO: Place exception-handling code here in case an
				//       InterruptedException is thrown by Thread.sleep(),
				//		 meaning that another thread has interrupted this one
				stop();
			}
		}
	}

	// MOUSE SUPPORT:
	//		The mouseDown() method is called if the mouse button is pressed
	// while the mouse cursor is over the applet's portion of the screen.
	//--------------------------------------------------------------------------
	public boolean mouseDown(Event evt, int x, int y)
	{
		// TODO: Place applet mouseDown code here
      rotateColorScheme();
		return true;
	}

	// MOUSE SUPPORT:
	//		The mouseUp() method is called if the mouse button is released
	// while the mouse cursor is over the applet's portion of the screen.
	//--------------------------------------------------------------------------
	public boolean mouseUp(Event evt, int x, int y)
	{
		// TODO: Place applet mouseUp code here
		return true;
	}

	// MOUSE SUPPORT:
	//		The mouseDrag() method is called if the mouse cursor moves over the
	// applet's portion of the screen while the mouse button is being held down.
	//--------------------------------------------------------------------------
	public boolean mouseDrag(Event evt, int x, int y)
	{
		// TODO: Place applet mouseDrag code here
		return true;
	}

	// MOUSE SUPPORT:
	//		The mouseMove() method is called if the mouse cursor moves over the
	// applet's portion of the screen and the mouse button isn't being held down.
	//--------------------------------------------------------------------------
	public boolean mouseMove(Event evt, int x, int y)
	{
		// TODO: Place applet mouseMove code here
		return true;
	}

	// MOUSE SUPPORT:
	//		The mouseEnter() method is called if the mouse cursor enters the
	// applet's portion of the screen.
	//--------------------------------------------------------------------------
	public boolean mouseEnter(Event evt, int x, int y)
	{
		// TODO: Place applet mouseEnter code here
		return true;
	}

	// MOUSE SUPPORT:
	//		The mouseExit() method is called if the mouse cursor leaves the
	// applet's portion of the screen.
 	//--------------------------------------------------------------------------
	public boolean mouseExit(Event evt, int x, int y)
	{
		// TODO: Place applet mouseExit code here
		return true;
	}


	// TODO: Place additional applet code here
	// TODO: Place additional applet code here

   public void rotateColor ()
   {
      redLevel += redBump;
      if (redLevel > maxRed)
      {
         redLevel = maxRed;
         redBump = -redStep;
      }
      if (redLevel < minRed)
      {
         redLevel = minRed;
         redBump = redStep;
      }

      blueLevel += blueBump;
      if (blueLevel > maxBlue)
      {
         blueLevel = maxBlue;
         blueBump = -blueStep;
      }
      if (blueLevel < minBlue)
      {
         blueLevel = minBlue;
         blueBump = blueStep;
      }

      intensityLevel += intensityBump;
      if (intensityLevel > maxIntensity)
      {
         intensityLevel = maxIntensity;
         intensityBump = -intensityStep;
      }
      if (intensityLevel < minIntensity)
      {
         rotateColorScheme();
         intensityLevel = minIntensity;
         intensityBump = intensityStep;
      }

      float fraction = intensityLevel / (float) 100.0;
      float redTemp = redLevel * fraction / maxBlue;
      float blueTemp = blueLevel * fraction / maxBlue;

      if (colorScheme == 0) 
         aColor = new Color (redTemp, (float) 0.0, blueTemp);
      else if (colorScheme == 1)
         aColor = new Color ((float) 0.0, redTemp, blueTemp);
      else if (colorScheme == 2)
         aColor = new Color (redTemp, blueTemp, (float) 0.0);
      return;
   }

   public void update (Graphics g)
   {
      paint(g);
   }

   public void rotateColorScheme()
   {
      colorScheme++;
      if (colorScheme >= 3) colorScheme = 0;
   }
}
