/*
	Элемент
*/
function CElem( aParent)
{
	this.parent = aParent;
}

// типы элементов
CElem.prototype.ELTYPE_WORD 		= 1; // слово
CElem.prototype.ELTYPE_SPACE		= 2; // разделитель - пробел
CElem.prototype.ELTYPE_LINE 		= 3; // перевод строки
CElem.prototype.ELTYPE_SPLIT 		= 4; // разделитель дилнного слова на два слова (строки)
CElem.prototype.ELTYPE_PARA 		= 5; // элемент начало абзаца, когда абзац не содержит элементов

CElem.prototype.parent		= null;
CElem.prototype.oText		= null;
CElem.prototype.type		= null;
CElem.prototype.value		= null;
CElem.prototype.id			= 0;
CElem.prototype.x			= 0;
CElem.prototype.y			= 0;


CElem.prototype.clear = function()
{
	if ( this.oText != null)
	{
		this.oText.parent = null;
		this.oText = null;
	}
	this.parent = null;
}

CElem.prototype.createText = function()
{
	if ( this.oText == null)
	{
		this.oText			= new Text();
		this.oText.name		= "o" + this.id;
		this.oText.style	= this.parent.stlChemElem;
		this.oText.parent	= this.parent;
		this.oText.x		= this.x;
		this.oText.y		= this.y;
		this.oText.id		= this.id;
	}
}


//
CElem.prototype.setValue = function( aValue)
{
	if ( this.type == this.ELTYPE_WORD)
	{
		this.createText();
		this.oText.value = aValue;
	}
	this.value = aValue;
}

CElem.prototype.getValue = function()
{
	return this.value;
}

CElem.prototype.getSValue = function()
{
	if ( this.type == this.ELTYPE_SPACE)
	{
		var s = " ";
		for ( var i = 1; i < this.value; i++)
			s += " ";
		return s;
	}

	if ( this.value == null)
		return String.fromCharCode( 29);

	return this.value;
}

CElem.prototype.getCount = function()
{
	if ( this.type == this.ELTYPE_WORD)
		return this.value.length;
	if ( this.type == this.ELTYPE_SPACE)
		return this.value;
	if ( this.type == this.ELTYPE_PARA)
		return 0;
	return -1;
}

// функция работает также как substr для строк
CElem.prototype.subValue = function( pos, len)
{
	if ( this.type == this.ELTYPE_WORD)
		return this.value.substr( pos, len);
	if ( this.type == this.ELTYPE_SPACE)
	{
		if ( len > this.value)
			len = this.value;
		return len - pos;
	}
	return null;
}

// вставляет в определенную позицию слова указанный символ или инкримент
CElem.prototype.insertAt = function( pos, charCode)
{
	if ( this.type == this.ELTYPE_WORD)
	{
		if ( pos == 0)
			this.setValue( String.fromCharCode( charCode) + this.value);
		else if ( pos == this.getCount())
			this.setValue( this.value + String.fromCharCode( charCode));
		else
			this.setValue( this.value.substr( 0, pos) + String.fromCharCode( charCode) + this.value.substr( pos, this.value.length - pos));
	}
	else if ( this.type == this.ELTYPE_SPACE)
		this.value++;
}

//
CElem.prototype.getFirstChar = function()
{
	if ( this.type == this.ELTYPE_WORD)
		return this.value[ 0];
	return null;
}

//
CElem.prototype.getLastChar = function()
{
	if ( this.type == this.ELTYPE_WORD)
		return this.value[ this.value.length - 1];
	return null;
}

// добавляет символ к слову в конец или инкремент для пробелов
CElem.prototype.addChar = function( ch)
{
	if ( this.type == this.ELTYPE_WORD)
		this.setValue( this.getValue() + ch);
	else if ( this.type == this.ELTYPE_SPACE)
		this.value += 1;
	return null;
}

// добавляет последовательностьс символов к слову или инкремент для пробелов
CElem.prototype.addValue = function( aValue)
{
	if ( this.type == this.ELTYPE_WORD)
		this.setValue( this.getValue() + aValue);
	else if ( this.type == this.ELTYPE_SPACE)
		this.value += aValue;
	return null;
}

// удалить первый символ для слова или декремент для пробелов
CElem.prototype.removeFirstChar = function()
{
	this.setValue( this.subValue( 1, this.getCount() - 1));
	return null;
}

// удалить последный символ для слова или декремент для пробелов
CElem.prototype.removeLastChar = function()
{
	this.setValue( this.subValue( 0, this.getCount() - 1));
	return null;
}

// удалить последный символ для слова или декремент для пробелов
CElem.prototype.removeChar = function( pos)
{
	if ( this.type == this.ELTYPE_WORD)
	{
		var len = this.getCount();
		if ( len > 0)
		{
			var val = this.subValue( 0, pos) + this.subValue( pos + 1, len - pos - 1);
			this.setValue( val);
		}
	}
	else if ( this.type == this.ELTYPE_SPACE)
		if ( this.value > 0)
			this.value--;
	return null;
}

