/*******************************************************************************
 * Copyright (c) 2000, 2010 IBM Corporation and others.
 * 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
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     QNX Software Systems - Mikhail Khodjaiants - Registers View (Bug 53640)
 *******************************************************************************/
package org.eclipse.debug.internal.ui;


import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchDelegate;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IDisconnect;
import org.eclipse.debug.core.model.IExpression;
import org.eclipse.debug.core.model.ILineBreakpoint;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IRegister;
import org.eclipse.debug.core.model.IRegisterGroup;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.ITerminate;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.core.model.IWatchExpression;
import org.eclipse.debug.core.model.IWatchpoint;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchShortcutExtension;
import org.eclipse.debug.internal.ui.views.variables.IndexedVariablePartition;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.model.IWorkbenchAdapter;

import com.ibm.icu.text.MessageFormat;

public class DefaultLabelProvider implements ILabelProvider {
	
	/**
	 * Maps image descriptors to images.
	 */
	private Map fImages = new HashMap();

	/**
	 * @see ILabelProvider#getImage(Object)
	 */
	public Image getImage(Object element) {
		String key= getImageKey(element);
		if (key == null && element instanceof ILaunch) {
			return null;
		}
		if (key == null && element instanceof IAdaptable) {
			IWorkbenchAdapter de= (IWorkbenchAdapter) ((IAdaptable) element).getAdapter(IWorkbenchAdapter.class);
			if (de != null) {
				ImageDescriptor descriptor= de.getImageDescriptor(element);
				if( descriptor != null) {
					return getImage(descriptor);					
				}
			}
			return null;
		}
		if(element instanceof LaunchShortcutExtension) {
			return getImage(((LaunchShortcutExtension)element).getImageDescriptor());
		}
		return DebugPluginImages.getImage(key);
	}
	
	/**
	 * Returns an image created from the given image descriptor or <code>null</code>.
	 * Caches and reuses images.
	 * 
	 * @param descriptor image descriptor
	 * @return image or <code>null</code>
	 */
	private Image getImage(ImageDescriptor descriptor) {
		Image image = (Image) fImages.get(descriptor);
		if (image != null) {
			return image;
		}
		image = descriptor.createImage();
		if (image != null) {
			fImages.put(descriptor, image);
		}
		return image;						
	}
	
