/*******************************************************************************
 * Copyright (c) 2006, 2007 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
 *******************************************************************************/

package org.eclipse.debug.internal.ui.elements.adapters;

import java.math.BigInteger;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.model.MemoryByte;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.debug.internal.ui.DebugPluginImages;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.memory.provisional.AbstractAsyncTableRendering;
import org.eclipse.debug.internal.ui.memory.provisional.MemoryViewPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousLabelAdapter;
import org.eclipse.debug.internal.ui.views.launch.DebugElementHelper;
import org.eclipse.debug.internal.ui.views.memory.renderings.AbstractBaseTableRendering;
import org.eclipse.debug.internal.ui.views.memory.renderings.MemorySegment;
import org.eclipse.debug.internal.ui.views.memory.renderings.TableRenderingContentDescriptor;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.memory.IMemoryBlockTablePresentation;
import org.eclipse.debug.ui.memory.MemoryRenderingElement;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.IFontProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;

public class MemorySegmentLabelAdapter extends AsynchronousLabelAdapter {

	protected String[] getLabels(Object element, IPresentationContext context)
			throws CoreException {
		
		if (context instanceof MemoryViewPresentationContext)
		{
			MemoryViewPresentationContext tableRenderingContext = (MemoryViewPresentationContext)context;
			if (tableRenderingContext.getRendering() != null && tableRenderingContext.getRendering() instanceof AbstractAsyncTableRendering)
			{
				AbstractAsyncTableRendering tableRendering = (AbstractAsyncTableRendering)tableRenderingContext.getRendering();
				TableRenderingContentDescriptor descriptor = (TableRenderingContentDescriptor)tableRendering.getAdapter(TableRenderingContentDescriptor.class);
				if (descriptor != null)
				{
					String addressStr = getColumnText(element, 0, tableRendering, descriptor);
					int numColumns = tableRendering.getAddressableUnitPerLine() / tableRendering.getAddressableUnitPerColumn();
					
					String[] labels = new String[numColumns+2];
					labels[0] = addressStr;
					
					for (int i=0; i<=numColumns; i++)
					{
						labels[i+1] = getColumnText(element, i+1, tableRendering, (TableRenderingContentDescriptor)tableRendering.getAdapter(TableRenderingContentDescriptor.class));
					}
					
					labels[labels.length - 1 ] = IInternalDebugCoreConstants.EMPTY_STRING;
					return labels;
				}
			}
		}
		return new String[0];
	}
	
	private String getColumnText(Object element, int columnIndex, AbstractAsyncTableRendering tableRendering, TableRenderingContentDescriptor descriptor) {
		String columnLabel = null;

		if (columnIndex == 0)
		{
			IMemoryBlockTablePresentation presentation = (IMemoryBlockTablePresentation)tableRendering.getMemoryBlock().getAdapter(IMemoryBlockTablePresentation.class);
			if (presentation != null)
			{
				String rowLabel = presentation.getRowLabel(tableRendering.getMemoryBlock(), ((MemorySegment)element).getAddress());
				if (rowLabel != null)
					return rowLabel;
			}
			
			columnLabel = ((MemorySegment)element).getAddress().toString(16).toUpperCase();
			
			int addressSize = descriptor.getAddressSize();
			int prefillLength = addressSize * 2 - columnLabel.length();
			StringBuffer buf = new StringBuffer();
			if (prefillLength > 0)
			{
				for (int i=0; i<prefillLength; i++)
				{
					buf.append("0"); //$NON-NLS-1$
				}
			}
			buf.append(columnLabel);
			return buf.toString();
			
		}
		else if (columnIndex > (tableRendering.getBytesPerLine()/tableRendering.getBytesPerColumn()))
		{
			columnLabel = " "; //$NON-NLS-1$
		}
		else
		{	
			if (element instanceof MemorySegment)
			{
				MemorySegment segment = (MemorySegment)element;
				if (segment.getBytes().length != tableRendering.getBytesPerLine())
					return IInternalDebugCoreConstants.EMPTY_STRING;
			}
			
			ILabelProvider labelProvider = (ILabelProvider)tableRendering.getAdapter(ILabelProvider.class);
			if (labelProvider != null && columnIndex > 0)
			{
				MemoryRenderingElement renderingElement = getMemoryRenderingElement(element, columnIndex, tableRendering);
				if (renderingElement != null) {
					String label = labelProvider.getText(renderingElement);
					if (label != null)
						return label;
				}			
			}
			
			int start = (columnIndex-1)*tableRendering.getBytesPerColumn();
			MemoryByte[] bytes = ((MemorySegment)element).getBytes(start, tableRendering.getBytesPerColumn());
			BigInteger address = ((MemorySegment)element).getAddress();
			address = address.add(BigInteger.valueOf(start)); 
			
			columnLabel = tableRendering.getString(tableRendering.getRenderingId(), address, bytes);
		}
		return columnLabel;
	}

