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

import java.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 comp) {
		fHolder = holder;
		fSet = new SortedSet(holder, comp);
	}
	
	public SortedMap(Comparator 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 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 {
		private int fIndex;
		
		public ArrayIterator() {
			fIndex = -1;
		}
		/**
		 * @see java.util.Iterator#hasNext()
		 */
		public boolean hasNext() {
			Object[] array = SortedMap.this.fHolder.getKeys();
			if (array == null)
				return false;
			return fIndex + 1 < array.length;
		}

		/**
		 * @see java.util.Iterator#next()
		 */
		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()
		 */
		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 String[]{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);
	}
	
	public FactoryObject next() {
		return fNext;
	}
	
	public void next(FactoryObject next) {
		fNext = (SortedMap) next;
	}
}