	/**
	 * Returns the key (<code>String</code>) of the default image
	 * appropriate for the given element or <code>null</code>
	 * if no default image is defined.
	 */
	public String getImageKey(Object element) {
		if (element instanceof IDebugElement) {
			// Group elements into debug elements and non-debug elements
			// to reduce the number of instanceof checks performed
			if (element instanceof IRegister) {
				return IDebugUIConstants.IMG_OBJS_REGISTER;
			} else if (element instanceof IRegisterGroup) {
				return IDebugUIConstants.IMG_OBJS_REGISTER_GROUP;
			} else if (element instanceof IVariable || element instanceof IValue) {
				if (element instanceof IndexedVariablePartition) {
					return IInternalDebugUIConstants.IMG_OBJS_ARRAY_PARTITION;
				} 
				return IDebugUIConstants.IMG_OBJS_VARIABLE;
			} else if (element instanceof IStackFrame) {
				if (((IStackFrame)element).getThread().isSuspended()) {
					return IDebugUIConstants.IMG_OBJS_STACKFRAME;
				}
				return IDebugUIConstants.IMG_OBJS_STACKFRAME_RUNNING;
			} else if (element instanceof IThread) {
				IThread thread = (IThread)element;
				if (thread.isSuspended()) {
					return IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED;
				} else if (thread.isTerminated()) {
					return IDebugUIConstants.IMG_OBJS_THREAD_TERMINATED;
				} else {
					return IDebugUIConstants.IMG_OBJS_THREAD_RUNNING;
				}
			} else if (element instanceof IDebugTarget) {
				IDebugTarget target= (IDebugTarget) element;
				if (target.isTerminated() || target.isDisconnected()) {
					return IDebugUIConstants.IMG_OBJS_DEBUG_TARGET_TERMINATED;
				} else if (target.isSuspended()) {
					return IDebugUIConstants.IMG_OBJS_DEBUG_TARGET_SUSPENDED;
				} else {
					return IDebugUIConstants.IMG_OBJS_DEBUG_TARGET;
				}
			} else if (element instanceof IExpression) {
				return IDebugUIConstants.IMG_OBJS_EXPRESSION;
			}
		} else {
			if (element instanceof IMarker) {
				return getMarkerImageKey((IMarker)element);
			} else if (element instanceof IBreakpoint) {
				return getBreakpointImageKey((IBreakpoint)element);
			} else if (element instanceof IProcess) {
				if (((IProcess) element).isTerminated()) {
					return IDebugUIConstants.IMG_OBJS_OS_PROCESS_TERMINATED;
				} 
				return IDebugUIConstants.IMG_OBJS_OS_PROCESS;
			} else if (element instanceof ILaunch) {
				// determine the image from the launch config type
				ILaunch launch= (ILaunch)element;
				ILaunchConfiguration configuration = launch.getLaunchConfiguration();
				if (configuration != null) {
					try {
						return configuration.getType().getIdentifier();
					} catch (CoreException e) {
						DebugUIPlugin.log(e);
						return null;
					}
				}
				// if no config, use the old "mode" way
				if (launch.getLaunchMode().equals(ILaunchManager.DEBUG_MODE)) {
					return IDebugUIConstants.IMG_OBJS_LAUNCH_DEBUG;
				} else if (launch.isTerminated()) {
					return IDebugUIConstants.IMG_OBJS_LAUNCH_RUN_TERMINATED;
				} else {
					return IDebugUIConstants.IMG_OBJS_LAUNCH_RUN;
				}	
			} else if (element instanceof ILaunchConfigurationType) {
				return ((ILaunchConfigurationType)element).getIdentifier();
			} else if (element instanceof ILaunchConfiguration) {
				try {
					return ((ILaunchConfiguration)element).getType().getIdentifier();
				} catch (CoreException e) {
					DebugUIPlugin.log(e);
					return null;
				}
			}
		}
		return null;		
	}

	/**
	 * @see ILabelProvider#getText(Object)
	 */
	public String getText(Object element) {
		StringBuffer label= new StringBuffer();
		try {
			// Group elements into debug elements and non-debug elements
			// to reduce the number of instanceof checks performed
			if (element instanceof IDebugElement) {
				if (element instanceof IStackFrame) {
					label.append(((IStackFrame)element).getName());
				} else if (element instanceof IndexedVariablePartition) {
					label.append(((IndexedVariablePartition)element).getName());
				} else if (element instanceof IVariable) {
					label.append(getVariableText((IVariable)element));
				} else if (element instanceof IThread) {
					label.append(((IThread)element).getName());
				} else if (element instanceof IDebugTarget) {
					label.append((((IDebugTarget)element).getName()));
				} else if (element instanceof IExpression) {
					label.append(getExpressionText((IExpression)element));
				} else if (element instanceof IRegisterGroup) {
					label.append(getRegisterGroupText((IRegisterGroup)element));
				} else if (element instanceof IValue) {
					label.append(((IValue)element).getValueString()); 
				}
			} else {
				if (element instanceof IMarker) {
					label.append(getMarkerText((IMarker) element));
				} else if (element instanceof IBreakpoint) {
					label.append(getBreakpointText((IBreakpoint)element));
				} else if (element instanceof IProcess) {
					label.append(((IProcess) element).getLabel());
				} else if (element instanceof ILaunch) {
					label.append(getLaunchText((ILaunch) element));
				} else if (element instanceof ILaunchConfiguration) {
					label.append(((ILaunchConfiguration)element).getName());
				} else if (element instanceof ILaunchConfigurationType) {
					label.append(((ILaunchConfigurationType)element).getName());
				} else if(element instanceof ILaunchDelegate) {
					ILaunchDelegate delegate = (ILaunchDelegate) element;
					String name = delegate.getName();
					if(name == null) {
						name = delegate.getContributorName();
					}
					label.append(name);
				} else if(element instanceof LaunchShortcutExtension) {
					label.append(((LaunchShortcutExtension)element).getLabel());
				} else if (element instanceof String) {
					label.append(element);
				} else {
					label.append(getAdapterLabel(element));
				}
			}
			if (element instanceof ITerminate) {
				if (((ITerminate) element).isTerminated()) {
					String terminatedMessage= null;
					if (element instanceof IProcess) {
						IProcess process = (IProcess)element;
						int exit = process.getExitValue();
						terminatedMessage= MessageFormat.format(DebugUIMessages.DefaultLabelProvider_16, new String[]{new Integer(exit).toString()}); 
					} else {
						terminatedMessage= DebugUIMessages.DefaultLabelProvider_1; 
					}
					label.insert(0, terminatedMessage);
				}
			} else if (element instanceof IDisconnect) {
				if (((IDisconnect) element).isDisconnected()) {
					label.insert(0, DebugUIMessages.DefaultLabelProvider__disconnected__1); 
				}
			}
		} catch (DebugException e) {
			DebugUIPlugin.log(e);
			label.append(DebugUIMessages.DefaultLabelProvider__unknown__1); 
		}
		return label.toString();
	}
	
