// 04-Dec-1995/SBH My First Java Program!!
// AC_CLOCK.JAVA
//
// Authors
// =======
//
// SBH  Steve Hill      100144.3120@compuserve.com
//
//
// Revision History
// ================
//
// 04-Dec-1995/SBH     Created, my first Applett
// 28-Jan-1996/SBH     Added these comments, and created
//                     demo release v0.0. Made no attempt to 
//                     clean up the code! 
// -----------------------------------------------------------


import java.applet.Applet;
import java.awt.Graphics;        // The Screen
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.*;
import java.util.Date;
import java.lang.Thread;
import java.lang.Integer;
import ac_hand;                   // Clock Hand


public class a_clock extends java.applet.Applet implements Runnable
{
  ac_hand SecondHand = new ac_hand();
  ac_hand MinuteHand = new ac_hand();
  ac_hand HourHand   = new ac_hand();
  Thread ticker;
  int iRadius;
  int iOldSeconds;
  boolean bBackgroundOK = false;

  Image offscreen;
  Image Imgbackground;
  int iBackWidth;
  Dimension offscreensize;
  Graphics offG;
  String szBackGroundType;

  Color colCircum,colHands,colBG;


  public void init()
  {
        String szBackGroundFile;
 

        colCircum = getColorFromParam("color_circumference",Color.red);
        colBG     = getColorFromParam("color_background",Color.gray);
        colHands  = getColorFromParam("color_hands",Color.black);

        SecondHand.setColor(colHands);
        MinuteHand.setColor(colHands);
        HourHand.setColor(colHands);

        //Start the load of the background file - if it works, set flag

        szBackGroundFile = getParameter("background");

        if (null != (Imgbackground = getImage(getCodeBase(),szBackGroundFile)))
        {
           bBackgroundOK = true;
           szBackGroundType = getParameter("background_type");
           if (szBackGroundType == null)
             szBackGroundType = "TILE";
           // we can have TILE,CENTRE or SCALE
           // TILE   = repeated tiling, starting top left
           // CENTRE = centre of clock and centre of image the same
           // SCALE  = image scaled to file applet window.


           szBackGroundType = szBackGroundType.toUpperCase();

           System.out.println("Background type is " + szBackGroundType);

        }


  }

public boolean mouseMove(Event evt,int x, int y)
{
showStatus( x + "," +y);
return(true);
}

Color getColorFromParam(String szParam,Color col_default)
//
// Returns a Color based on a Hex triplet specified as a parameter to
// the applet. If the parameter doesn't exist, or doesn't parse
// correctly, we return col_default.
//
// 01-Jan-1996/SBH      Created

  {
    String szColor;
    String szTemp;

    int Red,Blue,Green;
    int offset = 0;


    if((szColor = getParameter(szParam)) == null)
    {
      return (col_default);
    }
    else
    {
      //Hex triplets optionally start with '#'

      if (szColor.startsWith("#"))
      {
        offset = 1;
      }

 //     System.out.println("hex triplet is " + szColor);
      try
      {
        Red   = Integer.parseInt(szColor.substring(0+offset,2+offset),16);
        Green = Integer.parseInt(szColor.substring(2+offset,4+offset),16);
        Blue  = Integer.parseInt(szColor.substring(4+offset,6+offset),16);
      }
      catch (Exception e)
      {
        return (col_default);
      }

//      System.out.println("RGB (dec)"+ Red + "," + Green +"," +Blue );
      return new Color ( Red,Green,Blue);
    }
  }

  public void my_update(Graphics g) {

	Dimension d = size();
	if ((offscreen == null) || (d.width != offscreensize.width) || (d.height != offscreensize.height))
        {
	    offscreen = createImage(d.width, d.height);
	    offscreensize = d;
            offG = offscreen.getGraphics();
	}

	offG.setColor(colBG);
	offG.fillRect(0, 0, d.width, d.height);

        if (redraw(offG))
        {
          g.drawImage(offscreen, 0, 0, null);

        }
    }


