/*******************************************************************************
 * Copyright (c) 2011, 2015 Wind River Systems and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Wind River Systems - initial API and implementation
 *******************************************************************************/
package org.eclipse.debug.internal.ui.viewers.model.provisional;

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

import org.eclipse.core.runtime.Assert;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;

/**
 * Virtual item, which is analogous to the SWT's tree item.  This class is used
 * by the {@link VirtualTreeModelViewer}.
 *
 * @see VirtualTreeModelViewer
 * @since 3.8
 */
public class VirtualItem {

	// Data keys for display attributes of an item.
	public static String LABEL_KEY = "LABEL_KEY"; //$NON-NLS-1$
	public static String IMAGE_KEY = "IMAGE_KEY"; //$NON-NLS-1$
	public static String FONT_KEY = "FONT_KEY"; //$NON-NLS-1$
	public static String FOREGROUND_KEY = "FOREGROUND_KEY"; //$NON-NLS-1$
	public static String BACKGROUND_KEY = "BACKGROUND_KEY"; //$NON-NLS-1$

	public static String ELEMENT_DATA_KEY = "element"; //$NON-NLS-1$

	/**
	 * Index object of a tree item. It allows the indexes to be modified
	 * as items are inserted and removed.
	 */
	public static class Index implements Comparable<Object> {
		private Integer fIndexValue;

		public Index(int index) {
			fIndexValue = Integer.valueOf(index);
		}

		@Override
		public boolean equals(Object obj) {
			return obj instanceof Index && ((Index)obj).fIndexValue.equals(fIndexValue);
		}

		@Override
		public int hashCode() {
			return fIndexValue.hashCode();
		}

		public void increment() {
			fIndexValue = Integer.valueOf(fIndexValue.intValue() + 1);
		}

		public void decrement() {
			fIndexValue = Integer.valueOf(fIndexValue.intValue() - 1);
		}

		public int intValue() {
			return fIndexValue.intValue();
		}

		@Override
		public int compareTo(Object obj) {
			return obj instanceof Index ? fIndexValue.compareTo(((Index)obj).fIndexValue) : 0;
		}

		@Override
		public String toString() {
			return fIndexValue.toString();
		}
	}

	/**
	 * Parent items of this item.
	 */
	final private VirtualItem fParent;

	/**
	 * The index of this item.
	 */
	final private Index fIndex;

	/**
	 * Map of child items.  The key to the map is the item's index, which
	 * must be the same object instance as the index in the item.  The tree map
	 * keeps the items sorted while allowing indexes (keys) to be modified as
	 * child items are inserted and removed.
	 */
	private Map<Index, VirtualItem> fItems = new TreeMap<>();

	/**
	 * Flag indicating whether this item has child items.
	 */
	private boolean fHasItems = false;

	/**
	 * Indicates that this item has been expanded.  It should only
	 * be set to <code>true</code> if fHasItems is <code>true</code>.
	 */
	private boolean fExpanded = false;

	/**
	 * The count of child items.  <code>-1</code> indicates that the count
	 * is not known.
	 */
	private int fItemCount = -1;

	/**
	 * The data held by this item.  It includes the element as well as the item
	 * display attributes.
	 */
	private Map<String, Object> fData = new HashMap<>(1);

	/**
	 * Flag indicating that the item needs to have it's label updated.
	 */
	private boolean fNeedsLabelUpdate = true;

	/**
	 * Flag indicating that the item's count needs to be updated.
	 */
	private boolean fNeedsCountUpdate = true;

	/**
	 * Flag indicating that the item's element needs to be updated.
	 */
	private boolean fNeedsDataUpdate = true;

	/**
	 * Indicates that this item has been disposed.
	 */
	private boolean fDisposed = false;


	/**
	 * Virtual item constructor.
	 * @param parent parent virtual item
	 * @param index index of the item in the parent
	 */
	public VirtualItem(VirtualItem parent, Index index) {
		fParent = parent;
		fIndex = index;
	}

	/**
	 * Clears the child item at the given index.
	 * @param index index of item to clear.
	 */
	public void clear(Index index) {
		VirtualItem item = fItems.remove(index);
		if (item != null) {
			item.dispose();
		}
	}

	/**
	 * Clears all child items.
	 *
	 * @since 3.9
	 */
	public void clearAll() {
		fData.clear();
		for (VirtualItem item : fItems.values()) {
			item.dispose();
		}
		fItems.clear();
	}
	/**
	 * Returns the parent item.
	 * @return parent item.
	 */
	public VirtualItem getParent() {
		return fParent;
	}

