AnimationToggles.java

package org.opentrafficsim.swing.gui;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.opentrafficsim.animation.gtu.DefaultCarAnimation;
import org.opentrafficsim.animation.gtu.PerceptionAnimation;
import org.opentrafficsim.animation.gtu.DefaultCarAnimation.GtuData;
import org.opentrafficsim.animation.network.LinkAnimation;
import org.opentrafficsim.animation.network.LinkAnimation.LinkData;
import org.opentrafficsim.animation.network.NodeAnimation;
import org.opentrafficsim.animation.network.NodeAnimation.NodeData;
import org.opentrafficsim.animation.road.BusStopAnimation;
import org.opentrafficsim.animation.road.BusStopAnimation.BusStopData;
import org.opentrafficsim.animation.road.ConflictAnimation.ConflictData;
import org.opentrafficsim.animation.road.CrossSectionElementAnimation.ShoulderData;
import org.opentrafficsim.animation.road.DetectorData;
import org.opentrafficsim.animation.road.GtuGeneratorPositionAnimation;
import org.opentrafficsim.animation.road.GtuGeneratorPositionAnimation.GtuGeneratorPositionData;
import org.opentrafficsim.animation.road.LaneAnimation;
import org.opentrafficsim.animation.road.LaneAnimation.CenterLine;
import org.opentrafficsim.animation.road.LaneAnimation.LaneData;
import org.opentrafficsim.animation.road.PriorityAnimation.PriorityData;
import org.opentrafficsim.animation.road.StripeAnimation.StripeData;
import org.opentrafficsim.animation.road.TrafficLightAnimation;
import org.opentrafficsim.animation.road.TrafficLightAnimation.TrafficLightData;

import nl.tudelft.simulation.dsol.animation.Locatable;

/**
 * Set the default animation toggles for the simulation panel.
 * <p>
 * Copyright (c) 2013-2026 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
 * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
 * </p>
 * @author Alexander Verbraeck
 * @author Peter Knoppers
 * @author Wouter Schakel
 */
public final class AnimationToggles
{

    /** Toggles. */
    private static final Map<String, List<Toggle>> TOGGLES = new LinkedHashMap<>();

    /** Default visible. */
    private static final Map<String, Boolean> DEFAULT_VISIBLE = new LinkedHashMap<>();

    static
    {
        List<Toggle> list = new ArrayList<>();
        list.add(new Toggle("Node", NodeData.class, "Node24.png", "Show/hide nodes", true, false, false));
        list.add(new Toggle("NodeId", NodeAnimation.Text.class, "Id24.png", "Show/hide node ids", false, false, true));
        list.add(new Toggle("Link", LinkData.class, "Link24.png", "Show/hide links", true, false, false));
        list.add(new Toggle("LinkId", LinkAnimation.Text.class, "Id24.png", "Show/hide link ids", false, false, true));
        list.add(new Toggle("Priority", PriorityData.class, "Priority24.png", "Show/hide link priority", true, false, false));
        DEFAULT_VISIBLE.put("network", true);
        TOGGLES.put("network", list);

        list = new ArrayList<>();
        list.add(new Toggle("Lane", LaneData.class, "Lane24.png", "Show/hide lanes", true, true, false));
        list.add(new Toggle("LaneId", LaneAnimation.Text.class, "Id24.png", "Show/hide lane ids", false, false, true));
        list.add(new Toggle("Stripe", StripeData.class, "Stripe24.png", "Show/hide stripes", true, true, false));
        list.add(new Toggle("LaneCenter", CenterLine.class, "CenterLine24.png", "Show/hide lane center lines", false, false,
                true));
        list.add(new Toggle("Shoulder", ShoulderData.class, "Shoulder24.png", "Show/hide shoulders", true, true, false));
        DEFAULT_VISIBLE.put("lane", false);
        TOGGLES.put("lane", list);

        list = new ArrayList<>();
        list.add(new Toggle("GTU", GtuData.class, "Gtu24.png", "Show/hide GTUs", true, true, false));
        list.add(new Toggle("GTUId", DefaultCarAnimation.Text.class, "Id24.png", "Show/hide GTU ids", false, false, true));
        list.add(new Toggle("Perception", PerceptionAnimation.PerceptionData.class, "Perception24.png",
                "Show/hide perception (circle = attention, color = perception delay)", false, false, false));
        DEFAULT_VISIBLE.put("GTU", false);
        TOGGLES.put("GTU", list);

        list = new ArrayList<>();
        list.add(new Toggle("Detector", DetectorData.class, "Detector24.png", "Show/hide detectors", true, false, false));
        list.add(new Toggle("DetectorId", DetectorData.Text.class, "Id24.png", "Show/hide detector ids", false, false, true));
        list.add(new Toggle("Light", TrafficLightData.class, "TrafficLight24.png", "Show/hide traffic lights", true, true,
                false));
        list.add(new Toggle("LightId", TrafficLightAnimation.Text.class, "Id24.png", "Show/hide traffic light ids", false,
                false, true));
        list.add(new Toggle("Conflict", ConflictData.class, "Conflict24.png", "Show/hide conflicts", true, false, false));
        list.add(new Toggle("Generator", GtuGeneratorPositionData.class, "Generator24.png", "Show/hide generators", true, false,
                false));
        list.add(new Toggle("GeneratorQ", GtuGeneratorPositionAnimation.Queue.class, "Queue24.png",
                "Show/hide generator queues", false, false, true));
        list.add(new Toggle("Bus", BusStopData.class, "BusStop24.png", "Show/hide bus stops", true, false, false));
        list.add(new Toggle("BusId", BusStopAnimation.Text.class, "Id24.png", "Show/hide bus stop ids", false, false, true));
        DEFAULT_VISIBLE.put("objects", true);
        TOGGLES.put("objects", list);
    }

