package editor.database.attributes;

import java.util.Objects;

import editor.database.card.Card;

/**
 * This class represents the starting loyalty of a planeswalker.  All {@link Card}s have them, but they
 * are invisible for non-planeswalkers.
 *
 * @author Alec Roelke
 */
public class Loyalty implements OptionalAttribute, Comparable<Loyalty>
{
    /**
     * Constant for an arbitrary card with no loyalty.
     */
    public static final Loyalty NO_LOYALTY = new Loyalty(0);

    /**
     * Numerical value of the starting loyalty.  Zero means there is no loyalty and
     * -1 means it's X.
     */
    public final int value;

    /**
     * Create a new Loyalty with the given value.
     *
     * @param v value of the new Loyalty
     */
    public Loyalty(int v)
    {
        value = Math.max(-1, v);
    }

    /**
     * Parse a String for a loyalty value.  It can either be a number or "X," and if
     * anything else is used it is considered to not exist.
     *
     * @param s
     */
    public Loyalty(String s)
    {
        int v;
        try
        {
            v = Integer.valueOf(s);
        }
        catch (NumberFormatException x)
        {
            v = s.compareToIgnoreCase("X") == 0 ? -1 : 0;
        }
        value = v;
    }

    @Override
    public int compareTo(Loyalty other)
    {
        return Integer.compare(value, other.value);
    }

    @Override
    public boolean equals(Object other)
    {
        return other != null && (other == this || other instanceof Loyalty && value == ((Loyalty)other).value);
    }

    @Override
    public boolean exists()
    {
        return value != 0;
    }

    @Override
    public int hashCode()
    {
        return Objects.hash(value);
    }

    @Override
    public String toString()
    {
        if (value < 0)
            return "X";
        else if (value == 0)
            return "";
        else return Integer.toString(value);
    }

    /**
     * @return <code>true</code> if this Loyalty is variable (X),
     * and <code>false</code> otherwise.
     */
    public boolean variable()
    {
        return value < 0;
    }
}

@@ -476,16 +476,94 @@
 ty(0);%0A%0A
+    private static final int X = -1;%0A    private static final int STAR = -2;%0A%0A
     /**%0A
@@ -764,16 +764,52 @@
 n value.
+ Loyalty creatd this way can't vary.
 %0A     *%0A
@@ -914,18 +914,17 @@
 ath.max(
--1
+0
 , v);%0A  
@@ -1009,30 +1009,36 @@
 mber
- or
+,
  %22X,%22 
-and if%0A     *
+or %22*,%22%0A     * and if
  any
@@ -1307,47 +1307,143 @@
  = s
-.compareToIgnoreCase(%22X%22) == 0 ? -1 : 0
+witch (s.toUpperCase()) %7B%0A                case %22X%22 -%3E X;%0A                case %22*%22 -%3E STAR;%0A                default  -%3E 0;%0A            %7D
 ;%0A  
@@ -2006,22 +2006,31 @@
     
-if
+return switch
  (value
- %3C 0)
+) %7B
 %0A   
@@ -2038,22 +2038,28 @@
         
-return
+case X    -%3E
  %22X%22;%0A  
@@ -2068,28 +2068,29 @@
     
-else if (value == 0)
+    case STAR -%3E %22*%22;
 %0A   
@@ -2098,22 +2098,28 @@
         
-return
+case 0    -%3E
  %22%22;%0A   
@@ -2127,19 +2127,24 @@
     
-else return
+    default   -%3E
  Int
@@ -2157,32 +2157,43 @@
 oString(value);%0A
+        %7D;%0A
     %7D%0A%0A    /**%0A 

Fix Loyalty to include B.O.B.'s "*" loyalty