/*********************************************************


   beacon.java shows which NCDXF/IARU Beacon is transmiting
   at any given second.  It presumes the computer clock
   is accurate and needs a graphic of the world map "world.jpg"
   Beacon info based on http://www.ncdxf.org/beacon/beaconSchedule.htm
   
   version 1.0 -- Written July 11, 2002 Chris Thiel <cct@ktb.net>


**********************************************************/


import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.text.*;
import java.lang.*;

public class beacon extends Applet implements Runnable
{
  private Thread timer;
  private Image offScreenImage = null;
  private Graphics offScreenGraphics = null;
  private Dimension offScreenSize = null;
  private int lastsec = -1;
  private GregorianCalendar cal;
  public Choice daMenu;
  private String lastdate = "", lasttime = "";
  private DateFormat dfdate, dftime;
  private boolean doSeconds;
  private int sleeptime;
  private Locale locale;
  private int style;
  private int selectedFreq;
  private String[] bName = new String[18];// names of beacons
  private String[] fName = new String[5]; // names of the 5 frequencies
  private int[] blx = new int[18];	  // x locations of beacons
  private int[] bly = new int[18];	  // y locations of beacons
  private Image img = null;
  private int rings;

  public beacon()
  {
    this(TimeZone.getDefault(), Locale.getDefault());
  }

