
/*
* Created 01/1998
* Sample, h_flag.java, compact version.
* For free use, copy, modify
* By La Trong Hung, latronghung@yahoo.com
* Last modified, 01/2001
* 	 Summary: One more example of waving image by copyArea.
*	 Create necessary images -> createWaveImg
*		+ Create image to wave (Defalt: Vietnam Flag)
*		+ Wave image
*	 Create main image to draw into applet window -> createMainImg()
*/

//===========================================================================================//

import java.applet.*;
import java.awt.*;
import java.net.*;
import java.awt.image.*;

//===========================================================================================//

public class h_flag extends Applet implements Runnable{

	private Thread th = null;
	private MediaTracker mt;  
	private Image mainImg;
	private Graphics mainG;
	private boolean Init_Complete = false;          	// Flag that confirms the all initial methods are 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 String hung, link;
	private int  mouseX, mouseY;				// Mouse position
//h_flag itself
	private Image waveImg;
	private String imgName;
	private int h_Iw, h_Ih, w, h;
	private int i, m = 11;
	private int delay;
	private final double pi = 0.0174533;
	private Color bgcolor;

//---------------------------------Initialization------------------------------------------//
   public h_flag(){}

   public void init(){
         						String Bean;
         Bean = getParameter("link");
         	link = (Bean != null) ? Bean : null;
		mesString = (link != null) ? link : "Sample by La Trong Hung";
         Bean = getParameter("hung");
         	hung = (Bean != null) ? Bean : "_self";
         Bean = getParameter("imagename");
         	imgName = (Bean != null) ? Bean : null;
	 bgcolor = new Color(102, 102, 153);
	 try {
	 	bgcolor = new Color(Integer.parseInt(getParameter("bgcolor"), 16));
	 }
	 catch (Exception E) { }
   }
   private void createWaveImg(){				// create waveImg
								// I. loading
		Image img1=null, img2 = null;
		Graphics g;
       		mt = new MediaTracker(this);
		if(imgName != null){
       			img1 = getImage(getCodeBase(), imgName);
           		mt.addImage(img1, 0);
       				try {
           				mt.waitForID(0);
       				}
       				catch(InterruptedException e){};
		}
								// II. create image for waving
			img2 = createImage(h_Iw, h_Ih);
			g = img2.getGraphics();
			int a[] = {(int)(0.5*h_Iw), (int)(3.0*h_Iw/5.0), (int)(h_Iw/3.0), (int)(2.0*h_Iw/3.0), (int)( 2.0*h_Iw/5.0), (int)( 0.5*h_Iw)};
			int b[] = {(int)(h_Ih/5.0  ), (int)(2.0*h_Ih/3  ), (int)(h_Ih/3.0+3.0), (int)(h_Ih/3.0+3.0), (int)(2.0*h_Ih/3.0  ), (int)(h_Ih/4.0  )};
			int a1[] = {(int)( 0.5*h_Iw), (int)( 3.0*h_Iw/5.0), (int)( h_Iw/3.0), (int)( 0.5*h_Iw), (int)( 0.5*h_Iw)};
			int b1[] = {(int)(h_Ih/5.0  ), (int)(2.0*h_Ih/3.0  ), (int)(h_Ih/3.0+3.0), (int)(h_Ih/3.0+3.0), (int)(h_Ih/4.0  )};
			g.setColor(new Color(200, 0, 0));
			g.fillRect(0, 0, h_Iw, h_Ih);
			g.setColor(Color.yellow);
			g.fillPolygon(a, b, a.length);
			g.fillPolygon(a1, b1, a1.length);
			if(imgName != null){
				g.drawImage(img1, 0, 0, h_Iw, h_Ih, this);
			}
								// III. waves
		waveImg = createImage(h_Iw + 12 + 12*w, h);
		g = waveImg.getGraphics();
		g.setColor(bgcolor);
		g.fillRect(0, 0, h_Iw + 12 + 12*w, h);

		int pix[], pix1[];
       		pix = new int[h_Iw*h_Ih];
		pix1 = new int[h_Iw*h_Ih];
		grabPix(img2, pix1, h_Iw, h_Ih);
		MemoryImageSource memS;
         	memS = new MemoryImageSource(h_Iw, h_Ih, pix, 0, h_Iw);
		img1 = null;

		int ik;
		for(i = 0; i < 360; i += 30){
			ik = i/30;
			ik = 11 - ik;
			ik = ik*w;

			if(i > 0){
				g.setColor(bgcolor);
				g.fillRect(0, 30, h_Iw + 12, h_Ih);
			}
				System.arraycopy(pix1, 0, pix, 0, pix1.length);	//III-1. lights
				makeLight(i, 10, h_Iw, h_Ih, pix);
				img1 = createImage(memS);
	 	      		mt.addImage(img1, i/30);
 		      		try {
 		          		mt.waitForID(i/30);
 		      		}
 		      		catch(InterruptedException e){};
			g.drawImage(img1, 6, 30, h_Iw, h_Ih, this);
										//III-2. waves
			for(int m2 = 30; m2 < h_Ih + 30; m2 += 2){
				int m1 = m2 - 30;//(int)(0.5*m2);
				int mhung = (int)(3.0 + 2.0*Math.sin(((double)i - 4.5*m1)*pi));
				g.copyArea(10, m2, h_Iw - 4, 2, mhung, 0);
			}

			for (int x1 = 9; x1 < h_Iw + 12; x1 += 2){
				int x = x1 - 9;
				int z1 = (int)((double)h_Iw + 33.0 + 0.05*x*Math.sin(((double)i - 4.5*x)*pi)); //0.06..3.0
				int z2 = (int)(0.1*x + 0.09*x*Math.sin(((double)i - 4.5*x)*pi));  //3.0
				g.copyArea(x1, 30, 3, h_Ih, z1 + ik, z2); 
			}

			g.setColor(new Color(102, 102, 51));
			g.fillRoundRect(h_Iw + 12 + 27 + ik, 26, 5, h + 3, 2, 2);
			g.setColor(new Color(153, 153, 51));
			g.drawLine(h_Iw + 12 + 28 + ik, 26, h_Iw + 12 + 28 + ik, h + 3); 
			g.drawLine(h_Iw + 12 + 30 + ik, 26, h_Iw + 12 + 30 + ik, h + 3);
			g.setColor(new Color(180, 180, 51));
			g.drawLine(h_Iw + 12 + 29 + ik, 26, h_Iw + 12 + 29 + ik, h + 3); 
		}
		mt.addImage(waveImg, 13);
		try{
			mt.waitForID(13);
		}
		catch(InterruptedException e) {};
		g.dispose();
		img2 = null;
		img1 = null;
		memS = null;
   }
   private void grabPix(Image im, int[] pix, int w, int h){
       		PixelGrabber h_PixGrab = new PixelGrabber(im, 0, 0, w, h, pix, 0, w);
       		try {
          		h_PixGrab.grabPixels();
       		}
       		catch (InterruptedException e){
           		System.out.println("grabber error" + e);
           		return;
       		}
       		if ((h_PixGrab.status() & ImageObserver.ABORT) != 0){
           		System.out.println("grabber error");
           		return;
       		}
   }
   public void makeLight(int runItem, int delta, int w, int h, int[] pix){
	int i, r, g, b;
	int y = 0, x, del;
       for(i=0; i<w*h; i++){
		if((i != 0) && (i % h_Iw == 0)) y++;
		x = i - y*h_Iw;
		del = (int)(0.35*x*Math.sin(((double)runItem - 4.5*x)*pi));	//From z1
		if(del > 0) del = 0;
             r = (pix[i] >> 16) & 0xFF;
             g = (pix[i] >>  8) & 0xFF;
             b = (pix[i]      ) & 0xFF;
             r += del; if(r < 0) r = 0; if(r > 255) r = 255;
             g += del; if(g < 0) g = 0; if(g > 255) g = 255;
             b += del; if(b < 0) b = 0; if(b > 255) b = 255;
             pix[i] = (r << 16) | (g << 8) | b | 0xFF000000;
       }
   }
   private void initSetting(){
		w = size().width;
		h = size().height;
       		h_Iw = 130;
       		h_Ih = 90;
		createWaveImg();
		delay = 50;
         	mainImg = createImage(w, h);
         	mainG = mainImg.getGraphics();
		mainG.setColor(bgcolor);

	 	mouseX = -1;
	 	mouseY = -1;
	 	linkImg = createMesImg(mesString);
           	Init_Complete = true;
   }

   private void createMainImg(){
		if(Init_Complete == false){
			repaint();
			initSetting();
		}
		mainG.drawImage(waveImg, -h_Iw - 12 - m*w, 0, this);

		if(mouseX >= 0)
			mainG.drawImage(linkImg, mouseX, mouseY-16, this);
		m--; if(m < 0) m = 11;
   }
//____________________________________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...", 10, 20);
	}
   }

   public void run(){
       	while(Thread.currentThread() == th){  
           	try {
  	             createMainImg();
                     repaint();
                     Thread.sleep(delay);
                     System.gc();
            	} 
            	catch(InterruptedException E) {
                     E.printStackTrace();
            	}
       	}
   }
//____________________________________Applet Information_____________________________________//
   public String getAppletInfo() {
		return "Name: h_flag\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" },
			{ "imagename", "A String value", "Name of Image" },
			{ "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 = 6*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;
	}
}