	/**
	 * Returns default label for a breakpoint.
	 * 
	 * @param breakpoint
	 * @return default label for a breakpoint
	 */
	private String getBreakpointText(IBreakpoint breakpoint) {
		IResource resource = breakpoint.getMarker().getResource();
		StringBuffer label = new StringBuffer();
		if (resource != null) {
			label.append(resource.getName());
		}
		if (breakpoint instanceof ILineBreakpoint) {
			try {
				int lineNumber = ((ILineBreakpoint)breakpoint).getLineNumber();
				label.append(MessageFormat.format(DebugUIMessages.DefaultLabelProvider_17, new String[]{Integer.toString(lineNumber)})); 
			} catch (CoreException e) {
			}
		}
		return label.toString();
	}

	public String getAdapterLabel(Object object) {
		if (object instanceof IAdaptable) {
			IWorkbenchAdapter de= (IWorkbenchAdapter) ((IAdaptable) object).getAdapter(IWorkbenchAdapter.class);
			if (de != null) {
				return de.getLabel(object);
			}
		}
		return DebugUIMessages.DefaultLabelProvider__unknown__1; 
	}
	
	/**
	 * Used to render launch history items in the re-launch drop downs
	 */
	protected String getLaunchText(ILaunch launch) {
		if (launch.getLaunchConfiguration() == null || (!launch.getLaunchConfiguration().exists() && !launch.getLaunchConfiguration().isWorkingCopy())) {
			return DebugUIMessages.DefaultLabelProvider__unknown__1; 
		} 
		// new launch configuration
		ILaunchConfiguration config = launch.getLaunchConfiguration();
		StringBuffer buff= new StringBuffer(config.getName());
		buff.append(" ["); //$NON-NLS-1$
		try {
			buff.append(config.getType().getName());
		} catch (CoreException e) {
			DebugUIPlugin.log(e);
		}
		buff.append("]"); //$NON-NLS-1$
		return buff.toString();			
	}

	protected String getExpressionText(IExpression expression) {
		if (expression instanceof IWatchExpression) {
			return getWatchExpressionText((IWatchExpression) expression);
		}
		StringBuffer buffer= new StringBuffer(expression.getExpressionText());
		String valueString= null;
		IValue value= expression.getValue();
		if (value != null) {
			try {
				valueString= value.getValueString();
			} catch (DebugException de) {
				DebugUIPlugin.log(de);
			}
		}
		if (valueString != null && valueString.length() > 0) {
			buffer.append("= "); //$NON-NLS-1$
			buffer.append(valueString);		
		}
		return buffer.toString();
	}	
	
