/*******************************************************************************
 * Copyright (c) 2015-2016 Oak Ridge National Laboratory.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package org.csstudio.display.builder.model.macros;

import static org.csstudio.display.builder.model.ModelPlugin.logger;

import java.util.Collection;
import java.util.Map;
import java.util.logging.Level;

import org.csstudio.display.builder.model.WidgetProperty;

/** Provides values from macros, falling back to widget properties
 *  @author Kay Kasemir
 */
@SuppressWarnings("nls")
public class MacroOrPropertyProvider implements MacroValueProvider
{
    private final MacroValueProvider macros;
    private final Map<String, WidgetProperty<?>> properties;

    /** Initialize
     *  @param macros      Macros to use
     *  @param properties  Properties on which to fall back
     */
    public MacroOrPropertyProvider(final MacroValueProvider macros,
                                   final Map<String, WidgetProperty<?>> properties)
    {
        this.macros = macros;
        this.properties = properties;
    }

    @Override
    public String getValue(final String name)
    {
        // Automatic macro for Display ID,
        // uniquely identifies the display
        if ("DID".equals(name))
        {
            int id;
            try
            {
                id = System.identityHashCode(properties.get("name").getWidget().getDisplayModel());
            }
            catch (Exception ex)
            {
                logger.log(Level.WARNING, "Cannot obtain display ID for $(DID)", ex);
                return "DP00";
            }
            return "DP" + Integer.toHexString(id);
        }

        // Automatic macro for Display NAME
        if ("DNAME".equals(name))
        {
            try
            {
                return properties.get("name").getWidget().getDisplayModel().widgetName().getValue();
            }
            catch (Exception ex)
            {
                logger.log(Level.WARNING, "Cannot obtain display name", ex);
                return "Unknown";
            }
        }

        String value = macros.getValue(name);
        if (value != null)
            return value;

        final WidgetProperty<?> property = properties.get(name);
        if (property != null)
        {   // If value is a single-element collection, get string for that one element.
            // This is primarily for buttons that use $(actions) as their text,
            // and there's a single action which should show as "That Action"
            // and not "[That Action]".
            final Object prop_val = property.getValue();
            if (prop_val instanceof Collection<?>)
            {
                final Collection<?> coll = (Collection<?>) prop_val;
                if (coll.size() == 1)
                    return coll.iterator().next().toString();
            }
            return prop_val.toString();
        }
        return null;
    }
}

@@ -580,16 +580,111 @@
 .logger;
+%0Aimport static org.csstudio.display.builder.model.properties.CommonWidgetProperties.widgetType;
 %0A%0Aimport
@@ -1663,32 +1663,157 @@
 ame))%0A        %7B%0A
+            // Every widget must have a 'type' property,%0A            // so fetch that to get the widget and then the display%0A
             int 
@@ -1898,38 +1898,52 @@
 (properties.get(
-%22name%22
+widgetType.getName()
 ).getWidget().ge
@@ -2374,14 +2374,28 @@
 get(
-%22name%22
+widgetType.getName()
 ).ge

Clarify how automatic macros obtain the display model