/*
* Created 01/1998
* Sample, h_clock.java, release version, compact source
* For free use, copy, modify (noncommercial)
* By La Trong Hung, latronghung@yahoo.com
* Last modify, 01/2001
* SUMMARY:
*	1) Create background for h_clock (Not be changed everywhen re-draw) -> createClockBg()
*	2) Get date -> setCoor()
*          	d = new Date();
*          	ss = d.getSeconds();
*         	mm = d.getMinutes();
*          	hh = d.getHours();
*          	mon = d.getMonth() + 1;
*          	dat = d.getDate();
*	3) Set Coordinate for each clockhand -> setCoor()
*		xh = (int)((w/2-15)*Math.cos(((hh - 3)*30 + mm*0.5)*rd) + w/2);
*		yh = (int)((h/2-15)*Math.sin(((hh - 3)*30 + mm*0.5)*rd) + h/2);
*		xm = (int)((w/2-6)*Math.cos(((mm - 15)*6 + ss*0.1)*rd) + w/2);
*		ym = (int)((h/2-6)*Math.sin(((mm - 15)*6 + ss*0.1)*rd) + h/2);
*		xs = (int)((w/2-2)*Math.cos((ss - 15)*6*rd) + w/2);
*		ys = (int)((h/2-2)*Math.sin((ss - 15)*6*rd) + h/2);
*	4) Draw clockhand -> createMainImg()
*		mainG.drawLine(6*(w/2-xh)/5+xh, 6*(h/2-yh)/5+yh, xh, yh);
*		mainG.drawLine(6*(w/2-xm)/5+xm, 6*(h/2-ym)/5+ym, xm, ym);
*		mainG.drawLine(5*(w/2-xs)/4+xs, 5*(h/2-ys)/4+ys, xs, ys);
*/
//===========================================================================================//

import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.lang.*;
import java.util.*;
import java.net.*;

//===========================================================================================//

public class h_clock extends Applet implements Runnable{

	private Thread th = null;
	private Image mainImg;
	private Graphics mainG;
	private String hung, link;
	private boolean Init_Complete = false;          	// Flag that confirms the handlePix() method is completely worked.
	private boolean thSuspended = false;            	// Flag that confirm the thread th is in suspended or resumed state.
	private Image linkImg;			      		// message
	private String mesString;				// Message String
	private int  mouseX, mouseY;				// Mouse position
// for h_clock itself
	private MediaTracker mt;
	private Image bgImg;
	private int i;
	private int w, h;
	private Color bgC, handC;
	private int xc, yc, xh, yh, xm, ym, xs, ys;		// Coordinate of each hand
	private int hh, mm, ss, mon, dat;			// Integer values of hour, min, sec, month, date
	private String mondatS, monS, datS;			// For format of date
	private Date d;
	private double rd;

//---------------------------------Initialization------------------------------------------//
   public h_clock(){}

