var HeightAnimator = new function()
{
	this._animatorRunning = false;
	this._objHide = [];
	this._objShow = [];
	this._aniElmnts = [];
	this._aniHeightsMin = [];
	this._aniHeightsMax = [];
	this._callBack = [];

	this.AddElement = function(elmnt, min, max, callback)
	{
		if (!this._animatorRunning)
		{
			this._animatorRunning = true;
//			alert("Starting Animator!");
			setInterval(HeightAnimator.Animator, 10);
		}
		var id = this.FindAniId(elmnt);
		if (id == -1)	// If not exists, add new element
		{
			this._aniElmnts.push(elmnt);
			this._aniHeightsMin.push(min);
			this._aniHeightsMax.push(max);
			this._callBack.push(callback);
		}
		else	// If exists, update existing element
		{
			this._aniHeightsMin[id] = min;
			this._aniHeightsMax[id] = max;
			this._callBack[id] = callback;
		}
//		alert("done"+this._aniElmnts.length);
	}

	this.ShowElement = function(elmnt, instant)
	{
		for (var i = 0; i < this._objHide.length; ++i)
		{
			if (this._objHide[i] == elmnt)
			{
				this._objHide.splice(i, 1);
				break;
			}
		}
		if (instant)
		{
			elmnt.style.height = this.FindMaxHeight(elmnt) + "px";
			var func = HeightAnimator._callBack[HeightAnimator.FindAniId(elmnt)];
			if (func)
			{
				func(elmnt, ["max"]);
			}
		}
		else
		{
			this._objShow.push(elmnt);
		}
	}

	this.HideElement = function(elmnt, instant)
	{
		for (var i = 0; i < this._objShow.length; ++i)
		{
			if (this._objShow[i] == elmnt)
			{
				this._objShow.splice(i, 1);
				break;
			}
		}
		if (instant)
		{
			elmnt.style.height = this.FindMinHeight(elmnt) + "px";
			var func = HeightAnimator._callBack[HeightAnimator.FindAniId(elmnt)];
			if (func)
			{
				func(elmnt, ["min"]);
			}
		}
		else
		{
			this._objHide.push(elmnt);
		}
	}

	this.FindAniId = function(elmnt)
	{
		for (var i = 0; i < this._aniElmnts.length; ++i)
		{
			if (this._aniElmnts[i] == elmnt)
			{
				return i;
			}
		}
		return -1;
	}

	this.FindMaxHeight = function(elmnt)
	{
		var id = this.FindAniId(elmnt)
		if (id != -1)
		{
			return this._aniHeightsMax[id];
		}
		return -1;
	}
	
	this.FindMinHeight = function(elmnt)
	{
		var id = this.FindAniId(elmnt)
		if (id != -1)
		{
			return this._aniHeightsMin[id];
		}
		return -1;
	}

	this.Animator = function()
	{
		for (var i = 0; i < HeightAnimator._objHide.length; ++i)
		{
			var elmnt = HeightAnimator._objHide[i];
			var targetHeight = HeightAnimator.FindMinHeight(elmnt);
			if (elmnt.offsetHeight > targetHeight)
			{
				elmnt.style.height = elmnt.offsetHeight - Math.ceil((elmnt.offsetHeight - targetHeight) / 10) + "px";
			}
			else
			{
				HeightAnimator._objHide.splice(i, 1);
				var func = HeightAnimator._callBack[HeightAnimator.FindAniId(elmnt)];
				if (func)
				{
					func(elmnt, ["min"]);
				}
			}
		}
	
		for (var i = 0; i < HeightAnimator._objShow.length; ++i)
		{
			var elmnt = HeightAnimator._objShow[i];
			var targetHeight = HeightAnimator.FindMaxHeight(elmnt);
			if (elmnt.offsetHeight < targetHeight)
			{
				elmnt.style.height = elmnt.offsetHeight + Math.ceil((targetHeight - elmnt.offsetHeight) / 10) + "px";
			}
			else
			{
				HeightAnimator._objShow.splice(i, 1);
				var func = HeightAnimator._callBack[HeightAnimator.FindAniId(elmnt)];
				if (func)
				{
					func(elmnt, ["max"]);
				}
			}
		}
	}
}