	/**
	 * @return Returns the index of this item.
	 */
	public Index getIndex() {
		return fIndex;
	}

	/**
	 * Finds the given item in the child items of this element.
	 * @param element Data object of the item to be found.
	 * @return Item if found, <code>null</code> if not.
	 */
	public VirtualItem findItem(Object element) {
		for (VirtualItem item : fItems.values()) {
			Object nextData = item.getData();
			if ( (element != null && element.equals(nextData)) || (element == null && nextData == null) ) {
				return item;
			}
		}
		return null;
	}

	/**
	 * @return Returns whether the data element of this item is stale.
	 */
	public boolean needsDataUpdate() {
		return fNeedsDataUpdate;
	}

	/**
	 * Marks the item as having a stale data item.
	 */
	public void setNeedsDataUpdate() {
		fNeedsDataUpdate = true;
	}

	/**
	 * Clears the stale status of the item's data element.
	 */
	public void clearNeedsDataUpdate() {
		fNeedsDataUpdate = false;
	}

	/**
	 * @return Returns whether the item has stale item count.
	 */
	public boolean needsCountUpdate() {
		return fNeedsCountUpdate;
	}

	/**
	 * Marks the item as having a stale child count.
	 */
	public void setNeedsCountUpdate() {
		fNeedsCountUpdate = true;
		fItemCount = -1;
	}

	/**
	 * Clears the stale status of the item's child count.
	 */
	public void clearNeedsCountUpdate() {
		fNeedsCountUpdate = false;
	}

	/**
	 * @return Returns whether the item has stale label.
	 */
	public boolean needsLabelUpdate() {
		return fNeedsLabelUpdate;
	}

	/**
	 * Marks the item as having a stale label data.
	 */
	public void setNeedsLabelUpdate() {
		fNeedsLabelUpdate = true;
	}

	/**
	 * Clears the stale status of the item's label.
	 */
	public void clearNeedsLabelUpdate() {
		fNeedsLabelUpdate = false;
	}

	/**
	 * @return Returns whether the item has been disposed.
	 */
	public boolean isDisposed() {
		return fDisposed;
	}

	/**
	 * Disposes the item.
	 */
	public void dispose() {
		clearAll();

		fDisposed = true;
		findTree().fireItemDisposed(this);
	}

	/**
	 * @param key Key to retrieve data for.
	 * @return Returns item data corresponding to given key.
	 */
	public Object getData (String key) {
		return fData.get(key);
	}

	/**
	 * Sets given data element for given key.
	 * @param key Key for data.
	 * @param data Data value.
	 */
	public void setData(String key, Object data) {
		fData.put(key, data);
	}

	/**
	 * Sets the item's data element.
	 * @param data Item's new element.
	 */
	public void setData(Object data) {
		fData.put(ELEMENT_DATA_KEY, data);
	}

	/**
	 * @return Returns item's data element.
	 */
	public Object getData () {
		return fData.get(ELEMENT_DATA_KEY);
	}

	/**
	 * Marks the given item as expanded or collapsed.
	 * @param expanded If true, item will be marked as expanded.
	 */
	public void setExpanded(boolean expanded) {
		if (fExpanded == expanded) {
			return;
		}
		fExpanded = expanded;

		if (fExpanded && getItemCount() == -1) {
			setNeedsCountUpdate();
		}


		Assert.isTrue(!fExpanded || hasItems());

		// If collapsed, make sure that all the children are collapsed as well.
		if (!fExpanded) {
			for (VirtualItem item : fItems.values()) {
				item.setExpanded(expanded);
			}
		}
	}

	/**
	 * @return Returns item's expanded state.
	 */
	public boolean getExpanded() {
		return fExpanded;
	}

	/**
	 * Sets the flag indicating whether item has child items.
	 * @param hasChildren Set to true if child has items.
	 */
	public void setHasItems(boolean hasChildren) {
		fHasItems = hasChildren;
		if (!fHasItems) {
			if (getItemCount() != 0) {
				setItemCount(0);
			}
		} else if (getItemCount() == 0) {
			setItemCount(-1);
		}
	}

	/**
	 * @return Returns true if item has child items.
	 */
	public boolean hasItems() {
		return fHasItems;
	}

