/**
 * 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: FaceId.java,v 1.10 2006/02/26 00:59:05 pietschy Exp $
 */

package org.pietschy.command;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * A class that represents the Id of a {@link Face}.  It consists of the id of the
 * {@link Face face's} parent and the {@link Face#getName name} of the face.
 */
public class
FaceId
{
   static final String _ID_ = "$Id: FaceId.java,v 1.10 2006/02/26 00:59:05 pietschy Exp $";

   private String parentId;
   private String name;


   private static Pattern absolutePattern = Pattern.compile("(..*)\\[(.*)\\]");
   private static Pattern relativePattern = Pattern.compile("\\[(.*)\\]");

   public FaceId(String parentId, String faceName)
   {
      if (parentId == null)
         throw new NullPointerException("parentId is null");

      if (faceName == null)
         throw new NullPointerException("faceName is null");

      this.parentId = parentId;
      this.name = faceName;
   }

   public String getName()
   {
      return name;
   }

   public String
   getParentId()
   {
      return parentId;
   }

   public boolean
   isAnonymous()
   {
      return IdHelper.isAnonymous(getParentId());
   }


   /**
    * Returns a string representation of the object. In general, the
    * <code>toString</code> method returns a string that
    * "textually represents" this object. The result should
    * be a concise but informative representation that is easy for a
    * person to read.
    * It is recommended that all subclasses override this method.
    * <p/>
    * The <code>toString</code> method for class <code>Object</code>
    * returns a string consisting of the name of the class of which the
    * object is an instance, the at-sign character `<code>@</code>', and
    * the unsigned hexadecimal representation of the hash code of the
    * object. In other words, this method returns a string equal to the
    * value of:
    * <blockquote>
    * <pre>
    * getClass().getName() + '@' + Integer.toHexString(hashCode())
    * </pre></blockquote>
    *
    * @return a string representation of the object.
    */
   public String
   toString()
   {
      return parentId + "[" + name + "]";
   }

   public boolean equals(Object o)
   {
      if (this == o) return true;
      if (!(o instanceof FaceId)) return false;

      final FaceId faceId = (FaceId) o;

      if (!name.equals(faceId.name)) return false;
      if (!parentId.equals(faceId.parentId)) return false;

      return true;
   }

   public int hashCode()
   {
      int result;
      result = parentId.hashCode();
      result = 29 * result + name.hashCode();
      return result;
   }

   /**
    * Parses a string of the form '&lt;parentId&gt;<b>[</b>&lt;faceName&gt;<b>]</b>' to generate
    * a new faceid based on the current face.  This method can also parse relative references
    * that don't define the parent element.
    * @param relative the face that defines the parent for relative ids.
    * @param relativeId the face id that is to be parsed.
    * @return a new FaceId
    */
   public static FaceId parseFaceReference(FaceId relative, String relativeId)
   {
      Matcher matcher = absolutePattern.matcher(relativeId);
      if (matcher.matches())
      {
         return new FaceId(matcher.group(1), matcher.group(2));
      }
      else
      {
         matcher = relativePattern.matcher(relativeId);
         if (matcher.matches())
         {
            return new FaceId(relative.getParentId(), matcher.group(1));
         }
         else
         {
            throw new IllegalArgumentException("Not a valid faceId: " + relativeId);
         }
      }
   }

   /**
    * Parses a string of the form '&lt;parentId&gt;<b>[</b>&lt;faceName&gt;<b>]</b>'.
    * @param string the face id of the form form '&lt;parentId&gt;<b>[</b>&lt;faceName&gt;<b>]</b>'.
    * @return a face id matching the specified string.
    * @throws IllegalArgumentException if the string doesn't confirm the the specified standard.
    */
   public static FaceId parseFaceReference(String string)
   {
      Matcher matcher = absolutePattern.matcher(string);
      if (matcher.matches())
      {
         return new FaceId(matcher.group(1), matcher.group(2));
      }
      else
      {
         throw new IllegalArgumentException("Not a valid faceId: " + string);
      }
   }

//
//   public static void main(String[] args)
//   {
//      FaceId parent = FaceId.parse("abc[default]", null);
//      System.out.println(FaceId.parse("[button]", parent));
//
//   }
}
