package projectzombie.util.math.map;

import java.util.ArrayList;
import java.util.Iterator;

import gl_engine.vec.Vec2i;

public class Map2D<T> implements Iterable<Map2DElement<T>>
{
	private ArrayList<Map2DElement<T>> elements;
	private Map2DElement<T> element_last = null;
	private IMap2D<T> map2d_i;
	
	public Map2D(IMap2D<T> map2d_i)
	{
		// Store some values
		this.map2d_i = map2d_i;
		this.elements = new ArrayList<Map2DElement<T>>();
	}
	
	public void set(Vec2i pos, T o)
	{
		if(element_last != null) {
			if(element_last.pos.equal(pos)) {
				element_last.o = o;
				return;
			}
		}
		
		// Loop over the elements
		for(Map2DElement<T> e : this.elements)
		{
			// Set the object if these positions are the same
			if(e.pos.equal(pos)) {
				element_last = e;
				e.o = o;
				return;
			}
		}
		
		// Create an element and add it
		Map2DElement<T> e = new Map2DElement<T>(pos, o);
		this.elements.add(e);
		element_last = e;
	}
	
	public T get(Vec2i pos)
	{
		if(element_last != null) {
			if(element_last.pos.equal(pos)) {
				return element_last.o;
			}
		}
		
		// Loop over the elements
		for(int i=0;i<this.elements.size();i++)
		{
			Map2DElement<T> e = this.elements.get(i);
			
			if(e == null) {
				continue;
			}
			
			// Send back the object if these positions are the same
			if(e.pos.equal(pos)) {
				element_last = e;
				return e.o;
			}
		}
		
		// Send back an empty object
		return this.map2d_i.getEmpty(pos);
	}
	
	public void remove(Vec2i pos)
	{
		if(element_last != null) {
			if(element_last.pos.equal(pos)) {
				this.elements.remove(element_last);
			}
		}
		
		// Loop over the elements
		for(int i=0;i<elements.size();i++)
		{
			// Get the element
			Map2DElement<T> e = this.elements.get(i);
			
			// Delete the item if the position is the same
			if(e.pos.equal(pos)) {
				this.elements.remove(e);
			}
		}
		
		element_last = null;
	}
	
	public boolean contains(Vec2i pos)
	{
		if(element_last != null) {
			if(element_last.pos.equal(pos)) {
				return true;
			}
		}
		
		// Loop over the elements
		for(int i=0;i<elements.size();i++)
		{
			// Get the element
			Map2DElement<T> e = this.elements.get(i);
			
			// Return true if the position is the same
			if(e.pos.equal(pos)) {
				return true;
			}
		}
		
		// Return false if nothing was found
		return false;
	}
	
	public int size() {
		return elements.size();
	}

	@Override
	public Iterator<Map2DElement<T>> iterator() {
		return new Iterator<Map2DElement<T>>()
		{
			private int i = 0;

			@Override
			public boolean hasNext() {
				return i < elements.size();
			}

			@Override
			public Map2DElement<T> next() {
				Map2DElement<T> o = elements.get(i);
				i++;
				return o;
			}
			
		};
	}
}