	/**
	 * Sets the item's child count.
	 * @param count Child count.
	 */
	public void setItemCount(int count) {
		fItemCount = count;
		for (Iterator<Entry<Index, VirtualItem>> itr = fItems.entrySet().iterator(); itr.hasNext();) {
			Entry<Index, VirtualItem> entry = itr.next();
			int index = entry.getKey().intValue();
			if (index >= count) {
				VirtualItem item = entry.getValue();
				item.dispose();
				itr.remove();
			}
		}
		if (fItemCount == 0) {
			if (hasItems()) {
				setHasItems(false);
			}
			if (getExpanded()) {
				setExpanded(false);
			}
		} else {
			if (!hasItems()) {
				setHasItems(true);
			}
		}
	}

	/**
	 * @return  Returns item's child count.
	 */
	public int getItemCount() {
		return fItemCount;
	}

	/**
	 * Returns the child item at given index.  Child item is created if needed.
	 *
	 * @param index Index of the child item.
	 * @return Child item.
	 */
	public VirtualItem getItem(Index index) {
		ensureItems();

		VirtualItem item = fItems.get(index);
		if (item == null) {
			item = new VirtualItem(this, index);
			fItems.put(index, item);
		}
		return item;
	}

	/**
	 * @return Returns true if any of the child items need a data update.
	 */
	public boolean childrenNeedDataUpdate() {
		if (getItemCount() == 0) {
			return false;
		}
		if (fItems == null || fItems.size() != fItemCount) {
			return true;
		}
		for (VirtualItem child : fItems.values()) {
			if (child.needsDataUpdate()) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Returns an array of current child items.  The returned array contains
	 * only the items that have been created.  It may not contain as many items as the
	 * item count.
	 *
	 * @return Child items array.
	 */
	public VirtualItem[] getItems() {
		return fItems.values().toArray(new VirtualItem[fItems.size()]);
	}

	/**
	 * Adds a child item at the given index position.
	 * @param position The index position to inser the new item at.
	 * @return Returns the added item.
	 */
	public VirtualItem addItem(int position) {
		if (!fHasItems) {
			fHasItems = true;
		}
		if (fItemCount < 0) {
			fItemCount = 0;
		}

		// Increment all items with an index higher than the given position.
		fItemCount++;
		ensureItems();
		for (Index childIndex : fItems.keySet()) {
			if (childIndex.intValue() >= position) {
				childIndex.increment();
			}
		}

		// Note: the same index object used to create the item has to
		// be used as the key into the map.
		Index childIndex = new Index(position);
		VirtualItem newChild = new VirtualItem(this, childIndex);
		fItems.put(childIndex, newChild);
		return newChild;
	}

	/**
	 * Removes the item at the given index.
	 * @param position Index of the item to remove.
	 */
	public void remove(Index position) {
		fItemCount--;
		if (fItemCount < 0) {
			fHasItems = false;
		}

		ensureItems();

		VirtualItem removedItem = null;
		for (Iterator<Entry<Index, VirtualItem>> itr = fItems.entrySet().iterator(); itr.hasNext();) {
			Entry<Index, VirtualItem> entry = itr.next();
			Index childIndex = entry.getKey();
			if (childIndex.intValue() > position.intValue()) {
				childIndex.decrement();
			} else if (childIndex.intValue() == position.intValue()) {
				removedItem = entry.getValue();
				removedItem.dispose();
				itr.remove();
			}
		}
	}

	private void ensureItems() {
		if (fItems == null) {
			fItems = new HashMap<>(Math.max(1, Math.min(fItemCount, 16)));
		}
	}

	private VirtualTree findTree() {
		VirtualItem item = this;
		while (!(item instanceof VirtualTree)) {
			item = item.fParent;
		}
		return (VirtualTree)item;
	}

	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		toStringItem(buffer, IInternalDebugCoreConstants.EMPTY_STRING);
		return buffer.toString();
	}

	void toStringItem(StringBuffer buffer, String indent) {
		buffer.append(indent);
		buffer.append(toStringElement());
		buffer.append("\n"); //$NON-NLS-1$
		indent = indent + "  "; //$NON-NLS-1$
		for (int i = 0; i < fItemCount; i++) {
			VirtualItem item = fItems.get(new Index(i));
			if (item != null) {
				item.toStringItem(buffer, indent);
			} else {
				buffer.append("<no item>\n"); //$NON-NLS-1$
			}
		}
	}

	private String toStringElement() {
		String[] label = (String[])fData.get(LABEL_KEY);
		if (label != null && label.length != 0) {
			return label[0];
		}
		Object data = fData.get(ELEMENT_DATA_KEY);
		if (data != null) {
			return data.toString();
		}
		return "<no data>"; //$NON-NLS-1$
	}
}
