/*******************************************************************************
 * Copyright (c) 2002, 2013 Object Factory Inc.
 *
 * 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:
 *		Object Factory Inc. - Initial implementation
 *******************************************************************************/
package org.eclipse.ant.internal.ui.dtd.util;

import com.ibm.icu.text.MessageFormat;
import java.util.Comparator;
import java.util.Iterator;

/**
 * @author Bob Foster
 */
public class SortedMap implements FactoryObject {

	private SortedSet fSet;
	private IMapHolder fHolder;
	private SortedMap fNext;

	public SortedMap(IMapHolder holder, Comparator<Object> comp) {
		fHolder = holder;
		fSet = new SortedSet(holder, comp);
	}

	public SortedMap(Comparator<Object> comp) {
		fSet = new SortedSet(comp);
	}

	public SortedMap(IMapHolder holder) {
		fHolder = holder;
		fSet = new SortedSet(holder);
	}

	public SortedMap() {
		fSet = new SortedSet();
	}

	public void setMapHolder(IMapHolder holder) {
		fHolder = holder;
		fSet.setKeyHolder(holder);
	}

	public void setComparator(Comparator<Object> comp) {
		fSet.setComparator(comp);
	}

	public boolean containsKey(Object key) {
		return fSet.contains(key);
	}

	public boolean containsKeyIdentity(Object key) {
		return fSet.containsIdentity(key);
	}

	public Object put(Object key, Object val) {
		Object[] values = fHolder.getValues();
		int index = fSet.indexOf(key);
		Object result = index >= 0 && values != null ? values[index] : null;

		int i = fSet.internalAdd(key, false);
		if (i >= 0)
			internalPut(i, val);
		return result;
	}

	protected void internalPut(int i, Object val) {
		Object[] values = fHolder.getValues();
		if (values == null) {
			values = new Object[1];
			values[0] = val;
			return;
		}

		Object[] tmp = new Object[values.length + 1];
		System.arraycopy(values, 0, tmp, 0, i);
		tmp[i] = val;
		System.arraycopy(values, i, tmp, i + 1, values.length - i);
		fHolder.setValues(tmp);
	}

	public int putAlways(Object key, Object val) {
		int i = fSet.internalAdd(key, true);
		internalPut(i, val);
		return i;
	}

	public void append(Object key, Object val) {
		Object[] values = fHolder.getValues();
		int len = values != null ? values.length : 0;
		fSet.internalAdd(len, key);
		internalPut(len, val);
	}

	public Object get(Object key) {
		Object[] values = fHolder.getValues();
		if (values == null)
			return null;
		int i = fSet.indexOf(key);
		if (i >= 0)
			return values[i];
		return null;
	}

	public Object getIdentity(Object key) {
		Object[] values = fHolder.getValues();
		if (values == null)
			return null;
		int i = fSet.indexOfIdentity(key);
		if (i >= 0)
			return values[i];
		return null;
	}

	public Object[] keys() {
		return fSet.members();
	}

	public Object[] values() {
		Object[] values = fHolder.getValues();
		if (values == null)
			return new Object[0];
		return values;
	}

	public Iterator<?> keyIterator() {
		return new ArrayIterator();
	}

	public Iterator<?> valueIterator() {
		return new ArrayIterator();
	}

	private class ArrayIterator implements Iterator<Object> {
		private int fIndex;

		public ArrayIterator() {
			fIndex = -1;
		}

		/**
		 * @see java.util.Iterator#hasNext()
		 */
		@Override
		public boolean hasNext() {
			Object[] array = SortedMap.this.fHolder.getKeys();
			if (array == null)
				return false;
			return fIndex + 1 < array.length;
		}

		/**
		 * @see java.util.Iterator#next()
		 */
		@Override
		public Object next() {
			Object[] array = SortedMap.this.fHolder.getKeys();
			if (array == null)
				throw new IllegalStateException(AntDTDUtilMessages.SortedMap_next___called_for_empty_array_1);
			return array[++fIndex];
		}

		/**
		 * @see java.util.Iterator#remove()
		 */
		@Override
		public void remove() {
			SortedMap.this.remove(fIndex);
			--fIndex;
		}

	}

	public void remove(int i) {
		Object[] values = fHolder.getValues();
		if (values == null) {
			throw new IllegalArgumentException(MessageFormat.format(AntDTDUtilMessages.SortedMap_remove__0___in_empty_map_2, new Object[] { Integer.toString(i) }));
		}
		fSet.remove(i);
		Object[] tmp = new Object[values.length - 1];
		System.arraycopy(values, 0, tmp, 0, i);
		System.arraycopy(values, i + 1, tmp, i, values.length - i - 1);
		fHolder.setValues(tmp);
	}

	public Object remove(Object obj) {
		Object[] values = fHolder.getValues();
		if (values == null)
			return null;
		int i = fSet.indexOf(obj);
		if (i >= 0) {
			Object tmp = values[i];
			fSet.remove(i);
			remove(i);
			return tmp;
		}
		return null;
	}

	public Object removeIdentity(Object obj) {
		Object[] values = fHolder.getValues();
		if (values == null)
			return null;
		int i = fSet.indexOfIdentity(obj);
		if (i >= 0) {
			Object tmp = values[i];
			fSet.remove(i);
			remove(i);
			return tmp;
		}
		return null;
	}

	public int size() {
		return fSet.size();
	}

	public int keyIndex(Object key) {
		return fSet.indexOf(key);
	}

	public void merge(SortedMap other) {
		Object[] values = fHolder.getValues();
		Object[] keys = fHolder.getKeys();
		Object[] othervalues = other.fHolder.getValues();
		Object[] otherkeys = other.fHolder.getKeys();
		if (otherkeys == null)
			return;
		if (keys == null) {
			fHolder.setKeys(otherkeys);
			fHolder.setValues(othervalues);
			return;
		}
		int ithis = 0, iother = 0, i = 0;
		int mthis = keys.length, mother = otherkeys.length;
		Object[] ktmp = new Object[mthis + mother];
		Object[] vtmp = new Object[mthis + mother];
		while (ithis < mthis && iother < mother) {
			int comp = fSet.fComp.compare(keys[ithis], otherkeys[iother]);
			if (comp <= 0) {
				vtmp[i] = values[ithis];
				ktmp[i++] = keys[ithis++];
			} else {
				vtmp[i] = othervalues[iother];
				ktmp[i++] = otherkeys[iother++];
			}
		}
		while (ithis < mthis) {
			vtmp[i] = values[ithis];
			ktmp[i++] = keys[ithis++];
		}
		while (iother < mother) {
			vtmp[i] = othervalues[iother];
			ktmp[i++] = otherkeys[iother++];
		}
		fHolder.setKeys(ktmp);
		fHolder.setValues(vtmp);
	}

	@Override
	public FactoryObject next() {
		return fNext;
	}

	@Override
	public void next(FactoryObject next) {
		fNext = (SortedMap) next;
	}
}
