package editor.gui.filter.editor;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JLabel;

import editor.database.attributes.CardAttribute;
import editor.database.attributes.ManaType;
import editor.database.symbol.ColorSymbol;
import editor.database.symbol.StaticSymbol;
import editor.filter.Filter;
import editor.filter.leaf.ColorFilter;
import editor.filter.leaf.FilterLeaf;
import editor.gui.generic.ComboBoxPanel;
import editor.gui.generic.ComponentUtils;
import editor.util.Containment;

/**
 * This class represents a panel corresponding to a filter that groups
 * cards by a color characteristic.
 *
 * @author Alec Roelke
 */
@SuppressWarnings("serial")
public class ColorFilterPanel extends FilterEditorPanel<ColorFilter>
{
    /**
     * Map of colors onto their corresponding check boxes.
     */
    private Map<ManaType, JCheckBox> colors;
    /**
     * Combo box showing the containment options.
     */
    private ComboBoxPanel<Containment> contain;
    /**
     * Check box indicating that only multicolored cards should be matched.
     */
    private JCheckBox multiCheckBox;
    /**
     * Type of the filter being edited.
     */
    private CardAttribute type;

    /**
     * Create a new ColorFilterPanel.
     */
    public ColorFilterPanel()
    {
        super();
        setLayout(new BoxLayout(this, BoxLayout.X_AXIS));

        // Containment options
        contain = new ComboBoxPanel<>(Containment.values());
        add(contain);

        // Check boxes for selecting colors
        colors = new HashMap<>();
        for (ManaType color : ManaType.colors())
        {
            JCheckBox box = new JCheckBox();
            colors.put(color, box);
            add(box);
            add(new JLabel(ColorSymbol.SYMBOLS.get(color).getIcon(13)));
        }
        add(Box.createHorizontalStrut(4));
        add(ComponentUtils.createHorizontalSeparator(4, contain.getPreferredSize().height));

        // Check box for multicolored cards
        multiCheckBox = new JCheckBox();
        add(multiCheckBox);
        add(new JLabel(StaticSymbol.SYMBOLS.get("M").getIcon(13)));

        add(Box.createHorizontalStrut(2));
    }

    /**
     * Create a new ColorFilterPanel with initial contents obtained
     * from the given filter.
     *
     * @param f filter to get the contents from
     */
    public ColorFilterPanel(ColorFilter f)
    {
        this();
        setContents(f);
    }

    @Override
    public Filter filter()
    {
        ColorFilter filter = (ColorFilter)CardAttribute.createFilter(type);
        filter.contain = contain.getSelectedItem();
        filter.colors.addAll(colors.keySet().stream().filter((c) -> colors.get(c).isSelected()).collect(Collectors.toSet()));
        filter.multicolored = multiCheckBox.isSelected();
        return filter;
    }

    @Override
    public void setContents(ColorFilter filter)
    {
        type = filter.type();
        contain.setSelectedItem(filter.contain);
        for (ManaType color : ManaType.colors())
            colors.get(color).setSelected(filter.colors.contains(color));
        multiCheckBox.setSelected(filter.multicolored);
    }

    @Override
    public void setContents(FilterLeaf<?> filter) throws IllegalArgumentException
    {
        if (filter instanceof ColorFilter)
            setContents((ColorFilter)filter);
        else
            throw new IllegalArgumentException("Illegal color filter " + filter.type());
    }
}

@@ -1230,16 +1230,52 @@
 eckBox;%0A
+    private JCheckBox colorlessBox;%0A
     /**%0A
@@ -1556,24 +1556,28 @@
 ons%0A        
+add(
 contain = ne
@@ -1615,17 +1615,19 @@
 alues())
-;
+);%0A
 %0A       
@@ -1627,27 +1627,94 @@
         
-add(contain
+// Check box for filtering for colorless%0A        colorlessBox = new JCheckBox(
 );%0A%0A    
@@ -2018,24 +2018,174 @@
 Icon(13)));%0A
+            box.addActionListener((e) -%3E %7B%0A                if (box.isSelected())%0A                    colorlessBox.setSelected(false);%0A            %7D);%0A
         %7D%0A  
@@ -2363,32 +2363,36 @@
 d cards%0A        
+add(
 multiCheckBox = 
@@ -2398,32 +2398,33 @@
  new JCheckBox()
+)
 ;%0A        add(mu
@@ -2425,35 +2425,345 @@
 add(
-multiCheckBox);%0A        add
+new JLabel(StaticSymbol.SYMBOLS.get(%22M%22).getIcon(13)));%0A        multiCheckBox.addActionListener((e) -%3E %7B%0A            if (multiCheckBox.isSelected())%0A                colorlessBox.setSelected(false);%0A        %7D);%0A%0A        // Actually add the colorless box here%0A        colorlessBox.setSelected(true);%0A        add(colorlessBox);%0A        add 
 (new
@@ -2762,38 +2762,37 @@
 add (new JLabel(
-Static
+Color
 Symbol.SYMBOLS.g
@@ -2794,33 +2794,327 @@
 OLS.get(
-%22M%22).getIcon(13))
+ManaType.COLORLESS).getIcon(13)));%0A        colorlessBox.addActionListener((e) -%3E %7B%0A            if (colorlessBox.isSelected())%0A            %7B%0A                for (JCheckBox box : colors.values())%0A                    box.setSelected(false);%0A                multiCheckBox.setSelected(false);%0A            %7D%0A        %7D
 );%0A%0A    
@@ -4139,16 +4139,99 @@
 lored);%0A
+        colorlessBox.setSelected(!filter.multicolored && filter.colors.isEmpty());%0A
     %7D%0A%0A 

Add a colorless button to color filters