package editor.filter.leaf;

import java.io.IOException;
import java.io.ObjectOutput;
import java.util.Objects;

import com.google.gson.JsonObject;

import editor.database.card.Card;
import editor.database.characteristics.ManaCost;
import editor.filter.Filter;
import editor.filter.FilterAttribute;
import editor.util.Containment;

/**
 * This class represents a filter to group cards by mana costs.
 *
 * @author Alec Roelke
 */
public class ManaCostFilter extends FilterLeaf<ManaCost>
{
    /**
     * Containment for this ManaCostFilter.
     */
    public Containment contain;
    /**
     * Mana cost to filter by.
     */
    public ManaCost cost;

    /**
     * Create a new ManaCostFilter.
     */
    public ManaCostFilter()
    {
        super(FilterAttribute.MANA_COST, null);
        contain = Containment.CONTAINS_ANY_OF;
        cost = new ManaCost();
    }

    @Override
    public Filter copy()
    {
        ManaCostFilter filter = (ManaCostFilter)FilterAttribute.createFilter(FilterAttribute.MANA_COST);
        filter.contain = contain;
        filter.cost = cost;
        return filter;
    }

    @Override
    public boolean equals(Object other)
    {
        if (other == null)
            return false;
        if (other == this)
            return true;
        if (other.getClass() != getClass())
            return false;
        ManaCostFilter o = (ManaCostFilter)other;
        return o.contain == contain && o.cost.equals(cost);
    }

    @Override
    public int hashCode()
    {
        return Objects.hash(type(), contain, cost);
    }

    /**
     * {@inheritDoc}
     * Filter cards by their mana costs.
     */
    @Override
    public boolean test(Card c)
    {
        switch (contain)
        {
        case CONTAINS_ANY_OF:
            return c.manaCost().stream().anyMatch((m) -> Containment.CONTAINS_ANY_OF.test(m, cost));
        case CONTAINS_NONE_OF:
            return c.manaCost().stream().anyMatch((m) -> Containment.CONTAINS_NONE_OF.test(m, cost));
        case CONTAINS_ALL_OF:
            return c.manaCost().stream().anyMatch((m) -> m.isSuperset(cost));
        case CONTAINS_NOT_ALL_OF:
            return c.manaCost().stream().anyMatch((m) -> !m.isSuperset(cost));
        case CONTAINS_EXACTLY:
            return c.manaCost().stream().anyMatch((m) -> m.equals(cost));
        case CONTAINS_NOT_EXACTLY:
            return c.manaCost().stream().anyMatch((m) -> !m.equals(cost));
        default:
            return false;
        }
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException
    {
        out.writeObject(contain);
        out.writeUTF(cost.toString());
    }

    @Override
    protected void serializeFields(JsonObject fields)
    {
        fields.addProperty("contains", contain.toString());
        fields.addProperty("cost", cost.toString());
    }

    @Override
    protected void deserializeFields(JsonObject fields)
    {
        contain = Containment.parseContainment(fields.get("contains").getAsString());
        cost = ManaCost.parseManaCost(fields.get("cost").getAsString());
    }
}

@@ -1703,16 +1703,61 @@
 %0A       
+ return c.manaCost().stream().anyMatch((m) -%3E
  switch 
@@ -1769,19 +1769,15 @@
 ain)
-%0A    
+ %7B%0A
     
-%7B%0A
     
@@ -1804,63 +1804,8 @@
 Y_OF
-:%0A            return c.manaCost().stream().anyMatch((m)
  -%3E 
@@ -1837,35 +1837,38 @@
 OF.test(m, cost)
-)
 ;%0A
+    
         case CON
@@ -1884,63 +1884,8 @@
 E_OF
-:%0A            return c.manaCost().stream().anyMatch((m)
  -%3E 
@@ -1922,25 +1922,24 @@
 est(m, cost)
-)
 ;%0A        ca
@@ -1928,32 +1928,36 @@
  cost);%0A        
+  
+  
 case CONTAINS_AL
@@ -1964,63 +1964,8 @@
 L_OF
-:%0A            return c.manaCost().stream().anyMatch((m)
  -%3E 
@@ -1974,35 +1974,38 @@
 isSuperset(cost)
-)
 ;%0A
+    
         case CON
@@ -2024,63 +2024,8 @@
 L_OF
-:%0A            return c.manaCost().stream().anyMatch((m)
  -%3E 
@@ -2039,25 +2039,24 @@
 perset(cost)
-)
 ;%0A        ca
@@ -2045,32 +2045,36 @@
 (cost);%0A        
+   
+ 
 case CONTAINS_EX
@@ -2082,63 +2082,8 @@
 CTLY
-:%0A            return c.manaCost().stream().anyMatch((m)
  -%3E 
@@ -2088,35 +2088,38 @@
 %3E m.equals(cost)
-)
 ;%0A
+    
         case CON
@@ -2139,126 +2139,27 @@
 CTLY
-:%0A            return c.manaCost().stream().anyMatch((m) -%3E !m.equals(cost));%0A        default:%0A            return false
+ -%3E !m.equals(cost)
 ;%0A  
@@ -2165,16 +2165,18 @@
        %7D
+);
 %0A    %7D%0A%0A

Use switch expression for containment test