package org.pietschy.command;

import javax.swing.*;

/**
 * The DefaultFaceRender provides the base methods for configuring buttons and
 * menus as well as a standard implementation that is suitable for most platforms.
 */
public class
DefaultFaceRenderer
implements FaceRenderer
{
   public static DownArrowIcon defaultGroupIcon = new DownArrowIcon();

   public void
   configureButton(AbstractButton button, RenderContext buttonContext)
   {
      Face face = getFace(buttonContext);

      configureText(button, face);
      configureTextPosition(button, face);
      configureMnemonic(button, face);
      configureToolTip(button, face);
      configureIcons(button, face);

      // do some special rendering of buttons that show popups.
      if (buttonContext.getCommand() instanceof CommandGroup)
      {
         Icon icon = face.getIcon();
         String text = face.getText();
         // we only do it for buttons that have text but no icon.
         if (text != null && text.trim().length() > 0 && icon == null)
         {
            button.setHorizontalTextPosition(SwingConstants.LEADING);
            button.setIcon(getDefaultGroupIcon());
         }
      }
   }

   protected Face getFace(RenderContext buttonContext)
   {
      Face face = buttonContext.getFace();

      if (face == null)
         throw new RuntimeException("Failed to get the face '" + buttonContext.getFaceName() +
         "' from command '" + buttonContext.getCommand().getId()+ "'.  " +
         "This is probably because you forgot to load a configuration file, or forgot to add at least one face.");

      return face;
   }

   protected DownArrowIcon
   getDefaultGroupIcon()
   {
      return defaultGroupIcon;
   }


   public static void
   setDefaultGroupIcon(DownArrowIcon defaultGroupIcon)
   {
      DefaultFaceRenderer.defaultGroupIcon = defaultGroupIcon;
   }

   public void
   configureMenu(JMenuItem menu, RenderContext menuContext)
   {
      Face face = getFace(menuContext);

      configureText(menu, face);
      configureMnemonic(menu, face);

      if (face.isMenuTooltipEnabled())
         configureToolTip(menu, face);
      else
         menu.setToolTipText(null);

      configureAccelerator(menu, face);
      configureIcons(menu, face);
   }

   /**
    * Configures the text attributes of the button.
    *
    * @param button the button to configureMenu.
    * @param face
    */
   protected void
   configureText(AbstractButton button, Face face)
   {
      String text = face.getText();
      button.setText(text);
   }

   protected void
   configureTextPosition(AbstractButton button, Face face)
   {
      if (face.getVerticalTextPosition() != null)
      {
         button.setVerticalTextPosition(face.getVerticalTextPosition().intValue());
         // if the vertical position has been configured, then we automatically
         // set the horizontal CENTER to get the naturally expected results.
         // If we didn't do this, you'd always have to configureMenu the horizontal
         // position to centre as well.
         button.setHorizontalTextPosition(SwingConstants.CENTER);
      }
      else
      {
         if (face.getHorizontalTextPosition() != null)
            button.setHorizontalTextPosition(face.getHorizontalTextPosition().intValue());
      }
   }

   protected void
   configureMnemonic(AbstractButton button, Face face)
   {

      String text = face.getText();

      // only do mnemonics if the text is present and where not on mac os.
      if (text != null)
      {
         // the menonic index overrides the mnemonic.
         Integer mIndex = face.getMnemonicIndex();
         if (mIndex != null && mIndex.intValue() < text.length())
         {
            int mnemonicIndex = mIndex.intValue();
            button.setMnemonic(text.charAt(mnemonicIndex));
            button.setDisplayedMnemonicIndex(mnemonicIndex);
         }
         else
         {
            if (face.getMnemonic() != null)
               button.setMnemonic(face.getMnemonic().intValue());
         }
      }
   }

   protected void
   configureToolTip(AbstractButton button, Face face)
   {
      String description = face.getDescription();

      if (description != null && description.length() < 1)
      {
         button.setToolTipText(null);
      }
      else
      {
         button.setToolTipText(description);
      }
   }

   /**
    * Safely sets the accelerator for the specified menu.
    *
    * @param menu
    * @param face
    */
   protected void
   configureAccelerator(JMenuItem menu, Face face)
   {
      if (!(menu instanceof JMenu))
         menu.setAccelerator(face.getAccelerator());
   }

   protected void
   configureIcons(AbstractButton button, Face face)
   {
      button.setIcon(face.getIcon());
      button.setSelectedIcon(face.getSelectedIcon());
      button.setRolloverIcon(face.getRolloverIcon());
      button.setRolloverSelectedIcon(face.getRolloverSelectedIcon());
      button.setPressedIcon(face.getPressedIcon());
      button.setDisabledIcon(face.getDisabledIcon());

      if (face.getRolloverIcon() != null || face.getRolloverSelectedIcon() != null)
         button.setRolloverEnabled(true);

      if (face.getIconTextGap() != null)
         button.setIconTextGap(face.getIconTextGap().intValue());
   }
}