//
CElem.prototype.getWidth = function()
{
	if ( this.type == this.ELTYPE_WORD)
	{
		if ( this.oText != null)
			return this.oText.getMediaSize().width;
		return 0;
	}

	if ( this.type == this.ELTYPE_SPACE)
		return this.value * this.parent.orderSpacingX;

	if ( this.type == this.ELTYPE_PARA)
		return 0;
	return 0;
}

//
CElem.prototype.setX = function( aX)
{
	this.x = aX;
	if ( this.type == this.ELTYPE_WORD)
		if ( this.oText != null)
			this.oText.x = aX;
}

CElem.prototype.setY = function( aY)
{
	this.y = aY;
	if ( this.type == this.ELTYPE_WORD)
		if ( this.oText != null)
			this.oText.y = aY;
}

CElem.prototype.getX = function()
{
	return this.x;
}

CElem.prototype.getY = function()
{
	return this.y;
}

CElem.prototype.getHeight = function()
{
	if ( this.type == this.ELTYPE_WORD)
		if ( this.oText != null)
			return this.oText.style.fontSize;
	return null;
}

CElem.prototype.getCursorPos = function( iCursorPos)
{
	if ( iCursorPos < 0)
	{
		trace( "#aa0000 CElem::getCursorPos::ERROR iCursorPos = " + iCursorPos);
		return iCursorPos;
	}
	if ( this.type == this.ELTYPE_WORD)
	{
		if ( this.oText != null)
		{
			this.parent.txtCursorPos.value = this.subValue( 0, iCursorPos);
			var aWidth = this.parent.txtCursorPos.getMediaSize().width;
			var posX = this.x + aWidth;
			return posX;
		}
		trace( "#aa0000 CElem::getCursorPos::ERROR this.oText is null");
		return -1;
	}
	if ( this.type == this.ELTYPE_SPACE)
	{
		if ( iCursorPos > this.value)
		{
			trace( "#aa0000 CElem::getCursorPos::ERROR iCursorPos = " + iCursorPos + " > this.value = " + this.value);
			iCursorPos = this.value;
		}
		return this.x + iCursorPos * this.parent.orderSpacingX;
	}

	if ( this.type == this.ELTYPE_LINE || this.type == this.ELTYPE_SPLIT)
		return this.x;

	if ( this.type == this.ELTYPE_PARA)
		return 0;
}

CElem.prototype.getCursorElementNumber = function( posX, bLeft)
{
	posX -= this.getX();
	var count = this.getCount();
	if ( this.type == this.ELTYPE_WORD)
	{
		if ( this.oText == null)
		{
			trace( "#aa0000 CElem::getCursorElementNumber::ERROR this.oText is null");
			return -1;
		}
	}

	if ( posX <= 0)
		return 0;

	var left	= 0;
	var right	= count;
	count = Math.ceil( count / 2);
	var aWidth = this.getTempWidth( count);
	while ( true)
	{
		//trace( "getCursorElementNumber::left = " + left);
		//trace( "getCursorElementNumber::right = " + right);
		//trace( "getCursorElementNumber::count = " + count);
		//trace( "getCursorElementNumber::aWidth = " + aWidth);
		if ( left >= right - 2)
		{
			break;
		}
		else if ( posX < aWidth)
		{
			if ( count <= left)
				return left;
			right = count;
			count -= Math.ceil(( count - left) / 2);
		}
		else if ( posX > aWidth)
		{
			if ( count >= right)
				return rigth;
			var count_ = count + Math.ceil(( right - count) / 2);
			if ( count_ == count)
				return count_;
			left = count;
			count = count_;
		}
		else
		{
			return count;
		}
		aWidth = this.getTempWidth( count);
	}

	for ( var i = left + 1; i <= right; i++)
	{
		if ( this.getTempWidth( i) > posX)
			return i - ( typeof( bLeft) != "undefined" && bLeft ? 1 : 0);
	}
	return i;
}

CElem.prototype.getTempWidth = function( iCursorPos)
{
	if ( this.type == this.ELTYPE_WORD)
	{
		this.parent.txtCursorPos.value = this.subValue( 0, iCursorPos);
		return this.parent.txtCursorPos.getMediaSize().width;
	}
	else if ( this.type == this.ELTYPE_SPACE)
	{
		if ( iCursorPos > this.value)
		{
			trace( "#aa0000 CElem::getTempWidth::ERROR iCursorPos = " + iCursorPos + " > this.value = " + this.value);
			iCursorPos = this.value;
		}
		return iCursorPos * this.parent.orderSpacingX;
	}
}

CElem.prototype.show = function()
{
	if ( this.type == this.ELTYPE_WORD)
	{
		if ( this.oText == null)
		{
			trace( "#aa0000 ERROR::CElem::getTempWidth::this.oText == null");
			return false;
		}
		this.oText.show();
	}
	return true;
}

CElem.prototype.hide = function()
{
	if ( this.type == this.ELTYPE_WORD)
	{
		if ( this.oText == null)
		{
			trace( "#aa0000 ERROR::CElem::getTempWidth::this.oText == null");
			return false;
		}
		this.oText.hide();
	}
	return true;
}