/* Alarm4.java

  Original version Alarm1 circa 1998 using Symantec Cafe.
  Subsequent versions Alarm2 and Alarm3 - minor changes. 	
  Alarm4 version 2008-02-20 for JDK 1.5 on OSX 10.4.11:
	- "Triggered" SOUND LOOP SECTION WAS MOVED TO THE RUN METHOD 2008-02-20 IN ORDER TO RESOLVE AN APPARENT COMPILATION AND RUN-TIME ISSUE PLAYING SOUNDS REPEATEDLY UNDER OSX  
	- MAIN DOES NOT WORK ON ANY PLATFORM AS OF 2008-02-2 DUE TO NULL POINTER EXCEPTION ON FIRST getCodeBas or getCodeBase call.

  Copyright (c) 1998-2008 Michael Cook	

*/  

/*
	This class is a basic extension of the Applet class.  It would generally be
	used as the main class with a Java browser or the AppletViewer.  But an instance
	can be added to a subclass of Container.  To use this applet with a browser or
	the AppletViewer, create an html file with the following code:

	<HTML>
	<HEAD>
	<TITLE> A simple program </TITLE>
	</HEAD>
	<BODY>

	<APPLET CODE="Alarm4.class" WIDTH=332 HEIGHT=169></APPLET>

	</BODY>

	</HTML>

	You can add controls to Clock with Cafe Studio.
	(Menus can be added only to subclasses of Frame.)
 */

//import java.awt.*;
import java.applet.*;
import java.applet.AudioClip;
import java.applet.AppletStub;

//My code starts here
import java.util.Date;
//My code ends here


//
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Calendar;
import java.io.*;
import java.net.*;
import sun.audio.*;
import java.util.jar.JarFile;
import java.util.StringTokenizer;

public class Alarm4 extends Applet implements Runnable {

	//My code starts here

	Font theFont = new Font("OCRA", Font.BOLD,12);
	Date theDate, RemainDate, TargetDate;
	Thread runner;
	String Starget, Sremaining, Snow, Sthen, in, newchar, work, SoundName;
	Float F1, F2;
	float f1, f2, f3;
	long l1, l2, l3, l3a, l4, l5, Lremain, Ltarget;
	Long Lwork1, Lwork2, Lwork3, Lwork4;
	boolean Triggered, looping, set;
	AudioClip loopClip;
	AudioClip ButtonSound; 
	int adaptcount, i, dangcount, slimcount, othercount;

	//{{DECLARE_CONTROLS
	TextField Now;
	Label label1;
	Button button0;
	Button button1;
	Button button2;
	Button button3;
	Button button4;
	Button buttonS;
	Button button5;
	Button button6;
	Button button7;
	Button button8;
	Button button9;
	Button buttonR;
	TextField Target;
	TextField Remaining;
	Label label2;
	Label label3;
	TextField Then;
	Label label4;
	Label label5;
	Choice choice1;
	Button buttonPlay;

	private AudioClip sound;

	public void clickedButton0() {
		// to do: put event handler code here.
		newchar="0";
		ButtonSound = getAudioClip(getCodeBase(),"0.au");
		ButtonSound.play();
		get();
		
	}
	public void clickedButton1() {
		// to do: put event handler code here.
		newchar="1";
		ButtonSound = getAudioClip(getCodeBase(),"1.au");
		ButtonSound.play();
		get();
	}
	public void clickedButton2() {
		// to do: put event handler code here.
		newchar="2";
		ButtonSound = getAudioClip(getCodeBase(),"2.au");
		ButtonSound.play();
		get();
	}
	public void clickedButton3() {
		// to do: put event handler code here.
		newchar="3";
		ButtonSound = getAudioClip(getCodeBase(),"3.au");
		ButtonSound.play();
		get();
	}
	public void clickedButton4() {
		// to do: put event handler code here.
		newchar="4";
		ButtonSound = getAudioClip(getCodeBase(),"4.au");
		ButtonSound.play();
		get();
	}
	public void clickedButton5() {
		// to do: put event handler code here.
		newchar="5";
		ButtonSound = getAudioClip(getCodeBase(),"5.au");
		ButtonSound.play();
		get();
	}
	public void clickedButton6() {
		// to do: put event handler code here.
		newchar="6";
		ButtonSound = getAudioClip(getCodeBase(),"6.au");
		ButtonSound.play();
		get();
	}
	public void clickedButton7() {
		// to do: put event handler code here.
		newchar="7";
		ButtonSound = getAudioClip(getCodeBase(),"7.au");
		ButtonSound.play();
		get();
	}
	public void clickedButton8() {
		// to do: put event handler code here.
		newchar="8";
		ButtonSound = getAudioClip(getCodeBase(),"8.au");
		ButtonSound.play();
		get();
	}
	public void clickedButton9() {
		// to do: put event handler code here.
		newchar="9";
		ButtonSound = getAudioClip(getCodeBase(),"9.au");
		ButtonSound.play();
		get();
	}
	public void clickedButtonPlay() {
		// to do: put event handler code here.
		loopClip.play();                        // play sound once.
	}
	public void clickedButtonR() {
		// to do: put event handler code here.
		reset();
		repaint();
	}
	//}}

