/*******************************************************************************
 * Copyright (c) 2007, 2013 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.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IRegisterGroup;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.internal.core.commands.Request;
import org.eclipse.debug.internal.ui.viewers.model.ViewerAdapterService;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.ui.IMemento;

/**
 * Used as input to the registers view for a stack frame. Insulates register groups
 * that do not change across stack frame selection to avoid register groups collapsing
 * while stepping between frames.
 * <p>
 * The standard debug model {@link IStackFrame} uses an
 * {@link org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputProvider} to
 * create a register group proxy for the register view's input.
 * </p>
 * <p>
 * This class delegates to the underlying stack frame for the following adapters. This way,
 * if a standard model provides custom adapters they are still used to present custom content
 * in the view and provide stable register groups while stepping.
 * <ul>
 * <li>{@link IModelProxyFactory}</li>
 * <li>{@link IColumnPresentationFactory}</li>
 * <li>{@link IElementContentProvider}</li>
 * <li>{@link IElementMementoProvider}</li>
 * </ul>
 * </p>
 * @since 3.4
 */
public class RegisterGroupProxy implements IModelProxyFactory, IColumnPresentationFactory, IElementContentProvider, IElementMementoProvider {

	private IRegisterGroup[] fGroups;
	private IStackFrame fFrame;

	private static final String HASH_CODE = "HASH_CODE"; //$NON-NLS-1$

	/**
	 * Local implementation of a viewer update request. This class delegates to the underlying frame
	 * for viewer requests. The requests have to be wrapped such that the request's element provided
	 * for existing clients is the underlying frame, rather than the register group proxy (as existing
	 * models do not know or need to know about the proxy).
	 */
	private class Update extends Request implements IViewerUpdate {
		private IViewerUpdate fViewerUpdate;