	protected ImageDescriptor[] getImageDescriptors(Object element,
			IPresentationContext context) throws CoreException {
		if (context instanceof MemoryViewPresentationContext)
		{
			MemoryViewPresentationContext tableRenderingContext = (MemoryViewPresentationContext)context;
			if (tableRenderingContext.getRendering() != null && tableRenderingContext.getRendering() instanceof AbstractAsyncTableRendering)
			{
				AbstractAsyncTableRendering tableRendering = (AbstractAsyncTableRendering)tableRenderingContext.getRendering();
				int numColumns = tableRendering.getAddressableUnitPerLine() / tableRendering.getAddressableUnitPerColumn();
				
				ImageDescriptor[] images = new ImageDescriptor[numColumns+2];
				
				for (int i=0; i<=numColumns; i++)
				{
					images[i] = getColumnImageDescriptor(element, i, tableRendering);
				}
				
				images[images.length - 1 ] = null;
				return images;
			}
		}
		return new ImageDescriptor[0];
	}
	
	private ImageDescriptor getColumnImageDescriptor(Object element, int columnIndex, AbstractAsyncTableRendering tableRendering)
	{
		if (columnIndex == 0)
			return DebugPluginImages.getImageDescriptor(IInternalDebugUIConstants.IMG_OBJECT_MEMORY);	
		
		if (element instanceof MemorySegment)
		{
			MemorySegment segment = (MemorySegment)element;
			if (segment.getBytes().length != tableRendering.getBytesPerLine())
				return null;
			
			ILabelProvider labelProvider = (ILabelProvider)tableRendering.getAdapter(ILabelProvider.class);
			if (labelProvider != null && columnIndex > 0)
			{
				MemoryRenderingElement renderingElement = getMemoryRenderingElement(element, columnIndex, tableRendering);
				if (renderingElement != null) {
					Image image = labelProvider.getImage(renderingElement);
					if (image != null)
					{
						return DebugElementHelper.getImageDescriptor(image);
					}
				}			
			}
			
			int start = (columnIndex-1)*tableRendering.getBytesPerColumn();

			MemoryByte[] bytes = ((MemorySegment)element).getBytes(start, tableRendering.getBytesPerColumn());
			boolean allKnown = true;
			boolean unchanged = true;
			for (int i=0; i<bytes.length; i++)
			{
				if (!bytes[i].isHistoryKnown())
					allKnown = false;
				
				if (bytes[i].isChanged())
					unchanged = false;
			}
			
			if (allKnown)
			{
				// mark changed elements with changed icon
				if (!unchanged)
					return DebugPluginImages.getImageDescriptor(IInternalDebugUIConstants.IMG_OBJECT_MEMORY_CHANGED);
				
			}
		}
		return DebugPluginImages.getImageDescriptor(IInternalDebugUIConstants.IMG_OBJECT_MEMORY);
	}