	public void clickedButtonS() {
		// to do: put event handler code here.
		// to set up the countdown to the alarm

		slimcount = 3;                          // set up timers to handle
		dangcount = 2;                          //  different clip lengths.
		othercount = 6;				// 2007-12-31 (was missing).
                adaptcount = 1;
 
		i = in.length();
		if (i < 8) {
			in = "00:00:06";
			Starget=in;
			repaint();
		}

		work=in.substring(0,2);                 // get HH as millisecs
		f1 = Float.valueOf(work).floatValue();
		l1 = (long) (f1 * 1000* 3600);

		work=in.substring(3,5);                 // get MM as millisecs
		f2 = Float.valueOf(work).floatValue();
		l2 = (long) (f2 * 1000 * 60);

		work=in.substring(6);                   // get SS as millisecs
		f3 = Float.valueOf(work).floatValue();
		l3 = (long) (f3 * 1000);

		l3a = l1 + l2 + l3;                     // get alarm time offset

		l4 = theDate.getTime();                 // time alarm set
		l5 = l3a + l4;                          // time alarms expires

		Lremain=l3a;
		Ltarget=l5;

		TargetDate = new Date(l5);

		set = true;                        // to trigger decrement of
						   //  the count
		repaint();
	}
   public void decrement() {

   Lremain = Lremain - 1000;                // decrement 1 second

   l1 = Lremain /  1000;                    // whole seconds remaining

   l2 = 0;                                  // whole hours left
   if (l1 > 3601) l2 = ((l1 - (l1 % 3600))/3600);

   l3 = 0;                                  // whole minutes left
   l1 = l1 - (l2 *3600);
   if (l1 > 60) l3 = ((l1 - (l1 % 60))/60);

   l4 = l1 - (l3 * 60);                     // whole seconds left

   Lwork2 = new Long((long) (l2));
   Lwork3 = new Long((long) (l3));
   Lwork4 = new Long((long) (l4));

   Sremaining = Lwork2.toString() + ":" +
				Lwork3.toString() + ":" +
				Lwork4.toString();

   if (Lremain < 0) {

		Triggered = true;
		looping = true;
		// loopClip = getAudioClip(getCodeBase(),   moved to init 98/12/25
		//                 "adapt.or.die.au");
		////	Lremain = 0; 		// try remove 2007-12-31

  }

 } 
   public void get () {
		// to do: put event handler code here.
		int i;
		i = in.length();
		if ((i==2) | (i==5)) in = in + ":";
		i = in.length();
		if (i < 8) in = in + newchar;
		Sthen=in;
		Starget=in;
		Sremaining=in;

		repaint();

   }   
	//My code ends here

