import java.net.URL;
import java.net.URLConnection;
import java.awt.Frame; 
import java.awt.Graphics; 
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.Dimension;
import java.applet.Applet;


public class webcam extends Applet{ 
	Image webimage=null;
	Image webimage_buffer=null;
	String sectillrefresh_string=null;
	Thread count=null;
	
	String imageurl_string=null;
	URL imageurl=null;
	URLConnection imageconn=null;
	long lmod = -1;
	long clmod = -1;

	String offlineurl_string=null;
	URL offlineurl=null;	

	int refreshsec=0;
	int offline_sec=0;
	boolean drawcounter;
	
	///////////////////////////////////
	//This is a Basic Double Buffering Module
	//Not writen by me.
	//The nice part about this is everything is automatic...
	//just write like you normally would in paint.
	Image OSC;
   	int widthOfOSC, heightOfOSC;
	public void update(Graphics g) {
      		if (OSC == null || widthOfOSC != getSize().width || heightOfOSC != getSize().height) {
         		OSC = null;
         		OSC = createImage(getSize().width, getSize().height);
         		widthOfOSC = getSize().width;
         		heightOfOSC = getSize().height;
      			}
      		Graphics OSG = OSC.getGraphics();
      		OSG.setColor(getBackground());
      		OSG.fillRect(0, 0, widthOfOSC, heightOfOSC);
      		OSG.setColor(getForeground());
      		OSG.setFont(getFont());
      		paint(OSG);
      		g.drawImage(OSC,0,0,this);
   	}
	//////////////////////////////////
	
    	public void paint(Graphics g) {
        	//Draw Image
        	if (webimage_buffer!=null) {g.drawImage(webimage_buffer,0,0,this);}
    		//Draw the Counter If it's enabled
    		if (drawcounter) {
    			//Set The Font Color
    			g.setColor(java.awt.Color.red);
			//g.drawString("Mod:" + Long.toString(lmod),100,80);
			//g.drawString("cMod:" + Long.toString(clmod),100,100);
			//g.drawString("Date:" + Long.toString(System.currentTimeMillis()),100,120);
    			//Get the Font Metrics
    			java.awt.FontMetrics fm=g.getFontMetrics();
    			int stringwidth=fm.stringWidth(sectillrefresh_string);
    			//Draw the countdown Timer
    			g.drawString(sectillrefresh_string,(getSize().width-stringwidth-4),(getSize().height-(fm.getHeight()/2)));
			}
		}

	public void loadnewimage() {        	
        	//Try to get the new image
        	try {
			if (webimage !=null) {webimage.flush();}
            		
			// Open the connection and get the Last Modified time.
			imageconn = imageurl.openConnection();
            		clmod = imageconn.getLastModified();
			
			// check the clmod time.
			if( clmod < System.currentTimeMillis() - (offline_sec * 1000) ){
				webimage=getToolkit().getImage(offlineurl);
				}
			else if(clmod > 2 && ( lmod == -1 || clmod >= lmod )){
				webimage=getToolkit().getImage(imageurl);
				}

			if(webimage != null){
				lmod = clmod;
				MediaTracker mt=new MediaTracker(this);
            			mt.addImage(webimage,0);
            			mt.waitForAll();
	            		mt.removeImage(webimage,0);
				}
            		} 
            	catch (Exception e) {webimage=null;}
		//If we were successfull then update the buffer, otherwise wait for next update
		if (webimage !=null) {webimage_buffer=webimage;}
		//repaint since the image changed.
		repaint();
		}

	public void start() {
		//First Let's Get Our Environment
		//Get The Refresh Time
		try {
			refreshsec=Integer.parseInt(getParameter("refreshsec"),10);
			}
		catch (Exception e) {
			refreshsec=30;
			}
		//Get the Images Url
		try {	
			imageurl_string=getParameter("imageurl");
			imageurl=new URL(imageurl_string);
			}
		catch (Exception e) {
			imageurl=null;
			}
        	//See if we want to draw the counter
        	try {
        		Boolean tmp=Boolean.valueOf(getParameter("drawcounter"));
        		drawcounter=tmp.booleanValue();
        		}
        	catch (Exception e){
        		drawcounter=true;
        		}       	
		//Get our Offline url
		try {
			offlineurl_string=getParameter("offlineurl");
			offlineurl=new URL(offlineurl_string);
			}
		catch (Exception e) {
			offlineurl=imageurl;
			}
		//Get The offline Timeout
		try {
			offline_sec=Integer.parseInt(getParameter("offline_timeout"),10);
			}
		catch (Exception e) {
			offline_sec=300;
			}
        	
        	//Okay, we're all set, Start up the Image Retriever.
        	count=(new Thread(new Proc(this)));
        	count.start();
    		}
    	
    	public void stop() {
        	Thread save=count;
        	count=null; // that will be noticed by run() in class Proc
    		try {
            		save.interrupt(); // awake from sleep(...) to speed up the loop
            		save.join(100); // try to merge in 100ms or generate error
        		}
        	catch(Exception ex) {}
        	}
    	
    	public void updatetime(int sectillrefresh){
    		sectillrefresh_string=String.valueOf(sectillrefresh);
    		repaint();
    		}
    	
    	}





class Proc implements Runnable {
	webcam creator;    
	int sectillrefresh;
	
	Proc(webcam c) {
		creator=c;
		}
	   		
	public void run() {
        	while (creator.count==Thread.currentThread()) {
        		//lets tell the user that we're refreshing the screen (so counter doesn't stop at 1
        		creator.sectillrefresh_string="Refreshing...";
       			creator.repaint();
       			
       			creator.loadnewimage(); // forces update of the screen
       			
       			//Run the Refreshcounter, update the image witht the counter as we do.
       			for(sectillrefresh=creator.refreshsec;sectillrefresh>0;sectillrefresh--){
       				creator.updatetime(sectillrefresh);
       				try {Thread.currentThread().sleep(1000);}
       				catch(Exception e) {}
				}       		
       		
       			}
  		}
	}