   public void init(){
         						String Bean;
         Bean = getParameter("link");
         	link = (Bean != null) ? Bean : null;
		mesString = (link != null) ? link : "by Hung";
         Bean = getParameter("hung");
         	hung = (Bean != null) ? Bean : "_self";
	 bgC = Color.white;
	 try{
		bgC = new Color(Integer.parseInt(getParameter("bgcolor"), 16));
	 }
	 catch (Exception E) { }
   }
   private void initSetting(){
		w = 80;
		h = 80;
		rd = Math.PI/180.0;
		handC = new Color(30, 70, 180);
         	mainImg = createImage(w, h);
         	mainG = mainImg.getGraphics();

	 	mouseX = -1;
	 	mouseY = -1;
	 	linkImg = createMesImg(mesString);
		bgImg = createClockBg();
		Init_Complete = true;
   }
   private void createMainImg(){
		if(Init_Complete == false){
			repaint();
			initSetting();
		}
		mainG.drawImage(bgImg, 0, 0, this);
		setCoor();				// get coordinate of clockhand
		mainG.setColor(Color.black);
		mainG.drawString(mondatS, 26, 63);	// draw date
							// draw clockhand
		mainG.drawLine(w/2, h/2-1, xh, yh);
		mainG.drawLine(w/2-1, h/2, xh, yh);
		mainG.drawLine(w/2+1, h/2, xh, yh);
		mainG.drawLine(w/2, h/2+1, xh, yh);
		mainG.drawLine(6*(w/2-xh)/5+xh, 6*(h/2-yh)/5+yh, xh, yh);

		mainG.setColor(handC);
		mainG.drawLine(w/2, h/2-1, xm, ym);
		mainG.drawLine(w/2-1, h/2, xm, ym);
		mainG.drawLine(w/2+1, h/2, xm, ym);
		mainG.drawLine(w/2, h/2+1, xm, ym);
		mainG.drawLine(6*(w/2-xm)/5+xm, 6*(h/2-ym)/5+ym, xm, ym);

		mainG.setColor(Color.red);
		mainG.drawLine(5*(w/2-xs)/4+xs, 5*(h/2-ys)/4+ys, xs, ys);
		mainG.drawLine(w/2-1, h/2-1, w/2+1, h/2+1);
		mainG.drawLine(w/2-1, h/2+1, w/2+1, h/2-1);
		mainG.drawLine(w/2, h/2-1, w/2, h/2+1);
		mainG.drawLine(w/2-1, h/2, w/2+1, h/2);

		mainG.setColor(Color.black);
		mainG.drawLine(w/2, h/2, w/2, h/2);

		if(mouseX >= 0)
			mainG.drawImage(linkImg, mouseX, mouseY-16, this);
   }
   private void setCoor(){
						// get date everywhen re-draw
          	d = new Date();
          	ss = d.getSeconds();
         	mm = d.getMinutes();
          	hh = d.getHours();
          	mon = d.getMonth() + 1;
          	dat = d.getDate();
						// format date
	if(mon < 10) monS = "0" + mon;
	else monS = "" + mon;
	if(dat < 10) datS = "0" + dat;
	else datS = "" + dat;
	mondatS = datS + "/" + monS;
						// set coordinate for clock hand
	xh = (int)((w/2-15)*Math.cos(((hh - 3)*30 + mm*0.5)*rd) + w/2);
	yh = (int)((h/2-15)*Math.sin(((hh - 3)*30 + mm*0.5)*rd) + h/2);
	xm = (int)((w/2-6)*Math.cos(((mm - 15)*6 + ss*0.1)*rd) + w/2);
	ym = (int)((h/2-6)*Math.sin(((mm - 15)*6 + ss*0.1)*rd) + h/2);
	xs = (int)((w/2-2)*Math.cos((ss - 15)*6*rd) + w/2);
	ys = (int)((h/2-2)*Math.sin((ss - 15)*6*rd) + h/2);
   }
//____________________________________State of thread_______________________________________//
   public void start(){
      	if(th == null){
         	th = new Thread(this);
         	th.start();
      	}
   }

   public void stop(){
      	if(th != null){
          	th.stop();
          	th = null;
      	}
   }

   public void destroy(){
        //All destroy
   }

   public void update(Graphics g){
  	    	paint(g);
   }

   public void paint(Graphics g){
	if(Init_Complete == true){
	    	g.drawImage(mainImg, 0, 0, this);
	}
	else{
		g.setColor(Color.red);
		g.drawString("Initializing...", 5, 20);
	}
   }

   public void run(){
       	while(Thread.currentThread() == th){  
           	try {
  	             createMainImg();
                     repaint();
                     Thread.sleep(100);
                     System.gc();
            	} 
            	catch(InterruptedException E) {
                     E.printStackTrace();
            	}
       	}
   }
//____________________________________Applet Information_____________________________________//
   public String getAppletInfo() {
		return "Name: h_clock\r\n" + "Author: La Trong Hung\r\n" + "Created with JDK 1.02";
   }