	protected FontData[] getFontDatas(Object element,
			IPresentationContext context) throws CoreException {
		if (context instanceof MemoryViewPresentationContext)
		{
			MemoryViewPresentationContext tableRenderingContext = (MemoryViewPresentationContext)context;
			if (tableRenderingContext.getRendering() != null && tableRenderingContext.getRendering() instanceof AbstractAsyncTableRendering)
			{
				AbstractAsyncTableRendering tableRendering = (AbstractAsyncTableRendering)tableRenderingContext.getRendering();
				int numColumns = tableRendering.getAddressableUnitPerLine() / tableRendering.getAddressableUnitPerColumn();
				
				FontData[] fontData = new FontData[numColumns+2];

				for (int i=0; i<fontData.length-1; i++)
				{
					fontData[i] = getColumnFontData(element, i, tableRendering);
				}
				return fontData;
			}
		}
		
		return new FontData[0];
	}
	
	private FontData getColumnFontData(Object element, int columnIndex, AbstractAsyncTableRendering tableRendering) 
	{
		if (element instanceof MemorySegment)
		{	
			MemorySegment segment = (MemorySegment)element;
			if (segment.getBytes().length != tableRendering.getBytesPerLine())
				return null;
			
			IFontProvider fontProvider = (IFontProvider)tableRendering.getAdapter(IFontProvider.class);
			if (fontProvider != null && columnIndex > 0)
			{
				MemoryRenderingElement renderingElement = getMemoryRenderingElement(element, columnIndex, tableRendering);
				if (renderingElement != null) {
					Font font = fontProvider.getFont(renderingElement);
					if (font != null)
						return font.getFontData()[0];
				}			
			}
		}
		return null;
	}

	protected RGB[] getForegrounds(Object element, IPresentationContext context)
			throws CoreException {
		
		if (context instanceof MemoryViewPresentationContext)
		{
			MemoryViewPresentationContext tableRenderingContext = (MemoryViewPresentationContext)context;
			if (tableRenderingContext.getRendering() != null && tableRenderingContext.getRendering() instanceof AbstractAsyncTableRendering)
			{
				AbstractAsyncTableRendering tableRendering = (AbstractAsyncTableRendering)tableRenderingContext.getRendering();
				int numColumns = tableRendering.getAddressableUnitPerLine() / tableRendering.getAddressableUnitPerColumn();
				
				RGB[] colors = new RGB[numColumns+2];

				for (int i=0; i<colors.length-1; i++)
				{
					colors[i] = getColumnForeground(element, i, tableRendering);
				}
				
				colors[colors.length-1] = null;
				
				return colors;
			}
		}

		return new RGB[0];
	}
	
	private RGB getColumnBackground(Object element, int columnIndex, AbstractAsyncTableRendering tableRendering)
	{
		if (columnIndex == 0)
			return null;
		
		if (element instanceof MemorySegment)
		{	
			MemorySegment segment = (MemorySegment)element;
			if (segment.getBytes().length != tableRendering.getBytesPerLine())
				return null;
			
			IColorProvider colorProvider = (IColorProvider)tableRendering.getAdapter(IColorProvider.class);
			if (colorProvider != null && columnIndex > 0)
			{
				MemoryRenderingElement renderingElement = getMemoryRenderingElement(element, columnIndex, tableRendering);
				if (renderingElement != null) {
					Color color = colorProvider.getBackground(renderingElement);
					if (color != null)
						return color.getRGB();
				}			
			}
		}
		return null;
	}
	
