/*******************************************************************************
 * 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.runtime.script;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import org.csstudio.display.builder.model.properties.FormatOption;
import org.csstudio.display.builder.model.util.FormatOptionHandler;
import org.csstudio.display.builder.model.util.VTypeUtil;
import org.csstudio.display.builder.runtime.pv.RuntimePV;
import org.diirt.vtype.VEnum;
import org.diirt.vtype.VTable;
import org.diirt.vtype.VType;

/** Utility for handling PVs and their values in scripts
 *
 *  @author Kay Kasemir
 *  @author Xihui Chen - Original org.csstudio.opibuilder.scriptUtil.*
 */
@SuppressWarnings("nls")
public class PVUtil
{
    private static VType getVType(final RuntimePV pv)
    {
        return Objects.requireNonNull(pv.read(), () -> "PV " + pv.getName() + " has no value");
    }

    /** Try to get a 'double' type number from the PV.
     *  @param pv PV
     *  @return Current value.
     *          <code>Double.NaN</code> in case the value type
     *          does not decode into a number.
     */
    public static double getDouble(final RuntimePV pv)
    {
        return VTypeUtil.getValueNumber(getVType(pv)).longValue();
    }

    /** Try to get an integer from the PV.
     *  @param pv PV
     *  @return Current value as int
     */
    public static int getInt(final RuntimePV pv)
    {
        return VTypeUtil.getValueNumber(getVType(pv)).intValue();
    }

    /** Try to get a long integer from the PV.
     *  @param pv PV
     *  @return Current value as long
     */
    public static long getLong(final RuntimePV pv)
    {
        return VTypeUtil.getValueNumber(getVType(pv)).longValue();
    }

    /** Get value of PV as string.
     *  @param pv PV
     *  @return Current value as string
     */
    public static String getString(final RuntimePV pv)
    {
        return FormatOptionHandler.format(getVType(pv), FormatOption.DEFAULT, 0, true);
    }

    /** Get labels for an enum value
     *  @param pv the PV.
     *  @return Enum labels or empty array if not enum
     */
    public static String[] getLabels(final RuntimePV pv)
    {
        final VType value = getVType(pv);
        if (! (value instanceof VEnum))
            return new String[0];
        final List<String> labels = ((VEnum) value).getLabels();
        return labels.toArray(new String[labels.size()]);
    }

    /** Create a VTable for Strings
     *  @param headers Table headers
     *  @param columns List of columns, i.e. columns.get(N) is the Nth column
     *  @return VTable
     */
    public static VTable createStringTableFromColumns(final List<String> headers, final List<List<String>> columns)
    {
        return new StringVTable(headers, columns);
    }

    /** Create a VTable for Strings
     *  @param headers Table headers
     *  @param rows List of rows, i.e. rows.get(N) is the Nth row
     *  @return VTable
     */
    public static VTable createStringTableFromRows(final List<String> headers, final List<List<String>> rows)
    {
        final List<List<String>> columns = new ArrayList<>();
        for (int col=0; col<headers.size(); ++col)
        {
            final ArrayList<String> column = new ArrayList<>();
            columns.add(column);
            for (int row=0; row<rows.size(); ++row)
                column.add(rows.get(row).get(col));
        }
        return new StringVTable(headers, columns);
    }
}

@@ -843,16 +843,51 @@
 timePV;%0A
+import org.diirt.vtype.VByteArray;%0A
 import o
@@ -2365,69 +2365,695 @@
 urn 
-FormatOptionHandler.format(getVType(pv), FormatOption.DEFAULT
+getString(pv, false);%0A    %7D%0A%0A    /** Get value of PV as string.%0A     *%0A     *  %3Cp%3EOptionally, byte arrays can be requested as a (long) string,%0A     *  instead of %22%5B 1, 2, 3, .. %5D%22%0A     *  @param pv PV%0A     *  @param byte_array_as_string Decode byte arrays as string?%0A     *  @return Current value as string%0A     */%0A    public static String getString(final RuntimePV pv, final boolean byte_array_as_string)%0A    %7B%0A        final VType vtype = getVType(pv);%0A        final FormatOption option = vtype instanceof VByteArray%0A                                  ? FormatOption.STRING%0A                                  : FormatOption.DEFAULT;%0A        return FormatOptionHandler.format(vtype, option
 , 0,

Allow reading long string from byte array