   public String[][] getParameterInfo()
   {
		String[][] info =
		{
			{ "link", "A String value", "URL to jump" },
			{ "bgcolor", "An Integer value (HEX)", "Background color" },
		};
		return info;		
   }
//____________________________________Mouse activity_________________________________________//
   public boolean mouseDown(Event evt, int x, int y){
      	if (link != null){
	         try{
        		    URL url = new URL(getDocumentBase(), link);
		            getAppletContext().showDocument(url, hung);
		            if (hung.equals("_self")){
               				stop();
            	 	    }
         	 }
         	 catch (MalformedURLException E){
            		    E.printStackTrace();
         	 }
      	}
      	else{
		 if (thSuspended) th.resume();
		 else  th.suspend();
		 thSuspended = !thSuspended;
      	}
      	return(true);
   }
   public boolean mouseEnter(Event evt, int x, int y){
         	showStatus(mesString);
		mouseX = x;
		mouseY = y;
      		return(true);
   }
   public boolean mouseMove(Event evt, int x, int y){
		mouseX = x;
		mouseY = y;
		return(true);
   }
   public boolean mouseExit(Event evt, int x, int y){
         	showStatus("");
		mouseX = -1;
		mouseY = -1;
      		return(true);
   }
//_____________________________________Message______________________________________________//
	public Image createMesImg(String mes){
		Image linkImage;
		Graphics g;
		int mw;
		int mh = 16;
		mw = 7*mes.length();
		linkImage = createImage(mw, mh);
		g = linkImage.getGraphics();
		g.setColor(new Color(255, 255, 190));
		g.fillRect(0, 0, mw, mh);
		g.setColor(Color.black);
		g.drawRect(0, 0, mw-1, mh-1);
		g.drawString(mes, 4, 12);
		return linkImage;
	}
//_____________________________________Message______________________________________________//
	public Image createClockBg(){
		int pix[];
		pix = new int[w*h];

		int x, y=0, xu, yu, c;
		double step, r;
			step = (210 - 130)/(w/2);
		for(i = 0; i < w*h; i++){
        		if((i != 0) && (i%w == 0)) y++;
	        	x = i - y*w;
	        	xu = x - w/2;
	        	yu = y - h/2;
			r = Math.sqrt(xu*xu + yu*yu);
	        	if(xu*xu + yu*yu > w*h/4){
                          	pix[i] = 0x00FFFFFF;
                	}
	        	else{
				c = 210 - (int)(r*step);
				if(c < 0) c = 0;
				pix[i] = ((c-8) << 16) | ((c-8) << 8) | c+20 | 0xFF000000;
			}
		}

		MemoryImageSource memS;
         	memS = new MemoryImageSource(w, h, pix, 0, w);
		Image img, im;
		Graphics g;
		img = createImage(memS);
				mt = new MediaTracker(this);
	 	      		mt.addImage(img, 1);
 		      		try {
 		          		mt.waitForID(1);
 		      		}
 		      		catch(InterruptedException e){};
		im = createImage(w, h);
		g = im.getGraphics();
		g.setColor(bgC);
		g.fillRect(0, 0, w, h);
		g.drawImage(img, 0, 0, this);
		for (i = 0; i < 60; i++){
			x = (int)((w/2-3)*Math.cos((i - 15)*6*rd) + w/2);
			y = (int)((h/2-3)*Math.sin((i - 15)*6*rd) + h/2);
			if (i == 0){
				g.setColor(Color.red);
				g.fillOval(x-2, y-2, 5, 5);
				g.setColor(Color.black);
				g.drawOval(x-2, y-2, 5, 5);
				g.drawOval(x-1, y-1, 3, 3);
			}
			else if ((i % 5 == 0) && (i != 0)){
				g.setColor(Color.green);
				g.fillOval(x-2, y-2, 5, 5);
				g.setColor(Color.black);
				g.drawOval(x-2, y-2, 5, 5);
				g.drawOval(x-1, y-1, 3, 3);
			}
			else{
				g.setColor(new Color(30, 30, 100));
				g.drawOval(x, y, 1, 1);
			}
		}
		return im;
	}
}
