/**
 * 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: AbstractVisitor.java,v 1.5 2005/06/15 23:42:57 pietschy Exp $
 */
package org.pietschy.command;


/**
 * AbstractVisitor provides a default implementation of {@link GroupVisitor} that predefines
 * a number of visitation modes by providing a default implementation of {@link #conditionallyVisitChildren}.
 * <p>
 * The available modes are as follows.
 * <dl>
 *    <dt><b>SHALLOW</b></dt>
 *      <dd>
 *      The visitor will visit the parent group and its immediate children only.  The children of
 *      any inline group will be visited as if they are members of the main group.
 *      </dd>
 *    <dt><b>DEEP</b></dt>
 *      <dd>
 *      The visitor traverse the entire graph of commands under the top level group.
 *      </dd>
 * </dl>
 *
 * @version $Revision: 1.5 $
 * @author andrewp
 */
public abstract class
AbstractVisitor
implements GroupVisitor
{
   // Constants and variables
   // -------------------------------------------------------------------------
   private static final String _ID_ = "$Id: AbstractVisitor.java,v 1.5 2005/06/15 23:42:57 pietschy Exp $";

   public  static class VisitMode
   {}

   /**
    * The visitor will visit the immediate children only (including inline children).
    */
   public static final VisitMode SHALLOW = new VisitMode();

   /**
    * The visitor traverse the entire graph of commands under the top level group.
    */
   public static final VisitMode DEEP = new VisitMode();

   /**
    * The mode in which the visitor should operate.
    */
   protected VisitMode mode;

   /**
    * The top level group the the visitor is visiting.
    */
   private CommandGroup parent;


   /**
    * Constructs a new Abstract visitor using the specified visitation mode.
    * @param mode  the {@link VisitMode} the visitor should use.
    */
   public AbstractVisitor(VisitMode mode)
   {
      this.mode = mode;
   }


   public void
   conditionallyVisitChildren(CommandGroup group)
   {
      if (isParentGroup(group))
         group.visitChildren(this);
      else if (DEEP.equals(mode))
         group.visitChildren(this);
   }

   protected boolean
   isParentGroup(CommandGroup group)
   {
      if (parent == null)
      {
         parent = group;
         return true;
      }

      return false;
   }

}