    /**
     * Do not instantiate this class.
     */
    private AnimationToggles()
    {
        // static class.
    }

    /**
     * Set all animation on, and create the toggles on the left hand side.
     * @param panel simulation panel
     */
    public static void setTextAnimationTogglesFull(final OtsSimulationPanel panel)
    {
        TOGGLES.entrySet().forEach((e) ->
        {
            panel.startToggleSection(e.getKey(), DEFAULT_VISIBLE.getOrDefault(e.getKey(), true));
            e.getValue().forEach(
                    (t) -> panel.addToggleAnimationButtonText(t.name(), t.locatableClass(), t.tooltip(), t.visibleFull()));
        });
    }

    /**
     * Set the most common animation on, and create the toggles on the left hand side.
     * @param panel the simulation panel
     */
    public static void setTextAnimationTogglesStandard(final OtsSimulationPanel panel)
    {
        TOGGLES.entrySet().forEach((e) ->
        {
            panel.startToggleSection(e.getKey(), DEFAULT_VISIBLE.getOrDefault(e.getKey(), true));
            e.getValue().forEach(
                    (t) -> panel.addToggleAnimationButtonText(t.name(), t.locatableClass(), t.tooltip(), t.visibleStandard()));
        });
    }

    /**
     * Set all animation on, and create the toggles on the left hand side.
     * @param panel the simulation panel
     */
    public static void setIconAnimationTogglesFull(final OtsSimulationPanel panel)
    {
        TOGGLES.entrySet().forEach((e) ->
        {
            panel.startToggleSection(e.getKey(), DEFAULT_VISIBLE.getOrDefault(e.getKey(), true));
            e.getValue().forEach((t) -> panel.addToggleAnimationButtonIcon(t.name(), t.locatableClass(), t.icon(), t.tooltip(),
                    t.visibleFull(), t.nextToPrevious()));
        });
    }

    /**
     * Set the most common animation on, and create the toggles on the left hand side.
     * @param panel the simulation panel
     */
    public static void setIconAnimationTogglesStandard(final OtsSimulationPanel panel)
    {
        TOGGLES.entrySet().forEach((e) ->
        {
            panel.startToggleSection(e.getKey(), DEFAULT_VISIBLE.getOrDefault(e.getKey(), true));
            e.getValue().forEach((t) -> panel.addToggleAnimationButtonIcon(t.name(), t.locatableClass(), t.icon(), t.tooltip(),
                    t.visibleStandard(), t.nextToPrevious()));
        });
    }

    /**
     * Set a class to be shown in the animation to true.
     * @param panel the simulation panel
     * @param locatableClass the class for which the animation has to be shown
     */
    public static void showAnimationClass(final OtsSimulationPanel panel, final Class<? extends Locatable> locatableClass)
    {
        panel.getAnimationPanel().showClass(locatableClass);
        panel.updateAnimationClassCheckBox(locatableClass);
    }

    /**
     * Set a class to be shown in the animation to false.
     * @param panel the simulation panel
     * @param locatableClass the class for which the animation has to be hidden
     */
    public static void hideAnimationClass(final OtsSimulationPanel panel, final Class<? extends Locatable> locatableClass)
    {
        panel.getAnimationPanel().hideClass(locatableClass);
        panel.updateAnimationClassCheckBox(locatableClass);
    }

    /**
     * Set all animation on, and create the toggles on the left hand side.
     * @param panel the simulation panel
     */
    public static void showAnimationFull(final OtsSimulationPanel panel)
    {
        TOGGLES.values().forEach((v) -> v.forEach((t) ->
        {
            if (t.visibleFull())
            {
                showAnimationClass(panel, t.locatableClass());
            }
            else
            {
                hideAnimationClass(panel, t.locatableClass());
            }
        }));
    }

    /**
     * Set the most common animation on, and create the toggles on the left hand side.
     * @param panel the simulation panel
     */
    public static void showAnimationStandard(final OtsSimulationPanel panel)
    {
        TOGGLES.values().forEach((v) -> v.forEach((t) ->
        {
            if (t.visibleStandard())
            {
                showAnimationClass(panel, t.locatableClass());
            }
            else
            {
                hideAnimationClass(panel, t.locatableClass());
            }
        }));
    }

    /**
     * Record to hold data pertaining to a toggle.
     * @param name name of the toggle
     * @param locatableClass type of the locatable that is toggled
     * @param icon name of the icon
     * @param tooltip tooltip on the toggle
     * @param visibleFull visible under full toggles
     * @param visibleStandard visible under standard toggles
     * @param nextToPrevious whether to place the icon toggle next to the previous
     */
    private record Toggle(String name, Class<? extends Locatable> locatableClass, String icon, String tooltip,
            boolean visibleFull, boolean visibleStandard, boolean nextToPrevious)
    {
    };
}