//////////////////////////////////////////////////////////////////////////////
// 
//               Copyright 2010, Starting Block Technologies
//                        www.startingblocktech.com
//
//////////////////////////////////////////////////////////////////////////////

package com.startingblocktech.tcases;

import com.startingblocktech.tcases.util.ToString;
import static com.startingblocktech.tcases.DefUtils.*;

import org.apache.commons.lang.ObjectUtils;

import java.util.HashSet;
import java.util.Set;

/**
 * Defines the properties of a value for an {@link IVarDef input variable}.
 *
 * @version $Revision$, $Date$
 */
public class VarValueDef extends Conditional
  {
  /**
   * Defines the type of an input value.
   *
   * @version $Revision$, $Date$
   */
  public enum Type
    {
    VALID( true), FAILURE( false), ONCE( true);

    Type( boolean valid)
      {
      valid_ = valid;
      }

    /**
     * Returns if this type of value is a valid member of the variable input domain.
     */
    public boolean isValid()
    {
    return valid_;
    }

    private boolean valid_;
    }

  /**
   * Creates a new VarValueDef object.
   */
  public VarValueDef()
    {
    this( null);
    }

  /**
   * Creates a new VarValueDef object.
   */
  public VarValueDef( String name)
    {
    this( name, Type.VALID);
    }

  /**
   * Creates a new VarValueDef object.
   */
  public VarValueDef( String name, Type type)
    {
    setName( name);
    setType( type);
    setCondition( ICondition.ALWAYS);
    setProperties( null);
    }

  /**
   * Changes the name of this value.
   */
  public void setName( String name)
    {
    assertIdentifier( name);
    name_ = name;
    }

  /**
   * Returns the name of this value.
   */
  public String getName()
    {
    return name_;
    }

  /**
   * Changes the type of this value.
   */
  public void setType( Type type)
    {
    type_ = type;
    }

  /**
   * Returns the type of this value.
   */
  public Type getType()
    {
    return type_;
    }

  /**
   * Returns if this value is a valid member of the variable input domain.
   */
  public boolean isValid()
    {
    return getType().isValid();
    }

  /**
   * Changes the set of test case properties contributed by this value.
   */
  public void setProperties( Set<String> properties)
    {
    assertPropertyIdentifiers( properties);
    properties_ = new HashSet<String>();
    addProperties( properties);
    }

  /**
   * Adds to the set of test case properties contributed by this value.
   */
  public void addProperties( Set<String> properties)
    {
    if( properties != null)
      {
      getProperties().addAll( properties);
      }
    }

  /**
   * Returns the set of test case properties contributed by this value.
   */
  public Set<String> getProperties()
    {
    return properties_;
    }

  public boolean equals( Object object)
    {
    VarValueDef other =
      object != null && object.getClass().equals( getClass())
      ? (VarValueDef) object
      : null;

    return
      other != null
      && ObjectUtils.equals( other.getName(), getName())
      && ObjectUtils.equals( other.getType(), getType());
    }

  public int hashCode()
    {
    return
      getClass().hashCode()
      ^ (getName()==null? 0 : getName().hashCode())
      ^ (getType()==null? 0 : getType().hashCode());
    }
  
  public String toString()
    {
    return
      ToString.getBuilder( this)
      .append( getName())
      .toString();
    }

  private String name_;
  private Type type_;
  private Set<String> properties_;
  }


@@ -459,24 +459,78 @@
 jectUtils;%0A%0A
+import java.util.Arrays;%0Aimport java.util.Collection;%0A
 import java.
@@ -2338,35 +2338,42 @@
  setProperties( 
-Set
+Collection
 %3CString%3E propert
@@ -2387,52 +2387,8 @@
   %7B%0A
-    assertPropertyIdentifiers( properties);%0A
     
@@ -2556,20 +2556,27 @@
  public 
-void
+VarValueDef
  addProp
@@ -2583,19 +2583,26 @@
 erties( 
-Set
+Collection
 %3CString%3E
@@ -2666,52 +2666,327 @@
     
-getProperties().addAll( properties);%0A      %7D
+assertPropertyIdentifiers( properties);%0A      getProperties().addAll( properties);%0A      %7D%0A%0A    return this;%0A    %7D%0A%0A  /**%0A   * Adds to the set of test case properties contributed by this value.%0A   */%0A  public VarValueDef addProperties( String ... properties)%0A    %7B%0A    return addProperties( Arrays.asList( properties));
 %0A   

Rework for better testability