      // General Information
      // ------------------------------------------------------------

      // File:  Piano.java
      // Type:  java applet
      // Date:  Sun Jan  5, 1997
      // Name:  blue
      // Line:  (Piano V7) - Display a keyboard, with adjacent keys


      // Applet Description
      // ------------------------------------------------------------

      /*

         This applet will simply display a keyboard of a given height
         and with, and with a given number of keys, in the middle of 
         the applet area.  The height and width and number of keys are 
         established globally.

         The Keyboard is now "trapped" in a Panel with a GridBagLayout,
         which evidently does not expand to fill its surrounding Panel.

         There is evidently a bit of a flaw somewhere - with the key
         on the far left.

      */

      // Package Identification
      // ------------------------------------------------------------

         package development.piano.v7;

      // Required packages
      // ------------------------------------------------------------

         import java.awt.*;
         import java.net.*;
         import java.applet.*;
         import blue.painter.*;
         import blue.shapes.*;


      // Applet class
      // ------------------------------------------------------------

         public class Piano extends java.applet.Applet
         {

            private int whiteKeyHeight = 80;
            private int whiteKeyWidth = 20;
            private int nrOfWhiteKeys = 8;

            private Keyboard keyboard = null;
            private KeyboardBuffer keyboardBuffer = null;

         // overriding init of java.awt.applet
            public void init() 
            {

            // Get the audioclips for this key
               AudioClip C, D, E, F, G, hA, hB, hC;
               URL Curl = null;
               try
               {
                  Curl = new URL("http://www.cs.oswego.edu/~blue/audio/sounds/simple/flute/C.au");
               }
               catch ( MalformedURLException e ) {};
               C = getAudioClip(Curl);
               D = getAudioClip(getCodeBase(),"audio/sounds/simple/flute/D.au");
               E = getAudioClip(getCodeBase(),"audio/sounds/simple/flute/E.au");
               F = getAudioClip(getCodeBase(),"audio/sounds/simple/flute/F.au");
               G = getAudioClip(getCodeBase(),"audio/sounds/simple/flute/G.au");
               hA = getAudioClip(getCodeBase(),"audio/sounds/simple/flute/hA.au");
               hB = getAudioClip(getCodeBase(),"audio/sounds/simple/flute/hB.au");
               hC = getAudioClip(getCodeBase(),"audio/sounds/simple/flute/hC.au");
               AudioClip[] acb = new AudioClip[nrOfWhiteKeys+1];
               acb[1] = C;
               acb[2] = D;
               acb[3] = E;
               acb[4] = F;
               acb[5] = G;
               acb[6] = hA;
               acb[7] = hB;
               acb[8] = hC;

            // Set the background color to white
               setBackground(Color.white);

            // Establish a layout so that the included
            // component with be centered within the applet.
               this.setLayout(new GridLayout(1,1));

            // Add a key
               keyboard = new Keyboard(nrOfWhiteKeys,whiteKeyHeight,whiteKeyWidth,acb);
               keyboardBuffer = new KeyboardBuffer(keyboard);
               add(keyboardBuffer);
               //gui = new VirtualPianoPanel(new Button("?"),keyboardBuffer,new Button("?"));
               //add(gui);

            }

         }


         class Key extends Painter
         {
            int width;
            int height;
            blue.shapes.Rectangle border;
            Circle dot;
            Color playColor = new Color(115,220,103);
            private AudioClip pitch;

            Key(int height, int width, AudioClip pitch)
            {
               super(width,height);
               this.width = width;
               this.height = height;
               border = new blue.shapes.Rectangle(height-1,width-1);
               dot = new Circle(7);
               this.pitch = pitch;
            }

            public boolean mouseDown(Event e, int x, int y)
            {
               highlight();
               play();
               return true;
            }

            public boolean mouseUp(Event e, int x, int y)
            {
               unhighlight();
               stop();
               return true;
            }

            public void play()
            {
              pitch.loop();
            }

            public void stop()
            {
              pitch.stop();
            }

            public void draw()
            {
              draw(border);
            }
               
            public void highlight()
            {
               setPenColor(playColor);
               jbk(height/4);
               paint(dot);
               jfd(height/4);
               setPenColor(Color.black);
               repaint();
            }

            public void unhighlight()
            {
               setPenColor(Color.white);
               jbk(height/4);
               paint(dot);
               jfd(height/4);
               setPenColor(Color.black);
               repaint();
            }


         }

         class Keyboard extends SupportingPainter
         {
            int size;
            double width;
            double height;
            blue.shapes.Rectangle frame;

            Key keys[];

            Keyboard(int s, int h, int w, AudioClip[] acb)
            {
               super(s+20,w*s+20);
               setLayout(new GridLayout(1,s));

               frame = new blue.shapes.Rectangle(h+10,s*w+10);

               size = s;
               width = w;
               height = h;

               keys = new Key[s+1];

               for ( int n = 1; n <= s; n++ )
               {
                  keys[n] = new Key(h,w,acb[n]);
               };

               for ( int i = 1; i <= s; i++ )
               {
                  add( keys[i] );
               };

               draw();
            }

            public void draw()
            {

               for ( int n = 1; n <= size; n++ )
               {
                 keys[n].draw();
               };
               frameit();
            }
              
            public Insets insets()
            {
              return new Insets(15,15,15,15);
            }

            public void frameit()
            {
               blue.shapes.Rectangle frame;
               for ( int i = 1; i <=5; i++ )
               {
                 frame = new blue.shapes.Rectangle(height+i,size*width+i);
                 draw(frame);
               };
            }


         }

         class KeyboardBuffer extends Panel
         {
            KeyboardBuffer(Keyboard k)
            {
               setLayout(new GridBagLayout());
               add(k);
            }
         }