	public boolean handleEvent(Event event) {
		if (event.id == Event.ACTION_EVENT && event.target == buttonPlay) {
				clickedButtonPlay();
				return true;
		}

		else

		if (event.id == Event.ACTION_EVENT && event.target == choice1) {
				selectedChoice1();
				return true;
		}
		else
		if (event.id == Event.ACTION_EVENT && event.target == buttonR) {
				clickedButtonR();
				return true;
		}
		else
		if (event.id == Event.ACTION_EVENT && event.target == button9) {
				clickedButton9();
				return true;
		}
		else
		if (event.id == Event.ACTION_EVENT && event.target == button8) {
				clickedButton8();
				return true;
		}
		else
		if (event.id == Event.ACTION_EVENT && event.target == button7) {
				clickedButton7();
				return true;
		}
		else
		if (event.id == Event.ACTION_EVENT && event.target == button6) {
				clickedButton6();
				return true;
		}
		else
		if (event.id == Event.ACTION_EVENT && event.target == button5) {
				clickedButton5();
				return true;
		}
		else
		if (event.id == Event.ACTION_EVENT && event.target == button4) {
				clickedButton4();
				return true;
		}
		else
		if (event.id == Event.ACTION_EVENT && event.target == button3) {
				clickedButton3();
				return true;
		}
		else
		if (event.id == Event.ACTION_EVENT && event.target == button2) {
				clickedButton2();
				return true;
		}
		else
		if (event.id == Event.ACTION_EVENT && event.target == button1) {
				clickedButton1();
				return true;
		}
		else
		if (event.id == Event.ACTION_EVENT && event.target == button0) {
				clickedButton0();
				return true;
		}
		else
		if (event.id == Event.ACTION_EVENT && event.target == buttonS) {
				clickedButtonS();
				return true;
		}

		return super.handleEvent(event);
	}
	//My code ends here

