/*
 * Copyright 2014 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Eclipse Public License version 1.0, available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.jboss.forge.plugin.idea.ui.component.many;

import com.intellij.ui.CheckBoxList;
import com.intellij.ui.CheckBoxListListener;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.util.Function;
import org.jboss.forge.addon.convert.Converter;
import org.jboss.forge.addon.convert.ConverterFactory;
import org.jboss.forge.addon.ui.hints.InputType;
import org.jboss.forge.addon.ui.input.InputComponent;
import org.jboss.forge.addon.ui.input.UISelectMany;
import org.jboss.forge.addon.ui.util.InputComponents;
import org.jboss.forge.furnace.proxy.Proxies;
import org.jboss.forge.plugin.idea.service.ServiceHelper;
import org.jboss.forge.plugin.idea.ui.component.ComponentBuilder;
import org.jboss.forge.plugin.idea.ui.component.ForgeComponent;
import org.jboss.forge.plugin.idea.util.ForgeProxies;
import org.jboss.forge.plugin.idea.util.FunctionConverterAdapter;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Adam Wyłuda
 */
public class CheckBoxTableComponentBuilder extends ComponentBuilder
{
    @Override
    public ForgeComponent build(final InputComponent<?, Object> input)
    {
        return new ForgeComponent()
        {
            @Override
            public void buildUI(Container container)
            {
                final UISelectMany inputMany = ForgeProxies.proxyTo(UISelectMany.class, input);

                final ConverterFactory converterFactory = ServiceHelper.getForgeService().getConverterFactory();
                Converter<?, String> forgeConverter = InputComponents.getItemLabelConverter(converterFactory, inputMany);
                Function<?, String> converter = new FunctionConverterAdapter(forgeConverter);

                List<Object> choices = new ArrayList<>();
                for (Object item : inputMany.getValueChoices())
                {
                    choices.add(Proxies.unwrap(item));
                }

                List<Object> value = new ArrayList<>();
                for (Object item : inputMany.getValue())
                {
                    value.add(Proxies.unwrap(item));
                }

                String label = InputComponents.getLabelFor(input, false);

                final CheckBoxList checkBoxList = new CheckBoxList();
                checkBoxList.setBorder(IdeBorderFactory.createTitledBorder(label, false));
                checkBoxList.setItems(choices, converter);
                setSelectedItems(checkBoxList, value);

                checkBoxList.setCheckBoxListListener(new CheckBoxListListener()
                {
                    @Override
                    public void checkBoxSelectionChanged(int index, boolean value)
                    {
                        InputComponents.setValueFor(converterFactory, inputMany, getSelectedItems(checkBoxList));
                        valueChangeListener.run();
                    }
                });

                container.add(checkBoxList, "span 2,growx,height :350:");
            }

            private List getSelectedItems(CheckBoxList checkBoxList)
            {
                List result = new ArrayList();

                for (int i = 0; i < checkBoxList.getItemsCount(); i++)
                {
                    if (checkBoxList.isItemSelected(i))
                    {
                        result.add(checkBoxList.getItemAt(i));
                    }
                }

                return result;
            }

            private void setSelectedItems(CheckBoxList checkBoxList, List value)
            {
                for (Object item : value)
                {
                    checkBoxList.setItemSelected(item, true);
                }
            }
        };
    }

    @Override
    protected Class<?> getProducedType()
    {
        return Object.class;
    }

    @Override
    protected String getSupportedInputType()
    {
        return InputType.CHECKBOX;
    }

    @Override
    protected Class<?>[] getSupportedInputComponentTypes()
    {
        return new Class<?>[]{UISelectMany.class};
    }
}

@@ -357,43 +357,8 @@
 ry;%0A
-import com.intellij.util.Function;%0A
 impo
@@ -669,54 +669,8 @@
 ts;%0A
-import org.jboss.forge.furnace.proxy.Proxies;%0A
 impo
@@ -911,143 +911,125 @@
 es;%0A
-import org.jboss.forge.plugin.idea.util.FunctionConverterAdapter;%0A%0Aimport java.awt.*;%0Aimport java.util.ArrayList;%0Aimport java.util.List
+%0Aimport java.awt.*;%0Aimport java.util.ArrayList;%0Aimport java.util.HashMap;%0Aimport java.util.List;%0Aimport java.util.Map
 ;%0A%0A/
@@ -1590,17 +1590,22 @@
 nverter%3C
-?
+Object
 , String
@@ -1606,22 +1606,17 @@
 String%3E 
-forgeC
+c
 onverter
@@ -1686,16 +1686,17 @@
 tMany);%0A
+%0A
         
@@ -1707,114 +1707,27 @@
     
-Function%3C?, String%3E converter = new FunctionConverterAdapter(forgeConverter);%0A%0A                List%3CObject
+Map%3CString, Boolean
 %3E ch
@@ -1734,33 +1734,31 @@
 oices = new 
-ArrayList
+HashMap
 %3C%3E();%0A      
@@ -1865,109 +1865,63 @@
 ces.
-add(Proxies.unwrap(item));%0A                %7D%0A%0A                List%3CObject%3E value = new ArrayList%3C%3E();
+put(converter.convert(item), false);%0A                %7D%0A
 %0A   
@@ -2016,38 +2016,49 @@
     
-value.add(Proxies.unwrap(item)
+choices.put(converter.convert(item), true
 );%0A 
@@ -2339,24 +2339,30 @@
 kBoxList.set
+String
 Items(choice
@@ -2366,74 +2366,8 @@
 ices
-, converter);%0A                setSelectedItems(checkBoxList, value
 );%0A%0A
@@ -3346,258 +3346,8 @@
    %7D
-%0A%0A            private void setSelectedItems(CheckBoxList checkBoxList, List value)%0A            %7B%0A                for (Object item : value)%0A                %7B%0A                    checkBoxList.setItemSelected(item, true);%0A                %7D%0A            %7D
 %0A   

Use String converters in CheckBoxTableComponentBuilder