/**
 * 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: MatchVisitor.java,v 1.6 2005/09/18 00:37:18 pietschy Exp $
 */

package org.pietschy.command;


/**
 * This class implements a visitor that will search the children of a group to find a group with the same
 * textural value.  This visitor is typically used when embedding plugin menus into the main menu heirarchy.
 *
 * <p>
 * For Example:
 * <pre>
 *
   private void installMenu(GroupCommand pluginMenu)
   {
      // reset all the menus back to their default state
      mainMenuGroup.visit(new ResetVisitor(ResetVisitor.SHALLOW));

      // try and find an existing menu that has the same name as
      // the menu being added
      MatchVisitor visitor = new MatchVisitor(pluginMenu, Face.MENU, MatchVisitor.SHALLOW);
      mainMenuGroup.visit(visitor);

      // if we found one, installFace the menu to it, otherwise installFace it to the main menu
      if (visitor.foundMatch())
         visitor.getMatchingGroup().addInline(pluginMenu);
      else
         mainMenuGroup.installFace(pluginMenu);
   }
</pre>
 *
 * @version $Revision: 1.6 $
 * @author andrewp
 */
public class
MatchVisitor
extends AbstractVisitor
{

   private String textToMatch;
   private String faceName;
   private CommandGroup matchingGroup;

   public MatchVisitor(CommandGroup groupToMatch, String faceName)
   {
      this(groupToMatch, faceName, SHALLOW);
   }

   public MatchVisitor(CommandGroup groupToMatch, String faceName, VisitMode mode)
   {
      super(mode);
      this.textToMatch = groupToMatch.getFace(faceName).getText();
      this.faceName = faceName;
   }

   public void
   visit(ActionCommand command)
   {
   }

   public void
   visit(CommandGroup group)
   {
      if (foundMatch())
         return;

      // we don't want to match the top level group..
      if (isParentGroup(group))
      {
         group.visitChildren(this);
      }
      else
      {
         if (textMatches(group))
            matchingGroup = group;
         else
            conditionallyVisitChildren(group);
      }
   }

   private boolean
   textMatches(CommandGroup group)
   {
      String text = group.getFace(faceName).getText();
      return textToMatch.equalsIgnoreCase(text);
   }

   public boolean
   foundMatch()
   {
      return matchingGroup != null;
   }

   public CommandGroup
   getMatchingGroup()
   {
      return matchingGroup;
   }
}
