//  This applet displays a selected color.  There are buttons to control
//  RGB and HSB and the desired color is displayed in a large view area.
//
//  The layout: grid of three panels - two panels on the right control
//  red, green, blue & hue, saturation, brightness; panel on left
//  is a canvas for displaying the chosen color.

import java.awt.*;

public class ColorTest extends java.applet.Applet
{
   ColorControls RGBcontrols, HSBcontrols;  //two control panel objects
   Canvas swatch;
   Color theColor;

   public void init()
   {
      theColor = new Color(0,0,0);  //theColor is the display color
      float[] HSB = Color.RGBtoHSB(theColor.getRed(),
                                   theColor.getGreen(),
                                   theColor.getBlue(), (new float[3]));

      setLayout(new GridLayout(1,4,10,10));  //three panels for display

      swatch = new Canvas();
      swatch.setBackground(theColor);  // display black to start

      // Set up RGB section of control panel - pass "this" for updating.
      RGBcontrols = new ColorControls
                        (this,
                         "Red", "Green", "Blue",
                         theColor.getRed(), theColor.getGreen(), theColor.getBlue());

      HSBcontrols = new ColorControls
                        (this,
                         "Hue", "Saturation", "Brightness",
                         (int)(HSB[0]*360), (int)(HSB[1]*100), (int)(HSB[2]*100));

      add(swatch);
      add(new Button("Do It!"));
      add(RGBcontrols);
      add(HSBcontrols);
   }

   public boolean action(Event evt, Object obj)
   {
      if (evt.target instanceof Button)
      {
         repaint();
         return true;
      }
      else
         return false;
   }

   // override insets method to give more definition to objects
   public Insets insets()
   {
      return new Insets(10,10,10,10);
   }

   void update(ColorControls in)
   {
      String v1 = in.f1.getText();  // a number (in text) representing Red or Hue
      String v2 = in.f2.getText();  // a number (in text) representing Green or Saturation
      String v3 = in.f3.getText();  // a number (in text) representing Blue or Brightness

      if (in == RGBcontrols)
      {
         theColor = new Color(Integer.parseInt(v1), Integer.parseInt(v2), Integer.parseInt(v3));

         float[] HSB = Color.RGBtoHSB(theColor.getRed(), theColor.getGreen(), theColor.getBlue(), (new float[3]));
         HSB[0] *= 360;  // Need degrees from 0-1 range supplied by RGBtoHSB
         HSB[1] *= 100;  // Need percent from 0-1 range ...
         HSB[2] *= 100;  // Need percent from 0-1 range ...

         HSBcontrols.f1.setText(String.valueOf((int)HSB[0]));
         HSBcontrols.f2.setText(String.valueOf((int)HSB[1]));
         HSBcontrols.f3.setText(String.valueOf((int)HSB[2]));

         swatch.setBackground(theColor);
         repaint();
      }
      else
      {
         int f1 = Integer.parseInt(v1);
         int f2 = Integer.parseInt(v2);
         int f3 = Integer.parseInt(v3);

         theColor = Color.getHSBColor((float)(f1/360.0), (float)(f2/100.0), (float)(f3/100.0));

         RGBcontrols.f1.setText(String.valueOf(theColor.getRed()));
         RGBcontrols.f2.setText(String.valueOf(theColor.getGreen()));
         RGBcontrols.f3.setText(String.valueOf(theColor.getBlue()));

         swatch.setBackground(theColor);
         repaint();
      }
   }
}

class ColorControls extends Panel
{
   TextField f1, f2, f3;  // fields to show 
   ColorTest outerparent;    // the applet pointer goes here

   ColorControls(ColorTest target,
                 String l1, String l2, String l3,
                 int v1, int v2, int v3)
   {
      this.outerparent = target;
      setLayout(new GridLayout(3,4,10,10));

      f1 = new TextField(String.valueOf(v1), 10);
      f2 = new TextField(String.valueOf(v2), 10);
      f3 = new TextField(String.valueOf(v3), 10);

      add(new Label(l1, Label.RIGHT));
      add(f1);
      add(new Label(l2, Label.RIGHT));
      add(f2);
      add(new Label(l3, Label.RIGHT));
      add(f3);
   }

   public Insets insets()
   {
      return new Insets (10,10,10,10);
   }

   public boolean action(Event evt, Object obj)
   {
      if (evt.target instanceof TextField)
      {
         this.outerparent.update(this);
         return true;
      }
      else
         return false;
   }
}