std::string TextDomArea::getHighlightedStringInternal(UInt32 lesserLine,UInt32 lesserIndex,UInt32 greaterLine,UInt32 greaterIndex)
{
	std::string firstLine="";
	std::string lastLine="";
	std::string intermediateLines="";
	PlainDocumentLeafElementRefPtr temp1 = dynamic_cast<PlainDocumentLeafElement*>(getLayoutManager()->getRootElement()->getElement(lesserLine));
	std::string temp2 = temp1->getText();
	if(lesserLine== greaterLine)
	{
		return temp2.substr(lesserIndex,greaterIndex-lesserIndex);
	}
	else
	{
		// get the first line 
		firstLine = temp2.substr(lesserIndex);

		// get the last line
		temp1 = dynamic_cast<PlainDocumentLeafElement*>(getLayoutManager()->getRootElement()->getElement(greaterLine));
		temp2 = temp1->getText();
		lastLine = temp2.substr(0,greaterIndex);
	}

	for(UInt32 i=lesserLine+1;i<greaterLine;i++)
	{
		PlainDocumentLeafElementRefPtr theElement = dynamic_cast<PlainDocumentLeafElement*>(getLayoutManager()->getRootElement()->getElement(i));
		intermediateLines+=theElement->getText();
	}

	return firstLine + intermediateLines + lastLine;
}
char FixedHeightLayoutManager::getNextCharacter(UInt32 _theOriginalCaretIndex,UInt32 _theOriginalCaretLine)
{
	PlainDocumentLeafElementRefPtr temp = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(_theOriginalCaretLine));
	if(temp->getTextLength()-2 == _theOriginalCaretIndex)
	{
		temp = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(_theOriginalCaretLine+1));
		std::string tempstring = temp->getText();
		return tempstring[0];
	}
	else
	{
		std::string tempstring = temp->getText();
		return tempstring[_theOriginalCaretIndex];
	}
	
}
void TextDomArea::drawHighlightBGInternal(Graphics * const TheGraphics, Real32 Opacity,UInt32 lesserLine,UInt32 lesserIndex,UInt32 greaterLine,UInt32 greaterIndex) const
{
	for(UInt32 i=lesserLine+1;i<greaterLine;i++)
	{
		PlainDocumentLeafElementRefPtr theElement = dynamic_cast<PlainDocumentLeafElement*>(getLayoutManager()->getRootElement()->getElement(i));
		
		if(theElement)
		{
			Pnt2f topLeft,bottomRight;
			getFont()->getBounds(theElement->getText(),topLeft,bottomRight);

			TheGraphics->drawRect(Pnt2f(getLayoutManager()->getGutterSpace() + getLayoutManager()->getGutterSeparation(),i*getLayoutManager()->getHeightOfLine()),Pnt2f(getLayoutManager()->getGutterSpace() + getLayoutManager()->getGutterSeparation()+ bottomRight.x(),(i+1)*getLayoutManager()->getHeightOfLine()),Color4f(0.7,0.7,0.95,1),Opacity);
		}
	}

	if(lesserLine== greaterLine)
	{
		TheGraphics->drawRect(getLayoutManager()->getXYPosition(lesserLine,lesserIndex,true),getLayoutManager()->getXYPosition(greaterLine,greaterIndex,false),Color4f(0.7,0.7,0.95,1),Opacity);
	}
	else
	{
		// draw the first line
		TheGraphics->drawRect(getLayoutManager()->getXYPosition(lesserLine,lesserIndex,true),getLayoutManager()->getEndXYPosition(lesserLine),Color4f(0.7,0.7,0.95,1),Opacity);

		// draw the last line
		TheGraphics->drawRect(getLayoutManager()->getStartXYPosition(greaterLine),getLayoutManager()->getXYPosition(greaterLine,greaterIndex,false),Color4f(0.7,0.7,0.95,1),Opacity);
	}

}
void FixedHeightLayoutManager::recalculateCaretPositions(void)
{
	// this function assumes that the caret index and line values are valid and computes the caret x and y positions directly
	_CaretYPosition = /*getParentTextDomArea()->getPosition().y() + */_CaretLine * heightOfLine;
	PlainDocumentLeafElementRefPtr theElement = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(_CaretLine));
	Pnt2f topLeft,bottomRight;
	std::string theSubstring = theElement->getText();
	theSubstring = theSubstring.substr(0,_CaretIndex);
	getParentTextDomArea()->getFont()->getBounds(theSubstring,topLeft,bottomRight);
	_CaretXPosition = _GutterSpace + _GutterSeparation + bottomRight.x();
}
UInt32 FixedHeightLayoutManager::getNumberOfLeadingSpaces(UInt32 line)
{
	if(line>=rootElement->getElementCount())return 0;
	UInt32 count = 0;
	PlainDocumentLeafElementRefPtr theElement = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(line));
	std::string theString = theElement->getText();
	
	for(UInt32 i=0;i<theString.size(),theString[i]==' ';i++)count++;
	
	return count;
}
void FixedHeightLayoutManager::DoIfLineLongerThanPreferredSize() const
{
	PlainDocumentLeafElementRefPtr temp = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(_CaretLine));

	Pnt2f topLeft,bottomRight;
	getParentTextDomArea()->getFont()->getBounds(temp->getText(),topLeft,bottomRight);
	
	Vec2f preferredSize = getParentTextDomArea()->getPreferredSize(); 

	if(bottomRight.x() > preferredSize.x())preferredSize.setValues(bottomRight.x(),preferredSize.y());
	
	getParentTextDomArea()->setPreferredSize(preferredSize);

}
Pnt2f FixedHeightLayoutManager::getEndXYPosition(UInt32 lineNumber) const
{
	PlainDocumentLeafElementRefPtr theElement = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(lineNumber));
	if(theElement)
	{
		Pnt2f topLeft,bottomRight;
		getParentTextDomArea()->getFont()->getBounds(theElement->getText(),topLeft,bottomRight);
		return Pnt2f(_GutterSpace + _GutterSeparation + bottomRight.x(),(lineNumber+1)*heightOfLine);
	}
	else
	{
		return Pnt2f(0,0);
	}
}
bool PlainTextFileType::write(Document* const Doc, std::ostream &OutputStream,
                    const std::string& FileNameOrExtension)
{
    PlainDocumentRefPtr TheDocument = dynamic_cast<PlainDocument*>(Doc);
    std::vector<Element*> GenericRoots;
    GenericRoots = TheDocument->getRootElements();
    for(UInt32 i=0;i<GenericRoots.size();i++)
    {
        PlainDocumentBranchElementRefPtr RootElement;
        RootElement = dynamic_cast<PlainDocumentBranchElement*>(GenericRoots[i]);    
        
        for(UInt32 j=0;j<RootElement->getElementCount()-1;j++)
        {    
            PlainDocumentLeafElementRefPtr LeafElement;
            LeafElement = dynamic_cast<PlainDocumentLeafElement*>(RootElement->getElement(j));
            OutputStream<<LeafElement->getText();
        }
        PlainDocumentLeafElementRefPtr LeafElement;
        LeafElement = dynamic_cast<PlainDocumentLeafElement*>(RootElement->getElement(RootElement->getElementCount()-1));
        OutputStream<<LeafElement->getText().substr(0,LeafElement->getTextLength()-2);

    }
    return false;
}
void FixedHeightLayoutManager::doubleClickHandler(void)
{
	UInt32 initIndex = _CaretIndex;
	PlainDocumentLeafElementRefPtr theElement = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(_CaretLine));
	std::string theString = theElement->getText();

	Int32 BeginWord = 0;
	Int32 EndWord = theElement->getTextLength();

	if(isPunctuationChar(theString[_CaretIndex]))
	{
		EndWord = _CaretIndex + 1;
		BeginWord = _CaretIndex;
	}
	else
	{
		for(Int32 i = _CaretIndex; i < theElement->getTextLength(); i++)
		{
			if(!isWordChar(theString[i]))
			{
				EndWord = i;
				break;
			}
		}
		for(Int32 i = _CaretIndex; i >= 0; i--)
		{
			if(!isWordChar(theString[i]))
			{
				BeginWord = i + 1;
				break;
			}
		}
	}

	HEL = HSL = _CaretLine;
	HSI = BeginWord;
	HEI = EndWord;

	_CaretIndex = EndWord;

	recalculateCaretPositions();

	getParentTextDomArea()->setCaretPosition(getParentTextDomArea()->getCaretPosition()+ (EndWord - initIndex));

}
Real32 FixedHeightLayoutManager::calculateWidthOfLongestLine(Element* const rootElement) const
{
	Real32 finalWidth=0.0;
	Real32 currentWidth;

	for(UInt32 i=0;i<rootElement->getElementCount();i++)
	{
		PlainDocumentLeafElementRefPtr temp = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(i));

		Pnt2f TopLeft, BottomRight;
		getParentTextDomArea()->getFont()->getBounds(temp->getText(), TopLeft, BottomRight);
		
		currentWidth = BottomRight.x() - TopLeft.x();

		if(currentWidth > finalWidth)finalWidth = currentWidth;
	}
	return finalWidth + 15.0;
}
Pnt2f FixedHeightLayoutManager::getXYPosition(UInt32 lineNumber,UInt32 index,bool isBeginning) const
{
	PlainDocumentLeafElementRefPtr theElement = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(lineNumber));
	if(theElement)
	{
		std::string substring = theElement->getText();
		substring = substring.substr(0,index);

		Pnt2f topLeft,bottomRight;
		getParentTextDomArea()->getFont()->getBounds(substring,topLeft,bottomRight);

		if(isBeginning)return Pnt2f( _GutterSpace + _GutterSeparation + bottomRight.x(),lineNumber*heightOfLine);
		return Pnt2f(_GutterSpace + _GutterSeparation + bottomRight.x(),(lineNumber+1)*heightOfLine);
	}
	else
	{
		return Pnt2f(0,0);
	}

}
void FixedHeightLayoutManager::moveAndHighlightWord(UInt32 dir)
{
	Int32 prevIndex= _CaretIndex;
	Int32 prevLine= _CaretLine;
	bool fromPrevElement = false;
	PlainDocumentLeafElementRefPtr theElement; 
	std::string theString;

	switch(dir)
	{

	case LEFT:
		
		theElement = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(prevLine));

		if(prevIndex == 0)
		{
			if(prevLine>0)
			{
				prevLine--;
				theElement = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(prevLine));
				prevIndex = theElement->getTextLength()-2;
				_CaretLine = prevLine;
				_CaretIndex = prevIndex;
				fromPrevElement = true;
				getParentTextDomArea()->setCaretPosition(getParentTextDomArea()->getCaretPosition()-2);
			}
			else break;
		}

		theString = theElement->getText();

		if(prevIndex>0 && isWordChar(theString[prevIndex-1]) == false)fromPrevElement = true;

		for(Int32 i=prevIndex-1; i>=0;)
		{
			if(isWordChar(theString[i]) != fromPrevElement) // this means that when prevIndex is 0, it would indicate the beginning of the line and hence, the ctrl action should take the cursor until a wordchar is found
			{
				_CaretLine = prevLine;
				_CaretIndex = i;	
				getParentTextDomArea()->setCaretPosition(getParentTextDomArea()->getCaretPosition()-1);
				i--;
			}
			else
			{
				break;
			}
		}
		recalculateCaretPositions();
		break;	// case left complete.

	case RIGHT:
		
		theElement = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(prevLine));

		if(prevIndex >=theElement->getTextLength()-2)
		{
			if(prevLine<rootElement->getElementCount()-1)
			{
				prevLine++;
				prevIndex = 0;
				_CaretLine = prevLine;
				_CaretIndex = prevIndex;
				fromPrevElement = true;
				theElement = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(prevLine));
				getParentTextDomArea()->setCaretPosition(getParentTextDomArea()->getCaretPosition()+2);
			}
			else break;
		}

		theString = theElement->getText();

		if(isWordChar(theString[prevIndex]) == false)fromPrevElement = true;

		for(UInt32 i=prevIndex; i<theElement->getTextLength()-2;)
		{
			if(isWordChar(theString[i]) != fromPrevElement) // this means that when prevIndex is 0, it would indicate the beginning of the line and hence, the ctrl action should take the cursor until a wordchar is found
			{
				i++;
				_CaretLine = prevLine;
				_CaretIndex = i;	
				getParentTextDomArea()->setCaretPosition(getParentTextDomArea()->getCaretPosition()+1);
			}
			else
			{
				break;
			}
		}
		recalculateCaretPositions();
		break;	// Case Right complete.
	}
}
UInt32 FixedHeightLayoutManager::calculateCaretPosition(Pnt2f PointOnComponent,bool isDragging)
{
	if(!insideGutterRegion(PointOnComponent.x()))
	{

		UInt32 pos = 0, noOfCharacters =0;
		UInt32 row = (UInt32(floor((PointOnComponent.y()/* - getParentTextDomArea()->getPosition().y() */) / heightOfLine)));

		_CaretLine = row;
		// calculating the caret line and caret y position
		_CaretYPosition = row * heightOfLine;
		
		Real32 xpos = PointOnComponent.x() - _GutterSpace - _GutterSeparation ;

		if(row>=rootElement->getElementCount())
		{
			_CaretLine = rootElement->getElementCount()-1;
			PlainDocumentLeafElementRefPtr temp = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(_CaretLine));
			_CaretIndex = temp->getTextLength()-2;

			recalculateCaretPositions();

			HEL = _CaretLine;
			HEI = _CaretIndex;

			if(!isDragging)
			{
				HSL = HEL;
				HSI = HEI;
			}

			printDebugInformation();

			getParentTextDomArea()->setCaretPosition(getParentTextDomArea()->getDocumentModel()->getEndPosition()-2);
			return 0;	
		}
		for(UInt32 i=0;i<_CaretLine;i++)
		{
			PlainDocumentLeafElementRefPtr temp = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(i));
			noOfCharacters= temp->getTextLength();
			pos += noOfCharacters;
		}
		PlainDocumentLeafElementRefPtr temp = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(row));

		noOfCharacters = 0;

		std::string temptext = temp->getText();
		Pnt2f topLeft,bottomRight;

		std::string ttemp = ""; 

		Real32 widthSoFar = 0.0;
		_CaretIndex = 0;

		for(UInt32 i=0;i<temp->getTextLength()-2;i++)
		{
			ttemp = temptext[i];
			getParentTextDomArea()->getFont()->getBounds(ttemp,topLeft,bottomRight);

			if(widthSoFar + bottomRight.x() <= xpos) 
			{
				noOfCharacters++;
				widthSoFar += bottomRight.x();
				_CaretIndex++;
			}
			else
			{
				break;
			}
			
		}

		_CaretXPosition = _GutterSpace + _GutterSeparation + widthSoFar;
		pos += noOfCharacters;

		HEL = _CaretLine;
		HEI = _CaretIndex;

		if(!isDragging)
		{
			HSL = HEL;
			HSI = HEI;
		}

		printDebugInformation();

		getParentTextDomArea()->setCaretPosition(pos);
		return pos;
	}
}
void FixedHeightLayoutManager::findBrace(char theChar,UInt32 direction)
{
	bool found = false;
	Int32 currentLine;
	
	switch(direction)
	{
		case AFTER:
		{
			currentLine = _StartingBraceLine;
			UInt32 val = 1;
			while(currentLine<rootElement->getElementCount())
			{
				PlainDocumentLeafElementRefPtr temp = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(currentLine));
				std::string theString = temp->getText();
				if(currentLine == _StartingBraceLine)
				{
					theString = theString.substr(_StartingBraceIndex);
				}
				if(find(theString.begin(),theString.end(),theChar) == theString.end() && find(theString.begin(),theString.end(),oppositeBrace(theChar)) == theString.end())
				{
					currentLine++;
					continue;
				}
				else 
				{
					for(UInt32 i=0;i<theString.size();i++)
					{
						if(theString[i]==theChar)
						{
							val++;
						}						
						else if(theString[i]==oppositeBrace(theChar))
						{
							val--;
							if(val <= 0)
							{
								_EndingBraceIndex = (currentLine == _StartingBraceLine)?(_StartingBraceIndex+i):i;
								_EndingBraceLine = currentLine;
								return;
							}
						}
					}
				}
				currentLine++;
			}
		break;
		}
		case BEFORE:
		{
			currentLine = _EndingBraceLine;
			UInt32 val = 1;
			while(currentLine>=0)
			{
				PlainDocumentLeafElementRefPtr temp = dynamic_cast<PlainDocumentLeafElement*>(rootElement->getElement(currentLine));
				std::string theString = temp->getText();
				if(currentLine == _EndingBraceLine)
				{
					theString = theString.substr(0,_EndingBraceIndex);
				}
				if(find(theString.begin(),theString.end(),theChar) == theString.end() && find(theString.begin(),theString.end(),oppositeBrace(theChar)) == theString.end())
				{
					currentLine--;
					continue;
				}
				else 
				{
					for(Int32 i=theString.size()-1;i>=0;i--)
					{
						if(theString[i]==theChar)
						{
							val++;
						}						
						else if(theString[i]==oppositeBrace(theChar))
						{
							val--;
							if(val <= 0)
							{
								_StartingBraceIndex = i;
								_StartingBraceLine = currentLine;
								return;
							}
						}
					}
				}
				currentLine--;
			}
		break;
		}
	}
}
void TextDomArea::tabHandler(bool isShiftPressed)
{
	UInt32 lesserLine,greaterLine,lesserIndex;
	DocumentElementAttribute temp;
	UInt32 oldHSI = getLayoutManager()->getHSI();
	UInt32 oldHSL = getLayoutManager()->getHSL();
	UInt32 oldHEI = getLayoutManager()->getHEI();
	UInt32 oldHEL = getLayoutManager()->getHEL();

	PlainDocumentLeafElementRefPtr theElement;
	if(getLayoutManager()->getHSL() <= getLayoutManager()->getHEL())
	{
		lesserLine = getLayoutManager()->getHSL();
		lesserIndex = getLayoutManager()->getHSI();
		greaterLine = getLayoutManager()->getHEL();
	}
	else
	{
		lesserLine = getLayoutManager()->getHEL();
		lesserIndex = getLayoutManager()->getHEI();
		greaterLine = getLayoutManager()->getHSL();
	}

	UInt32 count=0;
	if(getLayoutManager()->isSomethingSelected())
	{
		if(!isShiftPressed)
		{
			for(UInt32 caretLine = lesserLine;caretLine<=greaterLine;caretLine++)
			{
				for(UInt32 i=0;i<getTabSize();i++)
				{
					//getDocumentModel()->insertCharacter(0,caretLine,' ',temp);
					insertCharacterUsingCommandManager(' ',caretLine,0);
				}
				//getLayoutManager()->DoIfLineLongerThanPreferredSize();
			}
		
		}
		else
		{
			for(UInt32 caretLine = lesserLine;caretLine<=greaterLine;caretLine++)
			{
				theElement = dynamic_cast<PlainDocumentLeafElement*>(getLayoutManager()->getRootElement()->getElement(caretLine));
				std::string theString = theElement->getText();
				Int32 i;
				for(i=0;i<theElement->getTextLength()-2,i<getTabSize();i++)
				{
					if(theString[i]!=' ')break;
					if(caretLine == getLayoutManager()->getCaretLine())getLayoutManager()->moveTheCaret(LEFT,false,false);
					if(caretLine == lesserLine)count--;
				}
				theString = theString.substr(i);
				setTextUsingCommandManager(theElement,theString);
				//theElement->setText(theString);
				
			}
			getLayoutManager()->setHSI(0);
			getLayoutManager()->setHSL(lesserLine);
			getLayoutManager()->setHEI(0);
			getLayoutManager()->setHEL(greaterLine);
		}
	}
	else
	{
		if(!isShiftPressed)
		{
			for(UInt32 i=0;i<getTabSize();i++)
			{
				//getDocumentModel()->insertCharacter(getLayoutManager()->getCaretIndex(),getLayoutManager()->getCaretLine(),' ',temp);
				insertCharacterUsingCommandManager(' ',-1,-1);
				//getLayoutManager()->moveTheCaret(RIGHT,false,false);
			}
			//getLayoutManager()->DoIfLineLongerThanPreferredSize();	
		}
		else
		{
			theElement = dynamic_cast<PlainDocumentLeafElement*>(getLayoutManager()->getRootElement()->getElement(getLayoutManager()->getCaretLine()));
			std::string theString = theElement->getText();
			Int32 i,count=0;
			Int32 initIndex = getLayoutManager()->getCaretIndex();
			for(i=getLayoutManager()->getCaretIndex()-1;i>=0,count<getTabSize();i--,count++)
			{
				if(i<0 || theString[i]!=' ')break;
				getLayoutManager()->moveTheCaret(LEFT,false,false);
			}
			theString = theString.substr(0,getLayoutManager()->getCaretIndex())+theString.substr(initIndex);
			setTextUsingCommandManager(theElement,theString);
			//theElement->setText(theString);
		}
	}
}