import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;

public class NavigationButton extends Applet implements Runnable, MouseListener, MouseMotionListener
{
 int xc, yc, b_radius, c_radius, star_num, bb_radius; 
 int m = 0, c = 0, k;
 Dimension d;
 int angle[] = new int[8];
 int arcw, num, colnum, sleep;
 Color colors[];
 Color bgcolor[]    = new Color[1];
 Color b_bgcolor[]  = new Color[1];
 Color star_color[] = new Color[1];
 Thread th, tr;
 Graphics g, gr, g2;
 Image upd;
 STAR2 star;
 ARCButton arcb[] = new ARCButton[8];
 boolean bc = true;
 String url, target;
 String url_text[] = new String[8];
 String url_url[]  = new String[8];

 public void init()
 {
  addMouseListener(this); addMouseMotionListener(this);
  g = getGraphics();

  StringTokenizer st6 = new StringTokenizer(getParameter("bgcolor"), ",#");
  bgcolor[0] = new Color(Integer.parseInt(st6.nextToken()),
                         Integer.parseInt(st6.nextToken()),
                         Integer.parseInt(st6.nextToken()));

  setBackground(bgcolor[0]);
  d = getSize();

  upd = createImage(getSize().width, getSize().height);
  g2 = upd.getGraphics();
  gr = upd.getGraphics();

  StringTokenizer st3 = new StringTokenizer(getParameter("circle"), ",#");
    xc       = Integer.parseInt(st3.nextToken());
    yc       = Integer.parseInt(st3.nextToken());
    c_radius = Integer.parseInt(st3.nextToken());

  StringTokenizer st4 = new StringTokenizer(getParameter("star"), ",#");
    star_num   = Integer.parseInt(st4.nextToken());

    star_color[0] = new Color(Integer.parseInt(st4.nextToken()),
                              Integer.parseInt(st4.nextToken()),
                              Integer.parseInt(st4.nextToken()));

 
    star = new STAR2(xc, yc, c_radius, this, g2, star_num, star_color[0]);

    sleep = Integer.parseInt(getParameter("sleep"));

 
  StringTokenizer st0 = new StringTokenizer(getParameter("nm_colors"), ",#");
    colors = new Color[Integer.parseInt(st0.nextToken())];
    while(st0.hasMoreTokens())
    {
     colors[c++] = new Color(Integer.parseInt(st0.nextToken()),
                             Integer.parseInt(st0.nextToken()),
                             Integer.parseInt(st0.nextToken()));
    }

 StringTokenizer st1 = new StringTokenizer(getParameter("button"), ",#");
     b_radius = Integer.parseInt(st1.nextToken());

     bb_radius = Integer.parseInt(st1.nextToken());

     b_bgcolor[0] = new Color(Integer.parseInt(st1.nextToken()),
                              Integer.parseInt(st1.nextToken()),
                              Integer.parseInt(st1.nextToken()));
 
 for(int i = 1; (url = getParameter("url"+i)) !=null; i++)
 {    
  StringTokenizer st5 = new StringTokenizer(url, ",#");
  
  url_text[i-1] = st5.nextToken();
  url_url[i-1]  = st5.nextToken();
 }

 target = getParameter("target"); 
 
 StringTokenizer st10 = new StringTokenizer(getParameter("angle"), ",#");
    arcw = Integer.parseInt(st10.nextToken());
        
    while(st10.hasMoreTokens())
    {
     arcb[m] = new ARCButton(xc, yc, b_radius, bb_radius, this);
     
     angle[m++] = Integer.parseInt(st10.nextToken());
          
    }
    
 }

 public void update(Graphics g)
 {
  g.drawImage(upd, 0, 0, getSize().width, getSize().height, this);
 }

 public void setARC(int arc, Color co)
 {
  gr.setColor(co);
    
  for(int j = 1, k = 3; j <= 5; j++, k += 3)
  for(int i = 0; i < 3; i++)
  {
   gr.drawArc((xc-(5+k)-(i+(k-3)))-c_radius, (yc-(5+k)-(i+(k-3)))-c_radius, 2*(c_radius+((5+k)+(i+(k-3)))), 2*(c_radius+((5+k)+(i+(k-3)))), ((angle[arc]-arcw)+(i+(k-3))), ((2*arcw)-(2*(i+(k-3))))); 
  }
   arcb[arc].setCircleButton(gr, angle[arc], co, url_text[arc]);
   arcb[arc].setTriangle(gr, angle[arc], co);
  
 }

 public void drawNavigation(Color col1, Color col2)
 {
  gr.setColor(col2);
  for(int i = 0; i < 5; i++)
  gr.drawOval(xc-c_radius-i, yc-c_radius-i, 2*(c_radius+i), 2*(c_radius+i));

  for(int i = 0; i < angle.length; i++)
   {
    setARC(i, col1);
    
    arcb[i].setCircleButton(gr, angle[i], b_bgcolor[0], url_text[i]);
   }
 }

