
/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

/*  This code generated by: 
 *      Author : thomas
 *      Date   : Wed Jun 18 2003
 */



#ifndef TEXTBLOCK_H
#define TEXTBLOCK_H

#include <qdom.h>
#include <qobject.h>

class CodeDocument;

/**
  * class TextBlock
  * The fundemental unit of text within an output file containing code.
  */

class TextBlock : virtual public QObject {
	friend class CodeGenObjectWithTextBlocks;
	friend class ClassifierCodeDocument;
	Q_OBJECT
public:

	// Constructors/Destructors
	//  

	/**
	 * Constructors 
	 */
	TextBlock ( CodeDocument * parent, const QString & text = "");

	// destructor 
	~TextBlock ( );

	// Public attributes
	//  

	// Public attribute accessor methods
	//  

	/**
	 * Set the value of m_text
	 * The actual text of this code block.
	 * @param new_var the new value of m_text
	 */
	void setText ( const QString &new_var );

	/**
	 * Add text to this object.
  	 *
 	 */
	void appendText ( const QString &new_text );

	/**
	 * Get the value of m_text
	 * The actual text of this code block.
	 * @return the value of m_text
	 */
	QString getText ( ) const;

    	/**
	 * Get the tag of this text block. This tag
	 * may be used to find this text block in the code document
	 * to which it belongs.
	 */
	QString getTag( ) const;

	/**
	 * Set the tag of this text block. This tag
	 * may be used to find this text block in the code document
	 * to which it belongs.
	 */
	void setTag( const QString &value );
 
	/**
	 * Get the value of m_parentDoc
	 * @return the value of m_parentDoc
 	 */
	CodeDocument * getParentDocument ( );

	/**
	 * Set the value of m_writeOutText
	 * Whether or not to include the text of this TextBlock into a file.
	 * @param new_var the new value of m_writeOutText
	 */
	void setWriteOutText ( bool new_var );

	/**
	 * Get the value of m_writeOutText
	 * Whether or not to include the text of this TextBlock into a file.
	 * @return the value of m_writeOutText
	 */
	bool getWriteOutText ( );

	/** Set how many times to indent this text block. 
	 * The amount of each indenatation is determined from the parent
	 * codedocument codegeneration policy.
	 */
	void setIndentationLevel ( int level );

	/** Get how many times to indent this text block. 
	 * The amount of each indenatation is determined from the parent
	 * codedocument codegeneration policy.
	 */
	int getIndentationLevel ( );

	/** Get the actual amount of indentation for a given level of indentation.
	 */
	QString getIndentationString ( int level = 0);

	/** Get how much a single "level" of indentation will actually indent.
	 */
	QString getIndentation();

	QString getNewLineEndingChars ( );

	/** Format a long text string to be more readable.
	 */
	// should be static 
	QString formatMultiLineText ( const QString &text, const QString &linePrefix, QString breakStr, 
				      bool alwaysAddBreak = true, bool lastLineHasBreak = true);

	/** UnFormat a long text string. Typically, this means removing
	 *  the indentaion (linePrefix) and/or newline chars from each line.
	 *  If an indentation isnt specified, then the current indentation is used.
	 */
	virtual QString unformatText ( const QString & text, const QString & indent = "");

	/**
	 * @return	QString
	 */
	virtual QString toString ( );

	/** encode text for XML storage
	 * we simply convert all types of newLines to the "\n" or &#010;
	 * entity.
	 */
	static QString encodeText( QString text , const QString &endChars);


	/** decode text from XML storage
	 * We simply convert all newLine entity &#010; to chosen line ending.
	 */
	static QString decodeText( QString text, const QString &endChars);

	/**
	 * Save the XMI representation of this object
	 */
	virtual void saveToXMI ( QDomDocument & doc, QDomElement & root ) = 0;

	/**
	 * load params from the appropriate XMI element node.
	 */
	virtual void loadFromXMI ( QDomElement & root ) = 0;

	/** Determine if its OK to delete this textblock from the document.
	 * Used by the text editor to know if deletion could cause a crash of
	 * the program.
	 */
	bool canDelete ();

	/** set the class attributes from a passed object
	 */
	virtual void setAttributesFromObject (TextBlock * obj);

	/** Used by the CodeEditor. It provides it with an appropriate
	 * starting string for a new line of text within the given textblock
	 * (for example a string with the proper indentation).
	 * If the indentation amount is '0' the current indentationString will
	 * be used.
	 */
	virtual QString getNewEditorLine( int indentAmount = 0 );

	/** Ush. These are terrifically bad and must one day go away. 
	 * Both methods indicate the range of lines in this textblock 
	 * which may be edited by the codeeditor (assuming that any are
	 * actually editable). The default case is no lines are editable. 
	 * The line numbering starts with '0' and a '-1' means no line
	 * qualifies.
	 */
	virtual int firstEditableLine();
	virtual int lastEditableLine();

protected:

	/** causes the text block to release all of its connections
	 * and any other text blocks that it 'owns'.
	 * needed to be called prior to deletion of the textblock.
	 */
	virtual	void release ();

	/**
	 * Set the value of m_parentDocument
	 * @param new_var the new value of m_parentDoc
	 */
	void setParentDocument ( CodeDocument * new_var );

	/** set attributes of the node that represents this class
	 * in the XMI document.
	 */
	virtual void setAttributesOnNode ( QDomDocument & doc, QDomElement & blockElement);

	/** set the class attributes of this object from
	 * the passed element node.
	 */ 
	virtual void setAttributesFromNode ( QDomElement & element);

	bool m_canDelete;

private:

	// The actual text of this code block.
	QString m_text;
	QString m_tag;

	// Whether or not to include the text of this TextBlock into a file.
	bool m_writeOutText;

	int m_indentationLevel;
	CodeDocument * m_parentDocument;

	void initFields ( CodeDocument * doc);

};

#endif // TEXTBLOCK_H
