package org.mapfish.print.processor.map;

import org.mapfish.print.attribute.map.MapAttribute.MapAttributeValues;
import org.mapfish.print.attribute.map.StaticLayersAttribute;
import org.mapfish.print.config.Configuration;
import org.mapfish.print.config.ConfigurationException;
import org.mapfish.print.processor.AbstractProcessor;
import org.mapfish.print.wrapper.PArray;
import org.mapfish.print.wrapper.PJoinedArray;

import java.util.Arrays;
import java.util.List;
import javax.annotation.Nullable;

/**
 * <p>This processor adds the configured set of layers to the map.</p>
 *
 * <p>This is useful when all maps should have a default set of background layers or overlays
 * added to those that the client sends for printing.</p>
 *
 * <p>This can simplify the client so the client only needs to be concerned with the data layers.</p>
 * <p>See also: <a href="attributes.html#!staticLayers">!staticLayers</a> attribute</p>
 * [[examples=add_overlay_layer,report]]
 */
public final class AddStaticLayersProcessor extends AbstractProcessor<AddStaticLayersProcessor.Input,
        AddStaticLayersProcessor.Output> {

    private StaticLayerPosition position;

    /**
     * Constructor.
     */
    protected AddStaticLayersProcessor() {
        super(AddStaticLayersProcessor.Output.class);
    }

    /**
     * Set the position enumeration which indicates where the layers should be added to the map:
     * {@link org.mapfish.print.processor.map.AddStaticLayersProcessor.StaticLayerPosition}.
     *
     * @param position the position.
     */
    public void setPosition(final StaticLayerPosition position) {
        this.position = position;
    }

    @Override
    protected void extraValidation(final List<Throwable> validationErrors, final Configuration configuration) {
        if (this.position == null) {
            validationErrors.add(new ConfigurationException("The addPosition field needs to be set to one of the allowed options: " +
                                                            Arrays.toString(StaticLayerPosition.values())));
        }
    }

    @Nullable
    @Override
    public Input createInputParameter() {
        return new Input();
    }

    @Nullable
    @Override
    public Output execute(final Input values, final ExecutionContext context) throws Exception {
        switch (this.position) {
            case BOTTOM:
                values.map.layers = new PJoinedArray(new PArray[]{values.map.layers, values.staticLayers.layers});
                break;
            case TOP:
                values.map.layers = new PJoinedArray(new PArray[]{values.staticLayers.layers, values.map.layers});
                break;
            default:
                throw new Error("An enumeration value was added that does not have an implementation.  A Programmer must add "
                                + "this implementation to " + getClass().getName());
        }
        values.map.postConstruct();
        return new Output(values.map);
    }

    /**
     * The object containing the values required for this processor.
     */
    public static class Input {

        /**
         * The map to update with the static layers.
         */
        public MapAttributeValues map;

        /**
         * The attribute containing the static layers to add to the map.
         */
        public StaticLayersAttribute.StaticLayersAttributeValue staticLayers;
    }

    /**
     * The object containing the output for this processor.
     */
    public static class Output {

        /**
         * The map to update with the static layers.
         */
        public MapAttributeValues map;

        Output(final MapAttributeValues map) {
            this.map = map;
        }
    }

    /**
     * Indications where in the layer list to add the static layers.
     */
    public enum StaticLayerPosition {
        /**
         * Add Layers to the top of the map.  Essentially overlays.
         */
        TOP,
        /**
         * Add Layers to the bottom of the map, background layers.
         */
        BOTTOM
    }
}

@@ -35,16 +35,76 @@
 r.map;%0A%0A
+import org.mapfish.print.attribute.map.GenericMapAttribute;%0A
 import o
@@ -2361,24 +2361,96 @@
 Exception %7B%0A
+        final MapAttributeValues map = (MapAttributeValues) values.map;%0A
         swit
@@ -2503,39 +2503,32 @@
                 
-values.
 map.layers = new
@@ -2554,23 +2554,41 @@
 Array%5B%5D%7B
-values.
+%0A                        
 map.laye
@@ -2678,31 +2678,24 @@
             
-values.
 map.layers =
@@ -2725,16 +2725,41 @@
 Array%5B%5D%7B
+%0A                        
 values.s
@@ -2778,23 +2778,16 @@
 layers, 
-values.
 map.laye
@@ -3342,32 +3342,62 @@
 %0A        public 
+GenericMapAttribute%3C?%3E.Generic
 MapAttributeValu
@@ -3789,16 +3789,46 @@
  public 
+GenericMapAttribute%3C?%3E.Generic
 MapAttri
@@ -3861,24 +3861,54 @@
 utput(final 
+GenericMapAttribute%3C?%3E.Generic
 MapAttribute

Fix input output types from AddStaticLayersProcessor