 public void start()
 {
  if(th == null)
    {
     th = new Thread(this);
     th.start(); 
     tr = new Thread(star);
     tr.start(); 
   
    }
 }

 public void stop()
 {
  if(th != null) { th.stop(); tr.stop(); th = null; }
 }

 public void run()
  {
   Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
   while (true)
   {
     StringTokenizer st2 = new StringTokenizer(getParameter("program"), ",#");
     while(st2.hasMoreTokens())
     {
      num = Integer.parseInt(st2.nextToken());
      switch(num)
                { 
                 case 1: 
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(0, colors[colnum]); 
                        break;
                        
                 case 2: 
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(1, colors[colnum]); 
                        break;

                 case 3: 
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(2, colors[colnum]);
                        break;

                 case 4:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(3, colors[colnum]);
                        break;

                 case 5:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(4, colors[colnum]);
                        break;

                 case 6:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(5, colors[colnum]);
                        break;

                 case 7:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(6, colors[colnum]);
                        break;

                 case 8:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(7, colors[colnum]);
                        break;

                 case 9:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(0, colors[colnum]); setARC(4, colors[colnum]);
                        break;

                 case 10:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(1, colors[colnum]); setARC(5, colors[colnum]);
                        break;

                 case 11:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(2, colors[colnum]); setARC(6, colors[colnum]);
                        break;

                 case 12:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(3, colors[colnum]); setARC(7, colors[colnum]);
                        break;

                 case 13:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(0, colors[colnum]); setARC(2, colors[colnum]);
                        setARC(4, colors[colnum]); setARC(6, colors[colnum]);
                        break;

                 case 14:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(1, colors[colnum]); setARC(3, colors[colnum]);
                        setARC(5, colors[colnum]); setARC(7, colors[colnum]);
                        break;

                 case 15:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(0, colors[colnum]); setARC(3, colors[colnum]);
                        setARC(5, colors[colnum]); 
                        break;

                 case 16:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(1, colors[colnum]); setARC(4, colors[colnum]);
                        setARC(6, colors[colnum]);
                        break;

                 case 17:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(2, colors[colnum]); setARC(5, colors[colnum]);
                        setARC(7, colors[colnum]); 
                        break;

                 case 18:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(0, colors[colnum]); setARC(3, colors[colnum]); 
                        setARC(6, colors[colnum]);
                        break;

                 case 19:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(1, colors[colnum]); setARC(4, colors[colnum]); 
                        setARC(7, colors[colnum]);
                        break;

                 case 20:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(0, colors[colnum]); setARC(2, colors[colnum]);
                        setARC(5, colors[colnum]); 
                        break;

                 case 21:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(1, colors[colnum]); setARC(3, colors[colnum]);
                        setARC(6, colors[colnum]); 
                        break;

                 case 22:
                        drawNavigation(getBackground(), colors[colnum]);
                        setARC(2, colors[colnum]);
                        setARC(4, colors[colnum]); setARC(7, colors[colnum]);  
                        break;

                }
       setSleep(sleep);                       
     } if(++colnum >= colors.length) colnum = 0;
   
   }
   
 }
    
  public void setSleep(int sleep)
  {
   try { Thread.sleep(sleep); } catch (InterruptedException e){}
  }

  public void mouseExited(MouseEvent mee)
  {
   th.resume(); bc = false;
  }

 public void mouseReleased(MouseEvent mee){}

 public void mouseClicked(MouseEvent mee) {}

 public void mouseMoved(MouseEvent mee)
 {
  int x = mee.getX(), y = mee.getY();
  
  if(bc)
  for(int i = 0; i < arcb.length; i++) 	
  {
   if(arcb[i].contains(x, y, angle[i])) 
   { 
     drawNavigation(getBackground(), colors[colnum]);
     setARC(i, colors[colnum]);
     
     th.suspend(); bc = false; k = i;
   }
   
  }

  if(!bc && !arcb[k].contains(x, y, angle[k])) { th.resume(); bc = true; }

}


 public void mouseDragged(MouseEvent mee) {}

 public void mouseEntered(MouseEvent mee) {}  

 public void mousePressed(MouseEvent mee) 
 {
  int x = mee.getX(), y = mee.getY();

  for(int i = 0; i < arcb.length; i++) 	
  {
   if(arcb[i].contains(x, y, angle[i])) 
    { 
     try {
          URL u = new URL(getDocumentBase(), url_url[i]);
	  getAppletContext().showDocument(u, target);
	 } catch (MalformedURLException e) {} 
    }
  }
 }
}