	/**
	 * @param expression
	 * @return
	 */
	protected String getWatchExpressionText(IWatchExpression expression) {
		StringBuffer result= new StringBuffer();
		
		String snippet = expression.getExpressionText().trim();
		StringBuffer snippetBuffer = new StringBuffer();
		if (snippet.length() > 30){
			snippetBuffer.append(snippet.substring(0, 15));
			snippetBuffer.append(DebugUIMessages.DefaultLabelProvider_0);
			snippetBuffer.append(snippet.substring(snippet.length() - 15));
		} else {
			snippetBuffer.append(snippet);
		}
		snippet = snippetBuffer.toString().replaceAll("[\n\r\t]+", " ");  //$NON-NLS-1$//$NON-NLS-2$
		
		result.append('"');
		result.append(snippet);
		result.append('"');

		if (expression.isPending()) {
			result.append(DebugUIMessages.DefaultLabelProvider_12); 
		} else if (expression.hasErrors()) {
			result.append(DebugUIMessages.DefaultLabelProvider_13); 
		} else {
			IValue value= expression.getValue();
			if (value != null) {	
				String valueString= DebugUIPlugin.getModelPresentation().getText(value);
				if (valueString.length() > 0) {
					result.append(" = ").append(valueString); //$NON-NLS-1$
				}
			}
		}
		if (!expression.isEnabled()) {
			result.append(DebugUIMessages.DefaultLabelProvider_15); 
		}
		return result.toString();
	}

	protected String getVariableText(IVariable variable) {
		StringBuffer buffer= new StringBuffer();
		try {
			IValue value = variable.getValue();
			buffer.append(variable.getName());
			buffer.append(" = "); //$NON-NLS-1$
			buffer.append(value.getValueString());
		} catch (DebugException de) {
			DebugUIPlugin.log(de);
		}
		return buffer.toString();
	}
	
	protected String getRegisterGroupText(IRegisterGroup registerGroup) {
		StringBuffer buffer= new StringBuffer();
		try {
			buffer.append(registerGroup.getName());
		} catch (DebugException de) {
			DebugUIPlugin.log(de);
		}
		return buffer.toString();
	}
	
	protected String getMarkerText(IMarker marker) {
		try {
			if (marker.exists() && marker.isSubtypeOf(IBreakpoint.BREAKPOINT_MARKER)) {
				return DebugUIMessages.DefaultLabelProvider_Breakpoint_1; 
			}
		} catch (CoreException e) {
			DebugUIPlugin.log(e);
		}
		return IInternalDebugCoreConstants.EMPTY_STRING;
	}
	
	protected String getMarkerImageKey(IMarker marker) {
		try {
			IBreakpoint breakpoint= DebugPlugin.getDefault().getBreakpointManager().getBreakpoint(marker);
			if (breakpoint != null && marker.exists()) {
				if (breakpoint.isEnabled()) {
					return IDebugUIConstants.IMG_OBJS_BREAKPOINT;
				} 
				return IDebugUIConstants.IMG_OBJS_BREAKPOINT_DISABLED;
			}
		} catch (CoreException e) {
		}
		return null;
	}
	
