/**
 * GUI Commands
 * Copyright 2004 Andrew Pietsch
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * $Id: StringBuilder.java,v 1.4 2005/06/11 01:26:39 pietschy Exp $
 */

package org.pietschy.command;

import javax.swing.*;
import java.awt.event.KeyEvent;
import java.util.regex.Pattern;

/**
 * This class allows the string values of various fields to be derived from other
 * fields.  The template specifies the rules by which the final string result will be derived.
 *
 * @author andrewp
 * @version $Revision: 1.4 $
 */
class
StringBuilder
{

   private static Pattern textPattern = Pattern.compile("@text");
   private static Pattern acceleratorPattern = Pattern.compile("@accelerator");

   private static final String MAC_SHIFT = "\u21E7";
   private static final String MAC_ALT = "\u2325";
   private static final String MAC_CONTROL = "\u2303";
   private static final String MAC_COMMAND = "\u2318";


   private static Pattern[] all = new Pattern[]
   {
      textPattern,
      acceleratorPattern
   };

   private Face face;
   private String template;
   private boolean hasVars = false;

   public StringBuilder(Face face)
   {
      this.face = face;
   }

   public void setTemplate(String template)
   {
      this.template = template;
      this.hasVars = checkForVars(template);
   }

   public String getTemplate()
   {
      return template;
   }

   public String
   getString()
   {
      if (template == null)
         return null;

      if (!hasVars)
         return template;

      String result = template;
      result = textPattern.matcher(result).replaceAll(face.getText());
      result = acceleratorPattern.matcher(result).replaceAll(getAcceleratorText(face.getAccelerator()));

      return result;
   }


   public boolean
   checkForVars(String string)
   {
      if (string == null)
         return false;

      for (int i = 0; i < all.length; i++)
      {
         if (all[i].matcher(string).find())
            return true;
      }
      return false;
   }

   /**
    * Gets the user friendly string for an accelerator.
    *
    * @return a string representing the accelerator.
    */
   public String getAcceleratorText(KeyStroke accel)
   {
      if (accel == null)
         return "";

      String acceleratorText = "";

      int modifiers = accel.getModifiers();
      if (modifiers > 0)
      {
         acceleratorText = getModifiersText(modifiers);

         if (!CommandManager.isMacOS())
         {
            String delimiter = UIManager.getString("MenuItem.acceleratorDelimiter");
            // handle the case where the delimeter isn't specified or isn't applicable
            if (delimiter == null || delimiter.length() < 1)
               delimiter = "+";

             acceleratorText += delimiter;
         }

      }

      int keyCode = accel.getKeyCode();
      if (keyCode != 0)
      {
         acceleratorText += KeyEvent.getKeyText(keyCode);
      }
      else
      {
         acceleratorText += accel.getKeyChar();
      }

      return acceleratorText;
   }


   public boolean
   templateEquals(String template)
   {
      if (this.template != null)
         return this.template.equals(template);

      if (template != null)
         return template.equals(this.template);

      return true;
   }

   private String
   getModifiersText(int modifiers)
   {
      if (CommandManager.isMacOS())
      {
         String text = "";

         if (isPressed(modifiers, KeyEvent.CTRL_DOWN_MASK))
            text += MAC_CONTROL;

         if (isPressed(modifiers, KeyEvent.ALT_DOWN_MASK))
            text += MAC_ALT;

         if (isPressed(modifiers, KeyEvent.SHIFT_DOWN_MASK))
            text += MAC_SHIFT;

         if (isPressed(modifiers, KeyEvent.META_DOWN_MASK))
            text += MAC_COMMAND;

         return text;

      }

      return KeyEvent.getKeyModifiersText(modifiers);
   }


   private boolean
   isPressed(int modifiers, int mask)
   {
      return (modifiers & mask) == mask;
   }


}