	public void init() {

		super.init();

		reset();                         // clear all my fields.

		SoundName = "adapt.or.die.au";   // set default sound clip name at start.
		loopClip = getAudioClip(getCodeBase(),
					  "adapt.or.die.au");// load default sound clip name at start.
		//{{INIT_CONTROLS
		setLayout(null);
		addNotify();
		resize(insets().left + insets().right + 477, insets().top + insets().bottom + 375);
		Now=new TextField(42);
		Now.setFont(new Font("Courier",Font.BOLD,18));
		Now.disable();
		add(Now);
		Now.reshape(insets().left + 14,insets().top + 40,432,40);
		label1=new Label("Current Date and Time");
		label1.setFont(new Font("Dialog",Font.BOLD,12));
		label1.disable();
		add(label1);
		label1.reshape(insets().left + 36,insets().top + 16,180,16);
		button0=new Button("0");
		add(button0);
		button0.reshape(insets().left + 36,insets().top + 104,36,32);
		button1=new Button("1");
		add(button1);
		button1.reshape(insets().left + 72,insets().top + 104,36,32);
		button2=new Button("2");
		add(button2);
		button2.reshape(insets().left + 108,insets().top + 104,36,32);
		button3=new Button("3");
		add(button3);
		button3.reshape(insets().left + 144,insets().top + 104,36,32);
		button4=new Button("4");
		add(button4);
		button4.reshape(insets().left + 180,insets().top + 104,36,32);
		buttonS=new Button("Set");
		add(buttonS);
		buttonS.reshape(insets().left + 216,insets().top + 104,63,32);
		button5=new Button("5");
		add(button5);
		button5.reshape(insets().left + 36,insets().top + 136,36,32);
		button6=new Button("6");
		add(button6);
		button6.reshape(insets().left + 72,insets().top + 136,36,32);
		button7=new Button("7");
		add(button7);
		button7.reshape(insets().left + 108,insets().top + 136,36,32);
		button8=new Button("8");
		add(button8);
		button8.reshape(insets().left + 144,insets().top + 136,36,32);
		button9=new Button("9");
		add(button9);
		button9.reshape(insets().left + 180,insets().top + 136,36,32);
		buttonR=new Button("Reset");
		add(buttonR);
		buttonR.reshape(insets().left + 216,insets().top + 136,63,32);
		Target=new TextField(13);
		Target.setFont(new Font("Courier",Font.BOLD,16));
		Target.disable();
		add(Target);
		Target.reshape(insets().left + 297,insets().top + 112,135,24);
		Remaining=new TextField(13);
		Remaining.setFont(new Font("Courier",Font.BOLD,16));
		Remaining.disable();
		add(Remaining);
		Remaining.reshape(insets().left + 297,insets().top + 144,135,24);
		label2=new Label("Alarm after");
		label2.setFont(new Font("Dialog",Font.BOLD,12));
		label2.disable();
		add(label2);
		label2.reshape(insets().left + 297,insets().top + 88,90,16);
		label3=new Label("Time left");
		label3.setFont(new Font("Dialog",Font.BOLD,12));
		label3.disable();
		add(label3);
		label3.reshape(insets().left + 297,insets().top + 176,90,16);
		Then=new TextField(42);
		Then.setFont(new Font("Courier",Font.BOLD,18));
		Then.disable();
		add(Then);
		Then.reshape(insets().left + 14,insets().top + 208,432,40);
		label4=new Label("Target Date and Time");
		label4.setFont(new Font("Dialog",Font.BOLD,12));
		label4.disable();
		add(label4);
		label4.reshape(insets().left + 36,insets().top + 184,180,16);
		label5=new Label("Select sound");
		label5.setFont(new Font("Dialog",Font.BOLD,12));
		label5.disable();
		add(label5);
		label5.reshape(insets().left + 108,insets().top + 264,99,16);
		choice1= new Choice();
		add("1",choice1);
		choice1.reshape(insets().left + 216,insets().top + 256,171,80);
		choice1.addItem("adapt.or.die.au");
		choice1.addItem("cannot.be.completed.au");
		choice1.addItem("danger.danger.au");
		choice1.addItem("gong.au"); 
		choice1.addItem("slim.pickens.au");             // from Dr.Strangelove
		choice1.addItem("spacemusic.au");
		choice1.addItem("that.hurts.au");
		choice1.addItem("tiptoe.thru.the.tulips.au");
		buttonPlay=new Button("Play");
		add(buttonPlay);
		buttonPlay.reshape(insets().left + 396,insets().top + 256,48,32); //was 36,32
		//}}
		//My code ends here

		/*  This code is not set up correctly by Cafe - set it up manually

		choice1= new Choice();
		add("1",choice1);
		choice1.reshape(insets().left + 315,insets().top + 256,108,80);
		choice1.addItem("adapt.or.die.au");
		choice1.addItem("cannot.be.completed.au");
		choice1.addItem("danger.danger.au");
		choice1.addItem("gong.au"); 
		choice1.addItem("slim.pickens.au");             // from Dr.Strangelove
		choice1.addItem("spacemusic.au");
		choice1.addItem("that.hurts.au");
		choice1.addItem("tiptoe.thru.the.tulips.au");
		*/
		adaptcount = 1; dangcount = 2; othercount=6; slimcount=3;      // 2007-12-31
		Lremain = 0;            // try 2008-02-19
 
	}
   public void paint(Graphics g) {

			Now.setText(theDate.toString());
			Target.setText(Starget);
			Remaining.setText(Sremaining);
			Then.setText(TargetDate.toString());

		/*                                              testing only
			g.setFont(theFont);
			g.drawString(theDate.toString(), 10, 230);
			g.drawString(TargetDate.toString(), 10, 270);
			g.drawString(RemainDate.toString(), 10, 310);
			g.drawString(in, 10, 350);  

		*/

/* ********************************* THIS SECTION WAS MOVED TO THE RUN METHOD 2008-02-20 A TO RESOLVE AN APPARENT COMPILATION AND RUN-TIME ISSUE PLAYING SOUNDS REPEATEDLY UNDER OSX  
	
			if (Triggered == true) {
		
				if ((SoundName == "slim.pickens.au" |
					(SoundName == "Spacemusic.au")) {    // slim takes 4 secs
					slimcount ++;
					if (slimcount == 4) {
						slimcount = 0;
						loopClip.play();
					}
				}	
				if ((SoundName == "adapt.or.die.au") | 
					(SoundName == "gong.au") |
					(SoundName == "that.hurts.au")) {
					adaptcount ++;
					if (adaptcount == 2) {
						adaptcount = 0;
						loopClip.play();
					}
				}	
				if ((SoundName == "danger.danger.au") |  // these take 3 secs
					(SoundName == "tiptoe.thru.the.tulips.au") |
					(SoundName == "cannot.be.completed.au")) {

					dangcount ++;
					if (dangcount == 3) {
						dangcount = 0;
						loopClip.play();
					}
				
				}
			}
*/	
	/* THE FOLLOWING TEST SOUND PLAY SECTIONS ARE ALSO NOT USED 
	*/
	/*        AudioPlayer p = AudioPlayer.player;
                                try{
                                        AudioStream as = new AudioStream(getClass().getResourceAsStream("danger.danger.au"));
                                        p.start(as);
                                }
                                catch(IOException e){
                                        e.printStackTrace();
                                }   
	*/
	/*	

			// load current sound

			sound = getAudioClip( getCodeBase(), SoundName);
			loopClip = sound;
			loopClip.play();
	*/
	/* 
try
{
String soundFileString = "sound.au";	 // Make sure the file is in au format or it will not work.
URL soundFileURL = new URL("file:" +soundFileString);
AudioClip sound = Applet.newAudioClip(soundFileURL);
sound.play();
}

catch(Exception e)
{
System.err.println("problem: " + e.toString());
}
	*/

	}
	public void reset () {
		// to do: put event handler code here.

		Starget="HH:MM:SS";
		Sremaining=Starget;
		Lremain=0;
		Snow=Starget;
		Sthen=Starget;
		in="";
		Triggered = false;
		set = false;
		RemainDate = new Date();
		TargetDate = new Date();

		if (looping == true) {
				loopClip.stop();    //Stop the sound loop.
				looping = false;
		}

		slimcount = 3;                          // set up timers to handle
		dangcount = 2;                          //  different clip lengths.
		othercount = 6;				// 2007-12-31 (was missing).
		adaptcount = 1;
 
		repaint();
   }   
	public void run() {

			while(true) {

				theDate = new Date();
				repaint();

				try { Thread.sleep(1000); }
				catch (InterruptedException e) { }

				if (set == true) decrement();           // go decrement if
									//  alarm has been set.
									
									// play sound if triggered elsewhere
                	        if (Triggered == true) {
	
                                	if ((SoundName == "adapt.or.die.au") |	// these take 2 seconds
                                        	(SoundName == "that.hurts.au"))
					{
                                        	adaptcount ++;
                                        	if (adaptcount == 2) {
                                                	adaptcount = 0;
                                                	loopClip.play();
                                        	}
                                	}
                                	if ((SoundName == "danger.danger.au") |  // these take 3 secs
                                        	(SoundName == "tiptoe.thru.the.tulips.au"))
					{
        	                                dangcount ++;
                	                        if (dangcount == 3) {
                        	                        dangcount = 0;
                                	                loopClip.play();
                                        	}

                                	}
        	                        if ((SoundName == "slim.pickens.au") |	// these take up to 6 seoconds
                                        	(SoundName == "gong.au") |
                                        	(SoundName == "cannot.be.completed.au") |
						(SoundName == "spacemusic.au"))
					{	
        	                                        othercount ++;
                	                                if (othercount == 7) {
                        	                               othercount = 0;
                                	                        loopClip.play();
                                        	        }
                                	}
                        	}
			}
	}
	public void selectedChoice1() {
		// to do: put event handler code here.
		SetSound();
	}
	public void SetSound() {
		// to do: put event handler code here.
		SoundName = choice1.getSelectedItem();
		loopClip = getAudioClip(getCodeBase(),   // load sound clip name from
						 SoundName);             //  selected choice.

	}
	//My code starts here
	public void start() {
			if (runner == null); {
				runner = new Thread(this);
				runner.start();
			}
	}
	public void stop() {
			if (runner != null) {
				runner.stop();
				runner = null;
			}
			if (looping = true) {
				loopClip.stop();    //Stop the sound loop.
				looping = false;
			}
	}


	/**
	 * Alarm4 main class creates new appletFrame 
	 *
	 * @param   args  
	 **/
/* MAIN DOES NOT WORK ON ANY PLATFORM AS OF 2008-02-20
	IT CAUSES A NULL POINTER EXCEPTION ON getCodeBase or getCodeBase */  
	public static void main(String[] args)  {
        MyAppletFrame appletFrame= new MyAppletFrame ("Alarm4");
        // The following makes a new instance of MyApplet
        Alarm4 myNewApplet = new Alarm4();
        WinListen off = new WinListen();
        myNewApplet.init();
        myNewApplet.start();
        appletFrame.addWindowListener(off);
        appletFrame.add("Center",myNewApplet);
        appletFrame.setSize(450,450);
        appletFrame.show();
   	}    
/* MAIN DOES NOT WORK ON ANY PLATFORM AS OF 2008-02-20
	IT CAUSES A NULL POINTER EXCEPTION ON getCodeBase or getCodeBase */  
/*        
	public static void main(String[] args) {
                Alarm4 ac = new Alarm4();
        }
*/
}

