//******************************************************************************
// Clock.java
//
package frontierj.applet;

import java.util.*; 
import java.applet.*;
import java.awt.*;

public class Clock extends Applet implements Runnable
{
	private Thread m_Clock = null;

	private Color m_bgColor = Color.white;
	private Color m_lnColor = Color.black;
	private Color m_txColor = Color.blue;
	private Color m_faceColor = Color.white;
	private Color m_timeColor = Color.blue;
	private int m_hrOffset = 0;
	private int m_minOffset = 0;
	private int m_timeMode = 12; // 0=none, 12=12hr 24=24hr

	private final String PARAM_bgColor = "bgColor";
	private final String PARAM_lnColor = "lnColor";
	private final String PARAM_txColor = "txColor";
	private final String PARAM_faceColor = "faceColor";
	private final String PARAM_timeColor = "timeColor";
	private final String PARAM_hrOffset = "hrOffset";
	private final String PARAM_minOffset = "minOffset";
	private final String PARAM_timeMode = "timeMode";

	int lastxm=0, lastym=0, lastxh=0, lastyh=0; 
	Font txFont = new Font("TimesRoman", Font.PLAIN, 14); // text font
	int winSize = 300;
	int initialized = 0;

//	public Clock() { }

	public void init() {
		String param;

		// bgColor: background color
		param = getParameter(PARAM_bgColor);
		if (param != null)
			try {
				m_bgColor = new Color(Integer.parseInt(param,16));
			} catch (Exception e) { System.out.println ("Err:" + PARAM_bgColor + " - " + e ); } 

		// lnColor: line color
		param = getParameter(PARAM_lnColor);
		if (param != null)
			try {
				m_lnColor = new Color(Integer.parseInt(param,16));
			} catch (Exception e) { System.out.println ("Err:" + PARAM_lnColor + " - " + e ); } 

		// txColor: text color
		param = getParameter(PARAM_txColor);
		if (param != null)
			try {
				m_txColor = new Color(Integer.parseInt(param,16));
			} catch (Exception e) { System.out.println ("Err:" + PARAM_txColor + " - " + e ); } 

		// faceColor: face color
		param = getParameter(PARAM_faceColor);
		if (param != null)
			try {
				m_faceColor = new Color(Integer.parseInt(param,16));
			} catch (Exception e) { System.out.println ("Err:" + PARAM_faceColor + " - " + e ); } 

		// timeColor: time color
		param = getParameter(PARAM_timeColor);
		if (param != null)
			try {
				m_timeColor = new Color(Integer.parseInt(param,16));
			} catch (Exception e) { System.out.println ("Err:" + PARAM_timeColor + " - " + e ); } 

		// hrOffset: hour offset
		param = getParameter(PARAM_hrOffset);
		if (param != null)
			m_hrOffset = Integer.parseInt(param);

		// minOffset: minute offset
		param = getParameter(PARAM_minOffset);
		if (param != null)
			m_minOffset = Integer.parseInt(param);

		// timeMode: time Mode
		param = getParameter(PARAM_timeMode);
		if (param != null)
			m_timeMode = Integer.parseInt(param);

    resize(70, 100);

		winSize = Math.min(getSize().width, getSize().height) - 1;
		initialized = 0;
	}

	public void paint(Graphics g) {
	  
	  GregorianCalendar cal = new GregorianCalendar();
	  
	  int h = cal.get(Calendar.HOUR_OF_DAY) + m_hrOffset; 
	  int m = cal.get(Calendar.MINUTE) + m_minOffset; 
	  if (m > 59) {
	    m = m - 60;
	    h = h + 1;
	    if (h > 23)
	      h = h - 24;
	  }
	  int indicator = 1; // default is am
	  if (m_timeMode == 12 && h > 12) {
	    h = h - 12;
      indicator = 0;
    }
    String timeStr = String.valueOf(h);
    if (m_timeMode > 0) {
      timeStr = timeStr.concat(":");
      if (m < 10)
        timeStr = timeStr.concat("0");
      timeStr = timeStr.concat(String.valueOf(m));
      if (m_timeMode == 12) {
        if (indicator == 0)
          timeStr = timeStr.concat(" pm");
        else
          timeStr = timeStr.concat(" am");
      }
    }

// calculations
    int xcenter = winSize / 2;
    int ycenter = winSize / 2; 
    int radius = winSize / 2;
    int minLen = radius * 4 / 5;
    int hrLen = radius / 2;
   
    int xm = (int)(Math.cos(m * 3.14f/30 - 3.14f/2) * minLen + xcenter); 
    int ym = (int)(Math.sin(m * 3.14f/30 - 3.14f/2) * minLen + ycenter);
    int xh = (int)(Math.cos((h*30 + m/2) * 3.14f/180 - 3.14f/2) * hrLen + xcenter); 
    int yh = (int)(Math.sin((h*30 + m/2) * 3.14f/180 - 3.14f/2) * hrLen + ycenter);

// draw background
    g.setColor(m_bgColor);
    g.fillRect(0, 0, getSize().width, getSize().height);
   
// fill and draw circle
    g.setColor(m_faceColor);
    g.fillOval(0,0,winSize,winSize);
    g.setColor(m_lnColor); 
    g.drawOval(0,0,winSize,winSize); // circle(xcenter,ycenter,radius,g); 

// draw text
    g.setFont(txFont); 
    g.setColor(m_txColor); 
    g.drawString("9",xcenter-radius+5,ycenter+4);   
    g.drawString("3",xcenter+radius-10,ycenter+4); 
    g.drawString("12",xcenter-7,ycenter-radius+13); 
    g.drawString("6",xcenter-2,ycenter+radius-5);

// draw digital time
    if (m_timeMode > 0) {
      g.setColor(m_timeColor);
      int sWidth = g.getFontMetrics().stringWidth(timeStr);
      int sHeight = g.getFontMetrics().getHeight();
      g.drawString(timeStr, (winSize - sWidth) / 2, winSize + sHeight);
    }
 
// erase and redraw hands
    if (initialized == 0) {
      initialized = 1;
    } else {
      g.setColor(m_faceColor); 
      if (xm != lastxm || ym != lastym) { 
        g.drawLine(xcenter, ycenter-1, lastxm, lastym); 
        g.drawLine(xcenter-1, ycenter, lastxm, lastym);
      } 
      if (xh != lastxh || yh != lastyh) { 
        g.drawLine(xcenter, ycenter-1, lastxh, lastyh); 
        g.drawLine(xcenter-1, ycenter, lastxh, lastyh);
      } 
    }
    g.setColor(m_lnColor); 
    g.drawLine(xcenter, ycenter-1, xm, ym); 
    g.drawLine(xcenter-1, ycenter, xm, ym); 
    g.drawLine(xcenter, ycenter-1, xh, yh); 
    g.drawLine(xcenter-1, ycenter, xh, yh);
    g.fillOval(xcenter-2, ycenter-2, 4, 4);

// make current position the last position
    lastxm=xm; lastym=ym; 
    lastxh=xh; lastyh=yh; 
	}

	public void start()	{
		if (m_Clock == null){
			m_Clock = new Thread(this);
			m_Clock.start();
		}
	}
	
	public void stop() {
		if (m_Clock != null) {
			m_Clock.stop();
			m_Clock = null;
		}
	}

	public void run() {
		while (true) {
			try {
				repaint();
				Thread.sleep(60000); // 60,000 milliseconds = 1 minute
			}
			catch (InterruptedException e) {
				stop();
			}
		}
	}


}
