package org.eclipse.scanning.device.ui.device.scannable;

import java.text.DecimalFormat;

import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.scanning.api.INamedNode;
import org.eclipse.scanning.api.IScannable;
import org.eclipse.scanning.api.device.IScannableDeviceService;
import org.eclipse.scanning.api.scan.ui.ControlNode;
import org.eclipse.scanning.device.ui.Activator;
import org.eclipse.scanning.device.ui.DevicePreferenceConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class ControlValueLabelProvider extends ColumnLabelProvider implements IStyledLabelProvider {
	
	private static final Logger logger = LoggerFactory.getLogger(ControlValueLabelProvider.class);
	
	private IScannableDeviceService cservice;
	private ControlViewerMode       mode;
	
	public ControlValueLabelProvider(IScannableDeviceService cservice, ControlViewerMode mode) {
		Activator.getDefault().getPreferenceStore().setDefault(DevicePreferenceConstants.NUMBER_FORMAT, "##########0.0###");
		this.cservice = cservice;
		this.mode     = mode;
	}

	@Override
	public StyledString getStyledText(Object element) {

		if(!(element instanceof INamedNode)) return new StyledString();

		final StyledString ret = new StyledString(getText(element));
		
		INamedNode node = (INamedNode)element;
		try {
			if (node instanceof ControlNode) {
				final IScannable<?> scannable = cservice.getScannable(node.getName());
				ret.append("    ");
				ret.append(scannable.getUnit(), StyledString.DECORATIONS_STYLER);
			} else {
				// Intentionally do nothing!
			}
		} catch (Exception ne) {
			return ret.append(ne.getMessage(), StyledString.QUALIFIER_STYLER);
		}
		
		return ret;
	}

	@Override
	public String getText(Object element) {
		
		if(!(element instanceof INamedNode)) return super.getText(element);
		
		INamedNode node = (INamedNode)element;
		
		if (cservice==null) return "Server Error";
		try {
			if (node instanceof ControlNode) {
				ControlNode cnode = (ControlNode)node;
				
				Object value = null;
				if (!mode.isDirectlyConnected() && cnode.getValue()!=null) {
					value = cnode.getValue();
				} else {
					final IScannable<Number> scannable = cservice.getScannable(cnode.getName());
					value = scannable.getPosition();
				}
				
				if (value == null) return "!VALUE";
				final DecimalFormat format = new DecimalFormat(Activator.getDefault().getPreferenceStore().getString(DevicePreferenceConstants.NUMBER_FORMAT));
				try {
					return format.format(value); 
				} catch (Exception ne) {
					return value.toString();
				}
				
			} else {
				return ""; // Only controls have values...
			}
		} catch (Exception ne) {
			logger.error("Error with value for "+node, ne);
		    return ne.toString();
		}
		
	}

}

@@ -1385,18 +1385,25 @@
 dString 
-re
+styledTex
 t = new 
@@ -1601,34 +1601,83 @@
 etName());%0D%0A%09%09%09%09
-re
+%09if (scannable.getUnit() != null) %7B%0D%0A%09%09%09%09%09styledTex
 t.append(%22    %22)
@@ -1683,18 +1683,26 @@
 );%0D%0A%09%09%09%09
-re
+%09styledTex
 t.append
@@ -1758,16 +1758,23 @@
 YLER);%0D%0A
+%09%09%09%09%7D%0D%0A
 %09%09%09%7D els
@@ -1856,18 +1856,25 @@
 %09return 
-re
+styledTex
 t.append
@@ -1942,18 +1942,25 @@
 %09return 
-re
+styledTex
 t;%0D%0A%09%7D%0D%0A

fix NPE when unit scannable.getUnit() returns null