// array.js - CArray, CHash, CHashWithKeys classes

function CArray()
{
	this.Init = CArray_Init;
	this.Init();
}
function CArray_Init()
{
	this.Set = function ( objItem, nIndex)
	{
		if (nIndex < 0)
			nIndex = this.Count();
		this.m_arItems[nIndex] = objItem;
		return nIndex;
	}
	this.Add = function ( objItem)
	{
		return this.Set( objItem, -1);
	}
	this.Del = function ( nIndex)
	{
		var i;
		var nLast = this.Count() -1;
		for (i = nIndex; i < nLast; i++)
		{
			this.m_arItems[i] = this.m_arItems[i + 1];
		}
		if (nLast >= nIndex)
			this.m_arItems.pop();
			//delete this.m_arItems[ nLast];// = null;
	}
	this.DelPredicate = function( objPredicate)
	{
		var i;
		var nCount = this.Count();
		var nDelCount = 0;
		for ( i=0; i < nCount; i++)
		{
			if (objPredicate.Test( this.Item(i)))
			{
				nDelCount ++;
			}
			else
			{
				if (nDelCount > 0)
					this.m_arItems[i - nDelCount] = this.m_arItems[i];
			}
		}
		for ( i=0; i < nDelCount; i++)
			this.m_arItems.pop();
	}
	this.Item = function ( nIndex)
	{
		return this.m_arItems[nIndex];
	}
	this.Count = function ()
	{
		return this.m_arItems.length;
	}
	this.Pop = function()
	{
		return this.m_arItems.pop();
	}
	this.Push = function( objItem)
	{
		return this.Add( objItem);
	}
	this.Is = function()
	{
		return (this.Count() > 0);
	}
	this.CopyFrom = function( objOther)
	{
		var nCount = objOther.Count();
		for ( var i = 0; i < nCount; i++)
		{
			this.Add( objOther.Item(i));
		}
	}
	this.CopyNotNullFrom = function( objOther)
	{
		var nCount = objOther.Count();
		for ( var i = 0; i < nCount; i++)
		{
			var item = objOther.Item(i);
			if ( item != null)
				this.Add( item);
		}
	}
	this.CloneFrom = function( objOther)
	{
		var nCount = objOther.Count();
		for ( var i = 0; i < nCount; i++)
		{
			this.Add( objOther.Item(i).Clone());
		}
	}
	this.ArItems = function()
	{
		return this.m_arItems;
	}
	this.Clear = function()
	{
		this.m_arItems = new Array();
	}

	this.Clear();
}

function CHash_Init()
{
	this.Set = function ( nKey, objItem)
	{
		this.m_hash[nKey] = objItem;
	}
	this.Del = function ( nKey)
	{
		delete this.m_hash[nKey];
		//this.Set( nKey, null);
	}
	this.Item = function ( nKey)
	{
		var item = null;
		var e;
		try
		{
			item = this.m_hash[nKey];
		}
		catch ( e)
		{
		}
		return item;
	}
	this.Clear = function()
	{
		this.m_hash = new Array();
	}

	this.Clear();
}

function CHash()
{
	this.Init = CHash_Init;
	this.Init();
}

function CHashWithKeys()
{
	this.Set = function( key, value)
	{
		if ( this.m_hashKeyIndex.Item( key))
		{
		}
		else
		{
			this.m_arKey.Add( key);
			this.m_hashKeyIndex.Set( key, this.m_arKey.Count());
		}
		this.m_hashKeyValue.Set( key, value);
	}
	
	this.Del = function( key)
	{
		var nIncreasedNameIndex = this.m_hashKeyIndex.Item( key);
		if ( nIncreasedNameIndex)
		{
			this.m_arKey.Del( nIncreasedNameIndex -1);
			this.m_hashKeyIndex.Del( key);
			this.m_hashKeyValue.Del( key);
			var i = 0;
			for ( i = nIncreasedNameIndex -1; i < this.m_arKey.Count(); i++)
			{
				var strKey = this.m_arKey.Item( i);
				var nNewIndex = this.m_hashKeyIndex.Item( strKey) -1;
				this.m_hashKeyIndex.Set( strKey, nNewIndex);
			}
		}
	}

	this.Keys = function()
	{
		return this.m_arKey;
	}

	this.Item = function( key)
	{
		return this.m_hashKeyValue.Item( key);
	}

	this.Clear = CHashWithKeys;

	this.m_arKey = new CArray();
	this.m_hashKeyIndex = new CHash();
	this.m_hashKeyValue = new CHash();
}