class STAR2 extends Thread
{
 int xc, yc, radius, num;
 Polygon p[];
 int x1[] = {0,0,2,8,4,6,0,-6,-4,-8,-2,0};
 int y1[] = {0,-4,-2,-2,2,8,4,8,2,-2,-2,-8};
 int x, y, u, m;
 Thread th1;
 Graphics g2;
 boolean b = false;
 NavigationButton nb;
 Color c;

 public STAR2(int xc, int yc, int radius, NavigationButton nb, Graphics g2, int num, Color c)
 {
  p = new Polygon[num];
  this.nb = nb;
  this.g2 = g2;
  this.xc = xc;
  this.yc = yc;
  this.radius = radius;
  this.num = num;
  this.c = c;
  
 }

 public void run() 
   {
    Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
    while (true) { 
                   g2.setColor(nb.getBackground());
                   g2.fillOval(xc-(radius-1), yc-(radius-1), (2*(radius-1)), (2*(radius-1)));

                   for(int i = 0; i < p.length; i++)
                      {
                       p[i] = new Polygon(x1, y1, 12);

                       if(b)
                            {
                             x = (int)(Math.cos((i+u)*0.48)*(radius-10));
                             y = (int)(Math.sin((i+u)*0.48)*(radius-10));
                            }

                       else  
                           {
                            x = (int)(Math.cos((i)*0.48)*(u));
                            y = (int)(Math.sin((i)*0.48)*(u));
                           }
                     
                       p[i].translate(xc,yc); // keskipiste 
                       p[i].translate(x,y);
    
                   g2.setColor(c);
                   g2.fillPolygon(p[i]);

                   g2.drawLine(xc-5, yc, xc+5, yc);
                   g2.drawLine(xc, yc-5, xc, yc+5);
                   
                 }
                 if(b) u += ++m; 

                 if((++u > radius-10) && !b)
                    {
                     u = 0; b = true;
                     try { th1.sleep(500); } catch (InterruptedException e) {}
                    }      
                  
                 try { th1.sleep(50); } catch (InterruptedException e) {}
                 nb.repaint();
                 
                }
       
   }
}

class ARCButton extends Canvas
{
 int xc, yc, b_r, bb_r, x, y;
 NavigationButton nb;
 Point p1, p2, p3;
 FontMetrics fm;
 Font f;

  
 public ARCButton(int xc, int yc, int b_r, int bb_r, NavigationButton nb)
 {
  this.xc = xc;
  this.yc = yc;
  this.b_r = b_r;
  this.bb_r = bb_r;
  this.nb = nb;
  
  f  = new Font("Helvetica",1,16); 
  fm = getFontMetrics(f);
 }

  public void setCircleButton(Graphics g, int angle, Color c, String text)
  {
   g.setColor(c);
     
   x = (int)(Math.cos(((360-angle)*2*Math.PI)/360)*b_r);
   y = (int)(Math.sin(((360-angle)*2*Math.PI)/360)*b_r);

   g.setFont(f);
   g.drawString(text, (xc+x)-((fm.stringWidth(text))/2), (yc+y)+(fm.getAscent()/2)); 
   
   g.drawOval((xc+x)-(bb_r/2), (yc+y)-(bb_r/2), bb_r, bb_r);

  }

  public boolean contains(int x, int y, int angle)  // Circle 
  {
   int xt = (int)(Math.cos(((360-angle)*2*Math.PI)/360)*b_r);
   int yt = (int)(Math.sin(((360-angle)*2*Math.PI)/360)*b_r);

   return (((xc+xt-x)*(xc+xt-x) + (yc+yt-y)*(yc+yt-y)) <= ((bb_r/2)*(bb_r/2)));
  }

  public void setTriangle(Graphics g, int angle, Color c)
  {
   g.setColor(c);
   
   p1 = new Point((int)(Math.cos(((360-angle)*2*Math.PI)/360)*(b_r+30))+xc,
                  (int)(Math.sin(((360-angle)*2*Math.PI)/360)*(b_r+30))+yc);
   
   p2 = new Point((int)(Math.cos(((360-angle-3)*2*Math.PI)/360)*(b_r+15))+xc,
                  (int)(Math.sin(((360-angle-3)*2*Math.PI)/360)*(b_r+15))+yc);

   p3 = new Point((int)(Math.cos((((360-angle)+3)*2*Math.PI)/360)*(b_r+15))+xc,
                  (int)(Math.sin((((360-angle)+3)*2*Math.PI)/360)*(b_r+15))+yc);

   g.drawLine(p1.x, p1.y, p2.x, p2.y);
   g.drawLine(p2.x, p2.y, p3.x, p3.y);
   g.drawLine(p3.x, p3.y, p1.x, p1.y);
   
  }


} 