		Update(IViewerUpdate update) {
			fViewerUpdate = update;
		}
		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate#getElement()
		 */
		@Override
		public Object getElement() {
			return fFrame;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate#getElementPath()
		 */
		@Override
		public TreePath getElementPath() {
			return TreePath.EMPTY;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate#getPresentationContext()
		 */
		@Override
		public IPresentationContext getPresentationContext() {
			return fViewerUpdate.getPresentationContext();
		}

		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.core.commands.Request#done()
		 */
		@Override
		public void done() {
			fViewerUpdate.setStatus(getStatus());
			fViewerUpdate.done();
		}

		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate#getViewerInput()
		 */
		@Override
		public Object getViewerInput() {
			return fFrame;
		}

	}

	private class CountUpdate extends Update implements IChildrenCountUpdate {

		private IChildrenCountUpdate fUpdate;

		CountUpdate(IChildrenCountUpdate delegate) {
			super(delegate);
			fUpdate = delegate;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate#setChildCount(int)
		 */
		@Override
		public void setChildCount(int numChildren) {
			fUpdate.setChildCount(numChildren);
		}

	}

	private class HasUpdate extends Update implements IHasChildrenUpdate {

		private IHasChildrenUpdate fUpdate;

		HasUpdate(IHasChildrenUpdate delegate) {
			super(delegate);
			fUpdate = delegate;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate#setHasChilren(boolean)
		 */
		@Override
		public void setHasChilren(boolean hasChildren) {
			fUpdate.setHasChilren(hasChildren);
		}

	}

	private class ChildrenUpdate extends Update implements IChildrenUpdate {

		private IChildrenUpdate fUpdate;

		ChildrenUpdate(IChildrenUpdate delegate) {
			super(delegate);
			fUpdate = delegate;
		}
		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate#getLength()
		 */
		@Override
		public int getLength() {
			return fUpdate.getLength();
		}

		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate#getOffset()
		 */
		@Override
		public int getOffset() {
			return fUpdate.getOffset();
		}

		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate#setChild(java.lang.Object, int)
		 */
		@Override
		public void setChild(Object child, int offset) {
			fUpdate.setChild(child, offset);
		}

	}

	/**
	 * The memento request has to override {@link #getElement()} to provide the element
	 * that a memento is requested for (which could be any element in the view, not just
	 * the root stack frame).
	 */
	private class MementoRequest extends Update implements IElementMementoRequest {

		private IElementMementoRequest fUpdate;
		MementoRequest(IElementMementoRequest request) {
			super(request);
			fUpdate = request;
		}
		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest#getMemento()
		 */
		@Override
		public IMemento getMemento() {
			return fUpdate.getMemento();
		}
		@Override
		public Object getElement() {
			return fUpdate.getElement();
		}
		@Override
		public TreePath getElementPath() {
			return fUpdate.getElementPath();
		}

	}

	private class ElementCompare extends MementoRequest implements IElementCompareRequest {

		private IElementCompareRequest fRequest;
		ElementCompare(IElementCompareRequest request) {
			super(request);
			fRequest = request;
		}
		/* (non-Javadoc)
		 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest#setEqual(boolean)
		 */
		@Override
		public void setEqual(boolean equal) {
			fRequest.setEqual(equal);
		}

	}

	/**
	 * Creates a new register group proxy for the given stack frame.
	 *
	 * @param frame stack frame
	 * @throws DebugException exception if unable to retrieve register groups
	 */
	public RegisterGroupProxy(IStackFrame frame) throws DebugException {
		fFrame = frame;
		init(frame);
	}

	/* (non-Javadoc)
	 *
	 * A register group proxy is equal to other stack frames that have the same
	 * register groups.
	 *
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof RegisterGroupProxy) {
			return Arrays.equals(fGroups, ((RegisterGroupProxy)obj).fGroups);
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		int code = getClass().hashCode();
		for (int i = 0; i < fGroups.length; i++) {
			code+=fGroups[i].hashCode();
		}
		return code;
	}

	/**
	 * Initializes the register groups for this stack frame.
	 *
	 * @param frame stack frame
	 */
	private void init(IStackFrame frame) throws DebugException {
		fGroups = frame.getRegisterGroups();
	}

	/**
	 * Returns cached register groups for this stack frame.
	 *
	 * @return register groups
	 */
	protected IRegisterGroup[] getRegisterGroups() {
		return fGroups;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory#createModelProxy(java.lang.Object, org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext)
	 */
	@Override
	public IModelProxy createModelProxy(Object element, IPresentationContext context) {
		IModelProxyFactory factory = ViewerAdapterService.getModelProxyFactory(fFrame);
		if (factory != null) {
			return factory.createModelProxy(fFrame, context);
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory#createColumnPresentation(org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, java.lang.Object)
	 */
	@Override
	public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) {
		IColumnPresentationFactory factory = ViewerAdapterService.getColumnPresentationFactory(fFrame);
		if (factory != null) {
			return factory.createColumnPresentation(context, fFrame);
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory#getColumnPresentationId(org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, java.lang.Object)
	 */
	@Override
	public String getColumnPresentationId(IPresentationContext context, Object element) {
		IColumnPresentationFactory factory = ViewerAdapterService.getColumnPresentationFactory(fFrame);
		if (factory != null) {
			return factory.getColumnPresentationId(context, fFrame);
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider#update(org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate[])
	 */
	@Override
	public void update(IChildrenCountUpdate[] updates) {
		IElementContentProvider provider = ViewerAdapterService.getContentProvider(fFrame);
		if (provider != null) {
			IChildrenCountUpdate[] others = new IChildrenCountUpdate[updates.length];
			for (int i = 0; i < updates.length; i++) {
				others[i] = new CountUpdate(updates[i]);
			}
			provider.update(others);
		} else {
			cancelUpdates(updates);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider#update(org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate[])
	 */
	@Override
	public void update(IChildrenUpdate[] updates) {
		IElementContentProvider provider = ViewerAdapterService.getContentProvider(fFrame);
		if (provider != null) {
			IChildrenUpdate[] others = new IChildrenUpdate[updates.length];
			for (int i = 0; i < updates.length; i++) {
				others[i] = new ChildrenUpdate(updates[i]);
			}
			provider.update(others);
		} else {
			cancelUpdates(updates);
		}

	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider#update(org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate[])
	 */
	@Override
	public void update(IHasChildrenUpdate[] updates) {
		IElementContentProvider provider = ViewerAdapterService.getContentProvider(fFrame);
		if (provider != null) {
			IHasChildrenUpdate[] others = new IHasChildrenUpdate[updates.length];
			for (int i = 0; i < updates.length; i++) {
				others[i] = new HasUpdate(updates[i]);
			}
			provider.update(others);
		} else {
			cancelUpdates(updates);
		}
	}

	/**
	 * Cancels a collection of update requests.
	 *
	 * @param updates updates to cancel
	 */
	private void cancelUpdates(IViewerUpdate[] updates) {
		for (int i = 0; i < updates.length; i++) {
			updates[i].setStatus(Status.CANCEL_STATUS);
			updates[i].done();
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider#compareElements(org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest[])
	 */
	@Override
	public void compareElements(IElementCompareRequest[] requests) {
		IElementMementoProvider provider = ViewerAdapterService.getMementoProvider(fFrame);
		if (provider != null) {
			List<IElementCompareRequest> others = new ArrayList<>(requests.length);
			for (int i = 0; i < requests.length; i++) {
				IElementCompareRequest request = requests[i];
				if (request.getElement().equals(this)) {
					Integer integer = request.getMemento().getInteger(HASH_CODE);
					if (integer != null) {
						request.setEqual(integer.intValue() == hashCode());
					} else {
						request.setEqual(false);
					}
					request.done();
				} else {
					others.add(new ElementCompare(request));
				}
			}
			if (!others.isEmpty()) {
				provider.compareElements(others.toArray(new IElementCompareRequest[others.size()]));
			}
		} else {
			cancelUpdates(requests);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider#encodeElements(org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest[])
	 */
	@Override
	public void encodeElements(IElementMementoRequest[] requests) {
		IElementMementoProvider provider = ViewerAdapterService.getMementoProvider(fFrame);
		if (provider != null) {
			List<IElementMementoRequest> others = new ArrayList<>(requests.length);
			for (int i = 0; i < requests.length; i++) {
				IElementMementoRequest request = requests[i];
				if (request.getElement().equals(this)) {
					request.getMemento().putInteger(HASH_CODE, this.hashCode());
					request.done();
				} else {
					others.add(new MementoRequest(request));
				}
			}
			if (!others.isEmpty()) {
				provider.encodeElements(others.toArray(new IElementMementoRequest[others.size()]));
			}
		} else {
			cancelUpdates(requests);
		}
	}

}