	protected String getBreakpointImageKey(IBreakpoint breakpoint) {
		if (breakpoint != null && breakpoint.getMarker().exists()) {
		    try {
			    boolean enabled = breakpoint.isEnabled();
			    if (breakpoint instanceof IWatchpoint) {
	                IWatchpoint watchpoint = (IWatchpoint) breakpoint;
	        		if (watchpoint.isAccess()) {
	        			if (watchpoint.isModification()) {
	        				//access and modification
	        				if (enabled) {
	        					return IDebugUIConstants.IMG_OBJS_WATCHPOINT;
	        				} 
	        				return IDebugUIConstants.IMG_OBJS_WATCHPOINT_DISABLED;
	        			}
	        			if (enabled) {
        					return IDebugUIConstants.IMG_OBJS_ACCESS_WATCHPOINT;
        				} 
	        			return IDebugUIConstants.IMG_OBJS_ACCESS_WATCHPOINT_DISABLED;
	        		} else if (watchpoint.isModification()) {
	        			if (enabled) {
	        				return IDebugUIConstants.IMG_OBJS_MODIFICATION_WATCHPOINT;
	        			} 
	        			return IDebugUIConstants.IMG_OBJS_MODIFICATION_WATCHPOINT_DISABLED;
	        		} else {
	        			//neither access nor modification
	        			return IDebugUIConstants.IMG_OBJS_WATCHPOINT_DISABLED;
	        		}
	            }
			    if (enabled) {
					return IDebugUIConstants.IMG_OBJS_BREAKPOINT;
				} 
				return IDebugUIConstants.IMG_OBJS_BREAKPOINT_DISABLED;
		    } catch (CoreException e) {
		    }
		}
		return null;
	}

	/**
	 * @see IBaseLabelProvider#addListener(ILabelProviderListener)
	 */
	public void addListener(ILabelProviderListener listener) {
	}

	/**
	 * @see IBaseLabelProvider#dispose()
	 */
	public void dispose() {
		Iterator iterator = fImages.values().iterator();
		while (iterator.hasNext()) {
			Image image = (Image) iterator.next();
			image.dispose();
		}
		fImages.clear();
	}

	/**
	 * @see IBaseLabelProvider#isLabelProperty(Object, String)
	 */
	public boolean isLabelProperty(Object element, String property) {
		return false;
	}

	/**
	 * @see IBaseLabelProvider#removeListener(ILabelProviderListener)
	 */
	public void removeListener(ILabelProviderListener listener) {
	}
	
	/**
	 * Returns the given string with special chars in escaped sequences.
	 * 
	 * @param label
	 * @return the given string with special chars in escaped sequences
	 * @since 3.3
	 */
	public static String escapeSpecialChars(String string) {
		if (string == null) {
			return null;
		}
		StringBuffer escaped = new StringBuffer();
		for (int i = 0; i < string.length(); i++) {
			char c = string.charAt(i);
			switch (c) {
				case '\b':
					escaped.append("\\b"); //$NON-NLS-1$
					break;
				case '\f':
					escaped.append("\\f"); //$NON-NLS-1$
					break;					
				case '\n':
					escaped.append("\\n"); //$NON-NLS-1$
					break;
				case '\r':
					escaped.append("\\r"); //$NON-NLS-1$
					break;
				case '\t':
					escaped.append("\\t"); //$NON-NLS-1$
					break;
				case '\\':
					escaped.append("\\\\"); //$NON-NLS-1$
					break;					
				default:
					escaped.append(c);
					break;
			}
		}
		return escaped.toString();
	}	
	
	/**
	 * Returns the string with escaped sequences replaced with single chars.
	 * 
	 * @param string
	 * @return the string with escaped sequences replaced with single chars
	 * @since 3.3
	 */
	public static String encodeEsacpedChars(String string) {
		if (string == null) {
			return null;
		}
		StringBuffer encoded = new StringBuffer();
		if (string.length() == 1) {
			return string;
		}
		for (int i = 0; i < string.length(); i++) {
			char c = string.charAt(i);
			if (c == '\\') {
				switch (string.charAt(i+1)) {
					case 'b':
						c= '\b';
						i++;
						break;
					case 'f':
						c= '\f';
						i++;
						break;
					case 'n':
						c= '\n';
						i++;
						break;
					case 'r':
						c= '\r';
						i++;
						break;
					case 't':
						c= '\t';
						i++;
						break;
					case '\'':
						c= '\'';
						i++;
						break;
					case '\\':
						c= '\\';
						i++;
						break;
					default :
						break;
				}	
			}
			encoded.append(c);
		}
		return encoded.toString();		
	}
}

