/**Questa libreria necessita delle librerie
 *	util.js
 */
 
/**La classe AZArray rappresenta un'array di dimensione e
 * indice base variabili.
 */

/**Aggiunge l'elemento value nella posizione iPosition,
 * allungando l'array di una unità e mantenedo invariata
 * la base dell'array.
 * Se iPosition <= baseIndex l'elemento è aggiunto
 * all'inizio, se iPosition >= baseIndex + length,
 * l'elemento è aggiunto alla fine, altrimenti in mezzo.
 * @param value valore da inserire
 * @param iPosition (default baseIndex + length)
 * posizione di inserimento
 */
function AZArray_addElementAt(value, iPosition)
{
	if (isUndefined(iPosition))
		iPosition = this.baseIndex + this.length;
	iPosition = Math.max(iPosition, this.baseIndex);
	for (var i = this.baseIndex + this.length; i > iPosition; i--)
		this[i] = this[i - 1];
	this[i] = value;
	this.length++;
}

/**Elimina l'elemento value nella posizione iPosition,
 * accorciando l'array di una unità e mantenedo invariata
 * la base dell'array.
 * Se iPosition <= baseIndex l'elemento tolto
 * è il primo, se iPosition >= baseIndex + length - 1,
 * l'elemento tolto è l'ultimo, altrimenti in mezzo.
 * @param iPosition (default baseIndex + length - 1)
 * posizione dell'elemento da eliminare
 */
function AZArray_deleteElementAt(iPosition)
{
	if (isUndefined(iPosition))
		iPosition = this.baseIndex + this.length - 1;
	iPosition = Math.max(iPosition, this.baseIndex);
	this.length--;
	for (var i = iPosition; i < this.baseIndex + this.length; i++)
		this[i] = this[i + 1];
}

/**Trova l'indice della prima occorrenza di value
 * dalla posizione iFromIndex o dopo.
 * @param value valore da cercare
 * @param iFromIndex (default baseIndex) indice iniziale
 * da cui cercare
 * @return posizione di value nell'array, se trovato,
 * baseIndex - 1 se non trovato (== -1 se l'array è 0-based)
 */
function AZArray_indexOf(value, iFromIndex)
{
	if (isUndefined(iFromIndex))
		iFromIndex = this.baseIndex;
	var i = Math.max(iFromIndex, this.baseIndex);
	while (i < this.baseIndex + this.length)
	{
		if (this[i] == value)
			return i;
		i++;
	}
	return this.baseIndex - 1;
}

/**Trova l'indice dell'ultima occorrenza di value
 * dalla posizione iFromIndex o prima.
 * @param value valore da cercare
 * @param iFromIndex (default baseIndex + length - 1)
 * indice finale da cui cercare
 * @return posizione di value nell'array, se trovato,
 * baseIndex - 1 se non trovato (== -1 se l'array è 0-based)
 */
function AZArray_lastIndexOf(value, iFromIndex)
{
	if (isUndefined(iFromIndex))
		iFromIndex = this.baseIndex + this.length - 1;
	var i = Math.min(iFromIndex, this.baseIndex + this.length - 1);
	while (i >= this.baseIndex)
	{
		if (this[i] == value)
			return i;
		i--;
	}
	return this.baseIndex - 1;
}

/**Fornisce una copia esatta dell'array
 * @return il clone
 */
function AZArray_clone()
{
	var aRes = new AZArray(this.length, this.baseIndex, "");
	for (var i = this.baseIndex; i < this.baseIndex + this.length; i++)
		aRes[i] = this[i];
	return aRes;
}

/**Ridimensiona l'array
 * @param iLength (default 0) nuova dimensione
 * @param initValue (default undefined value) elementi
 * da inserire se l'array si allunga
 */
function AZArray_resizeTo(iLength, initValue)
{
	if (isUndefined(iLength))
		iLength = 0;
	for (var i = this.baseIndex + this.length;
			i < this.baseIndex + iLength; i++)
		this[i] = initValue;
	this.length = iLength;
}

/**Cambia la base dell'array
 * @param iBaseIndex (default 0) nuova base dell'array
 */
function AZArray_changeBaseIndex(iBaseIndex)
{
	if (isUndefined(iBaseIndex))
		iBaseIndex = 0;
	if (iBaseIndex <= this.baseIndex)
		for (var i = 0; i < this.length; i++)
			this[iBaseIndex + i] = this[this.baseIndex + i];
	else
		for (var i = this.length - 1; i >= 0; i--)
			this[iBaseIndex + i] = this[this.baseIndex + i];
	this.baseIndex = iBaseIndex;
}

function AZArray_toString()
{
	sRes = "baseIndex=" + this.baseIndex
			+"\nlength=" + this.length;
	for (var i = this.baseIndex; i < this.baseIndex + this.length; i++)
		sRes += "\n[" + i + "]=" + this[i];
	return sRes;
}

/**Costruttore della classe AZArray
 * @param iLength (default 0): dimensione dell'array
 * @param iBaseIndex (default 0): base per l'indice dell'array
 * @param initValue (default undefined value):
 * valore iniziale degli elementi dell'array
 */
function AZArray(iLength, iBaseIndex, initValue)
{
	if (isUndefined(iBaseIndex))
		iBaseIndex = 0;
	if (isUndefined(iLength))
		iLength = 0;
	
	this.length = iLength;
	this.baseIndex = iBaseIndex;
	for (var i = iBaseIndex; i < iBaseIndex + iLength; i++)
		this[i] = initValue;
	
	this.addElementAt		= AZArray_addElementAt;
	this.deleteElementAt	= AZArray_deleteElementAt;
	this.indexOf			= AZArray_indexOf;
	this.lastIndexOf		= AZArray_lastIndexOf;
	this.clone				= AZArray_clone;
	this.resizeTo			= AZArray_resizeTo;
	this.changeBaseIndex	= AZArray_changeBaseIndex;
	this.toString			= AZArray_toString;
	
	return this;
}