  private beacon(TimeZone timezone, Locale locale)
  {
   // cal = new GregorianCalendar(timezone);
    cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
     daMenu = new Choice();
    this.locale = locale;
    sleeptime = 200;
    int i;
    fName[0]="14.100";
    fName[1]="18.110";
    fName[2]="21.150";
    fName[3]="24.930";
    fName[4]="28.200";
    bName[0]= "United Nations (4U1UN)";
    bName[1]= "Canada (VE8AT)";
    bName[2]= "Unites States (W6WX)";
    bName[3]= "Hawaii (KH6WO)";
    bName[4]= "New Zealand (ZL6B)";
    bName[5]= "Australia (VK6RBP)";
    bName[6]= "Japan (JA2IGY)";
    bName[7]= "Russia (RR9O)";
    bName[8]= "Hong Kong (VR2B)";
    bName[9]= "Sri Lanka (4S7B)";
    bName[10]="South Africa (ZS6DN)";
    bName[11]="Kenya (5Z4B)";
    bName[12]="Israel (4X6TU)";
    bName[13]="Finland (OH2B)";
    bName[14]="Madeira (CS3B)";
    bName[15]="Argentina (LU4AA)";
    bName[16]="Peru (OA4B)";
    bName[17]="Venezuela (YV5B)";
    blx[0] = 437; bly[0] =111;
    blx[1] = 430; bly[1] =10;
    blx[2] = 370; bly[2] =100;
    blx[3] = 304; bly[3] =118;
    blx[4] = 284; bly[4] =253;
    blx[5] = 204; bly[5] =227;
    blx[6] = 232; bly[6] =119;
    blx[7] = 157; bly[7] =56;
    blx[8] = 208; bly[8] =140;
    blx[9] = 152; bly[9] =160;
    blx[10] = 79; bly[10] =232;
    blx[11] = 95; bly[11] =185;
    blx[12] = 90; bly[12] =132;
    blx[13] = 78; bly[13] =56;
    blx[14] = 20; bly[14] =128;
    blx[15] = 455; bly[15] =252;
    blx[16] = 435; bly[16] =191;
    blx[17] = 455; bly[17] =166;
    
    
    for (i=0; i<5; i++) daMenu.addItem(fName[i]);
    add(daMenu);
    selectedFreq=daMenu.getSelectedIndex();


   /**
   * Set style of date display: 0 = full, 1 = long, 2 = medium, 3 = short
   **/

    dftime = DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.UK);
    dfdate = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
    dftime.setCalendar(cal);
    dfdate.setCalendar(cal);
    timer = new Thread(this);
    timer.start();
  }

  /**
   * Draw 
   **/
  public void paint(Graphics g)
  {
    int s,m,h, bIndex,i,xLoc;
    String todaydate, todaytime;
    Dimension size;
    int[] fIndex = new int[5];
   
    Date now = new Date();

    cal.setTime(now);
    s = (int)cal.get(Calendar.SECOND);
    m = (int)cal.get(Calendar.MINUTE);
    h = (int)cal.get(Calendar.HOUR_OF_DAY);
    bIndex = (int) Math.floor((60*(m%3)+s)/10);
    for (i=0; i<5; i++) fIndex[i] = ((18-i)+bIndex)%18;
    todaydate = dfdate.format(now);
    todaytime = dftime.format(now) + " UTC";
  
    // Erase and redraw the digital time
  
      g.drawImage (img, 0,0,null);
      //g.setColor(Color.cyan);
      //g.fillRect(0,260,75,40);   
      g.setColor(Color.blue);
      g.drawString(todaydate, 5, 30);
      g.drawString(todaytime, 5, 10);
      
      //g.setColor(Color.yellow);
      //g.fillRect(75,0,175,40);
        
      selectedFreq=daMenu.getSelectedIndex();  
      g.setColor(((s%2)==0)? Color.red : Color.yellow);
      g.fillOval(blx[fIndex[selectedFreq]], bly[fIndex[selectedFreq]], 10, 10);
       g.setColor(((s%2)==1)? Color.red : Color.yellow);
      g.fillOval(blx[fIndex[selectedFreq]]+2, bly[fIndex[selectedFreq]]+2, 6, 6);
      g.setColor(Color.orange);
    //  g.drawOval(blx[fIndex[selectedFreq]]-(s%10), bly[fIndex[selectedFreq]]-(s%10), 11+2*(s%10), 11+2*(s%10));
      rings = (rings+16)%100;
     g.drawOval(blx[fIndex[selectedFreq]]-(rings), bly[fIndex[selectedFreq]]-(rings), 11+rings*2, 11+rings*2);
      g.setColor(Color.blue);
      switch (s%10){
       case (3):g.drawString(fName[selectedFreq]+": "+bName[fIndex[selectedFreq]]+" 100 W", 190,275);
            break;
        case (4):g.drawString(fName[selectedFreq]+": "+bName[fIndex[selectedFreq]]+" 10 W", 190,275); 
            break;
        case(5):g.drawString(fName[selectedFreq]+": "+bName[fIndex[selectedFreq]]+" 1 W", 190,275); 
            break;
        case (6):g.drawString(fName[selectedFreq]+": "+bName[fIndex[selectedFreq]]+" 1/10 W", 190,275); 
            break;
       default:g.drawString(fName[selectedFreq]+": "+bName[fIndex[selectedFreq]], 190,275); 	
            break;
       
      }
      g.drawString(fName[selectedFreq]+": "+bName[fIndex[selectedFreq]], 190,275);
      
      
      g.setColor(Color.black);
      xLoc = 0;
      for (i=0; i<5; i++){
       if (i != selectedFreq) {
            g.drawString(fName[i]+": "+bName[fIndex[i]], 50+(xLoc%2)*240,285+12*((int)(xLoc/2)));
            xLoc++;
            }
      }
   
  }

  /**
   * Restart the clock
   **/
  public void start()
  {
     img = getImage(getCodeBase(), "world.jpg");
    if (timer == null) {
      timer = new Thread(this);
      timer.start();
    }
  }

  /**
   * Stop the clock
   **/
  public void stop()
  {
    timer = null;
  }

  /**
   * Main loop of the thread: sleep, repaint, sleep,...
   **/
  public void run()
  {
    while (timer != null) {
      try {Thread.sleep(sleeptime);} catch (InterruptedException e){}
      repaint();

    }
    timer = null;
  }

  /**
   * Paint the screen, without first clearing the area
   **/
  public final void update(Graphics theG)
  {
    Dimension dim = getSize(); //see if we the size changed or 1st time
    if ( (offScreenImage==null)||
         (dim.width != offScreenSize.width) ||
         (dim.height != offScreenSize.height) ) {
         offScreenImage= createImage(dim.width, dim.height);
         offScreenSize = dim;
         offScreenGraphics = offScreenImage.getGraphics();
         }
         
    paint(offScreenGraphics);//construct updated image
    theG.drawImage(offScreenImage, 0, 0, null);//put it on the screen
  }
 
}