	private RGB getColumnForeground(Object element, int columnIndex, AbstractAsyncTableRendering tableRendering)
	{
		if (columnIndex == 0)
			return null;
		
		if (element instanceof MemorySegment)
		{	
			MemorySegment segment = (MemorySegment)element;
			if (segment.getBytes().length != tableRendering.getBytesPerLine())
				return null;
			
			IColorProvider colorProvider = (IColorProvider)tableRendering.getAdapter(IColorProvider.class);
			if (colorProvider != null && columnIndex > 0)
			{
				MemoryRenderingElement renderingElement = getMemoryRenderingElement(element, columnIndex, tableRendering);
				if (renderingElement != null) {
					Color color = colorProvider.getForeground(renderingElement);
					if (color != null)
						return color.getRGB();
				}			
			}
			
			int start = (columnIndex-1)*tableRendering.getBytesPerColumn();
			MemoryByte[] bytes = segment.getBytes(start, tableRendering.getBytesPerColumn());
			boolean allKnown = true;
			boolean unchanged = true;
			for (int i=0; i<bytes.length; i++)
			{
				if (!bytes[i].isHistoryKnown())
					allKnown = false;
				
				if (bytes[i].isChanged())
					unchanged = false;
			}
			
			if (allKnown)
			{
				// mark changed elements in changed color
				if (!unchanged)
					return DebugUIPlugin.getPreferenceColor(IDebugUIConstants.PREF_CHANGED_DEBUG_ELEMENT_COLOR).getRGB();				
				
				return DebugUIPlugin.getPreferenceColor(IDebugUIConstants.PREF_MEMORY_HISTORY_KNOWN_COLOR).getRGB();
			}
			
			return DebugUIPlugin.getPreferenceColor(IDebugUIConstants.PREF_MEMORY_HISTORY_UNKNOWN_COLOR).getRGB();
			
		}
		return null;
	}

	protected RGB[] getBackgrounds(Object element, IPresentationContext context)
			throws CoreException {
		
		if (context instanceof MemoryViewPresentationContext)
		{
			MemoryViewPresentationContext tableRenderingContext = (MemoryViewPresentationContext)context;
			if (tableRenderingContext.getRendering() != null && tableRenderingContext.getRendering() instanceof AbstractAsyncTableRendering)
			{
				AbstractAsyncTableRendering tableRendering = (AbstractAsyncTableRendering)tableRenderingContext.getRendering();
				int numColumns = tableRendering.getAddressableUnitPerLine() / tableRendering.getAddressableUnitPerColumn();
				
				RGB[] colors = new RGB[numColumns+2];

				for (int i=0; i<colors.length-1; i++)
				{
					colors[i] = getColumnBackground(element, i, tableRendering);
				}
				
				colors[colors.length-1] = null;
				
				return colors;
			}
		}

		return new RGB[0];
	}
	
	/**
	 * Returns a memory rendering element corresponding to the given element
	 * or <code>null</code> if none.
	 *  
	 * @param element element to be rendered
	 * @param columnIndex column index at which to render
	 * @return memory rendering element or <code>null</code>
	 */
	private MemoryRenderingElement getMemoryRenderingElement(Object element, int columnIndex, AbstractBaseTableRendering rendering) {
		if (element instanceof MemorySegment) {
			MemorySegment line = (MemorySegment) element;
			BigInteger address = line.getAddress();
			int offset = (columnIndex - 1) * rendering.getBytesPerColumn();
			if (offset < rendering.getBytesPerLine() && (offset + rendering.getBytesPerColumn()) <= rendering.getBytesPerLine()) {
				return getMemoryRenderingElement(line, address, offset, rendering);
			}
		}
		return null;
	}
	
	private MemoryRenderingElement getMemoryRenderingElement(MemorySegment line, BigInteger lineAddress, int offset, AbstractBaseTableRendering rendering) {
		BigInteger cellAddress = lineAddress.add(BigInteger.valueOf(offset));
		MemoryByte[] bytes = line.getBytes(offset, rendering.getBytesPerColumn());
		// make a copy to ensure that the memory bytes are not overwritten
		// by clients
		MemoryByte[] copy = new MemoryByte[bytes.length];
		System.arraycopy(bytes, 0, copy, 0, bytes.length);
		MemoryRenderingElement renderingElement = new MemoryRenderingElement(
				rendering, cellAddress, copy);
		return renderingElement;
	}

}