  boolean redraw (Graphics g)
  {
  // This always starts with a blank screen...

  // This gets the system date
  Date dToday   = new Date();
  int  iSeconds = dToday.getSeconds();
  int  iMinutes = dToday.getMinutes();
  int  iHours   = dToday.getHours();
  boolean bTimeChanged = false;

  // only redraw if seconds count has changed

  if (iOldSeconds != iSeconds)
  {
   iOldSeconds = iSeconds;
   bTimeChanged = true;
   // Resize may have occurred...

   Dimension mysize = size();

    if (mysize.width <= mysize.height)
     iRadius = mysize.width/2;
    else
     iRadius = mysize.height/2;

    //28-Jan-1995/SBH Reduced radius by one, becuase it increased in Netscapeb3!

    iRadius--;

    // Note - even though we know the SIZE of the image, we may not
    // yet have all the data. This currently causes a 'flashing' effect
    // whilst we collect the image, as it redraws eachtime more data is
    // recieved
    if (bBackgroundOK)
    {
      if (szBackGroundType.equals("TILE"))
      {
        if ((iBackWidth = Imgbackground.getWidth(this))>0)
        {
        int bx,by,iBackHeight;

        // we tile the background with repeated draws, starting top left

        if((iBackHeight = Imgbackground.getHeight(this))>0)
          for (bx=0;bx < mysize.width;bx += iBackWidth)
            for (by=0;by < mysize.height;by += iBackHeight)
              g.drawImage(Imgbackground,bx,by,this);
        }
      }
      else if (szBackGroundType.equals("SCALE"))
      {
        g.drawImage(Imgbackground,0,0,mysize.width,mysize.height,this);
      }
      else if (szBackGroundType.equals("CENTER"))
      { // Note - we center on the CLOCK center, not the applet center.

        g.drawImage(Imgbackground,iRadius-(Imgbackground.getWidth(this)/2),
        iRadius-(Imgbackground.getHeight(this)/2),this);
      }
    }
    g.setColor(colCircum);
    g.drawOval(0,0,iRadius*2,iRadius*2);


    SecondHand.setLength((int)(iRadius*0.9),(int)(iRadius*0.1) ,(int)(iRadius*0.02));
    MinuteHand.setLength((int)(iRadius*0.80),(int)(iRadius*0.1) ,(int)(iRadius*0.06));
    HourHand.setLength((int)(iRadius*0.6),(int)(iRadius*0.08),(int)(iRadius*0.05));

    SecondHand.setCenter(iRadius,iRadius);
    MinuteHand.setCenter(iRadius,iRadius);
    HourHand.setCenter(iRadius,iRadius);


    SecondHand.draw(g, (double)(iSeconds)/(double)(60));

    double dMinutes = (double)(iMinutes)/(double)(60);

    MinuteHand.draw(g,dMinutes );
    HourHand.draw(g, ((double)(iHours)/(double)(12)) + (dMinutes/12.0));
   }
   return (bTimeChanged);
}

public boolean imageUpdate(Image img, int flags,
			       int x, int y, int w, int h)

// This function is called whenever more data is recieved for the
// background image being drawn by g.drawImage(Imgbackground,bx,by,this);
//
// All this function does is prevent an auto repaint occuring when
// parts of the image are recieved, thus preventing flicker

{
   if ((flags & (ALLBITS)) != 0)
   {
        System.out.println("ALLBITS set");

        // Returning false here means that the browser doesn't perform
        // a full repaint every time we recieve a little more of the image.
        // Without this function, the display flickers as we load the image.

        return (false);
   }
   else
   {
        // we now have all the information - so we don't need informing
        // of further events

        return(true);

   }
}

  public String getAppletInfo()
  {
  return("Analogue Clock v1.0 - Steve Hill 100144.3120@compuserve.com");
  }

  public String[][] getParameterInfo()
  {
     String pinfo[][] =
     {
        {"background",      "url",    "Image to use for clock background"},
        {"background_type", "scale,tile,center", "How to display background"},
        {"color_circumference","RGB hex triplet","Color of clock circumference"},
        {"color_background","RGB hex triplet","Color of background"},
        {"color_hands","RGB hex triplet","Color of Hands"}
     };

      return (pinfo);
  }



  public void start() {
	ticker = new Thread(this);
	ticker.start();
    }
    public void stop() {
	ticker.stop();
    }


    public void run()
        {
        Graphics myGC;
	  while (true)
          {
            // We get our own graphics context, rather than forcing a repaint
            // so (in theory) we repaint in this thread, rather than the main

            myGC = getGraphics();
            my_update(myGC);
	    try {Thread.currentThread().sleep(50);} catch (InterruptedException e){}
            {
              my_update(myGC);
            }
	}
    }
}


