-- $Date: 2004/03/08 10:42:42 $
-- $Revision: 1.7 $
-- $Author: jcrocholl $
-- $Hash: 4f89a703f35f8415cbd8d978293853ba $

-- This file was automatically created with ado.php.
-- Manual changes will be lost when it is updated.

with Integer_Strings; use Integer_Strings;
with Enum_Strings; use Enum_Strings;
with Messages; use Messages;

package body Boxes.Keys is

   -- Constructor for instances.
   function Create
     (Key      : in Key_Access-- The initial key.
      Middle_C : in Integer)    -- The initial middle c.
     return Key_Box_Access      -- The newly created key box.
   is
      Result : Key_Box_Access := new Key_Box;
   begin
      Result.Key := Key;
      Result.Middle_C := Middle_C;
      return Result;
   end Create;

   -- Accessor to read the key of a key box.
   function Get_Key
     (This : access Key_Box-- The key box to read from.
     return Key_Access is    -- The key of that key box.
   begin
      return This.Key;
   end Get_Key;

   -- Accessor to read the middle c of a key box.
   function Get_Middle_C
     (This : access Key_Box-- The key box to read from.
     return Integer is       -- The middle c of that key box.
   begin
      return This.Middle_C;
   end Get_Middle_C;

   function Get_Center
     (This  : access Key_Box-- The key box object instance.
      Index : in Accidentals-- Which accidental position?
     return Vector is         -- Display offset for proper placement.
   begin
      return (Real(Index) * 100.0 - 50.0, -50.0 * Real(This.Offsets(Index)));
   end Get_Center;

   procedure Layout
     (This : access Key_Box;        -- The key box object instance.
      Font : access Font_Loader) is -- Use this font loader.
   begin
      if not Quiet then Debug("preparing key layout"); end if;

      if Get_Fifths(This.Key) > 0 then
         case This.Middle_C is
         when -6 => This.Offsets := (4, 1, 5, 2, -1, 3, 0);
         when 6 => This.Offsets := (2, -1, 3, 0, -3, 1, -2);
         when => This.Offsets := (3, 0, 4, 1, -2, 2, -1);
         when 2 => This.Offsets := (-2, 2, -1, 3, 0, 4, 1);
         when others => Error("unsupported middle C position" & This.Middle_C'Img);
         end case;

         for Index in 1 .. Get_Fifths(This.Key) loop
            This.Glyphs(Index) := Load_Glyph(Font, "accidentals/sharp");
            if Index = 1 then
               This.Bounds :=
                 Get_Bounds(This.Glyphs(Index)) + Get_Center(This, Index);
            else
               This.Bounds := Max(This.Bounds,
                 Get_Bounds(This.Glyphs(Index)) + Get_Center(This, Index));
            end if;
         end loop;
      elsif Get_Fifths(This.Key) < 0 then
         case This.Middle_C is
         when -6 => This.Offsets := (0, 3, -1, 2, -2, 1, -3);
         when 6 => This.Offsets := (-2, 1, -3, 0, -4, -1, 2);
         when => This.Offsets := (-1, 2, -2, 1, -3, 0, -4);
         when 2 => This.Offsets := (1, 4, 0, 3, -1, 2, -2);
         when others => Error("unsupported middle C position" & This.Middle_C'Img);
         end case;


         for Index in 1 .. -Get_Fifths(This.Key) loop
            This.Glyphs(Index) := Load_Glyph(Font, "accidentals/flat");
            if Index = 1 then
               This.Bounds :=
                 Get_Bounds(This.Glyphs(Index)) + Get_Center(This, Index);
            else
               This.Bounds := Max(This.Bounds,
                 Get_Bounds(This.Glyphs(Index)) + Get_Center(This, Index));
            end if;
         end loop;
      end if;
   end Layout;

   procedure Print
     (This   : access Key_Box;            -- The key box object instance.
      To     : access Printer'Class-- Render to this printer.
      Center : in Vector) is              -- Center of container.
   begin
      for Index in 1 .. abs(Get_Fifths(This.Key)) loop
         Print(To, This.Glyphs(Index),
           Center + This.Center + Get_Center(This, Index));
      end loop;

      Print_Bounds(This, To, Center);
   end Print;

end Boxes.Keys;