/*  Inti: Integrated Foundation Classes
 *  Copyright (C) 2002-2003 The Inti Development Team.
 *
 *  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 program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
 
//! @file inti/pango/break.h
//! @brief A PangoLogAttr C++ wrapper interface.
//!
//! Provides LogAttr, an object that stores information about the attributes of a single character.

#ifndef INTI_PANGO_BREAK_H
#define INTI_PANGO_BREAK_H

#ifndef INTI_UTF_STRING_H
#include <inti/utf-string.h>
#endif

#ifndef __PANGO_BREAK_H__
#include <pango/pango-break.h>
#endif

#ifndef _CPP_VECTOR
#include <vector>
#endif

namespace Inti {

namespace Pango {

class Analysis;

//! @class LogAttr break.h inti/pango/break.h
//! @brief A PangoLogAttr C++ wrapper class.
//!
//! LogAttr stores information about the logical attributes of a single character.

class LogAttr
{
	PangoLogAttr attr_;

public:
//! @name Constructors
//! @{

	LogAttr();
	//!< Constructs a new LogAttr with all fields set to false.
	
//! @}
//! @name Accessors
//! @{

	PangoLogAttr* pango_log_attr() const { return const_cast<PangoLogAttr*>(&attr_); }
	//!< Get a pointer to the PangoLogAttr structure.

	operator PangoLogAttr* () const;
	//!< Conversion operator; safely converts a LogAttr to a PangoLogAttr pointer.

	bool is_line_break() const;
	//!< Returns true if can break the line in front of the character.

	bool is_mandatory_break() const;
	//!< Returns true if must break the line in front of the character.

	bool is_char_break() const;
	//!< Returns true if can break at this character when doing character wrapping.

	bool is_white() const;
	//!< Returns true if this is a whitespace character.

	bool is_cursor_position() const;
	//!< Returns true if the cursor can appear in front of character (that is this
	//!< is a grapheme boundary, or the first character in the text).

	bool is_word_start() const;
	//!< Returns true if this is the first character in a word.

	bool is_word_end() const;
	//!< Returns true if this is the first non-word character after a word.

	bool is_sentence_boundary() const;
	//!< Returns true if this character is a sentence boundary.
	//!< There are two ways to divide sentences. The first assigns all intersentence
	//!< whitespace/control/format characters to some sentence, so all characters are
	//!< in some sentence; is_sentence_boundary() denotes the boundaries there. The
	//!< second way doesn't assign between-sentence spaces, etc. to any sentence, so
	//!< is_sentence_start()/is_sentence_end() mark the boundaries of those sentences.

	bool is_sentence_start() const;
	//!< Returns true if this character marks the start of a sentence (see is_sentence_boundary()).

	bool is_sentence_end() const;
	//!< Returns true if this character marks the end of a sentence (see is_sentence_boundary()).

//! @}
//! @name Methods
//! @{

	void set_is_line_break(bool setting);
	//!< Set whether the character is a line break.
	//!< @param setting The setting.

	void set_is_mandatory_break(bool setting);
	//!< Set whether the character is a mandatory line break.
	//!< @param setting The setting.

	void set_is_char_break(bool setting);
	//!< Set whether a line can be broken at the character when wrapping characters.
	//!< @param setting The setting.

	void set_is_white(bool setting);
	//!< Set whether the character is white space.
	//!< @param setting The setting.

	void set_is_cursor_position(bool setting);
	//!< Set whether the cursor can appear in front of character (that is this is
	//!< a grapheme boundary, or the first character in the text).
	//!< @param setting The setting.

	void set_is_word_start(bool setting);
	//!< Set whether the character is the first character in a word.
	//!< @param setting The setting.

	void set_is_word_end(bool setting);
	//!< Set whether the character is the first non-word character after a word.
	//!< @param setting The setting.

	void set_is_sentence_boundary(bool setting);
	//!< Set whether the character is a sentence boundary.
	//!< @param setting The setting.

	void set_is_sentence_start(bool setting);
	//!< Set whether the character marks the start of a sentence.
	//!< @param setting The setting.

	void set_is_sentence_end(bool setting);
	//!< Set whether the character marks the end of a sentence.
	//!< @param setting The setting.

//! @}
};

//! @name Rendering Methods
//! @{

void break_text(const String& text, const Analysis& analysis, std::vector<LogAttr>& attrs);
//!< Determines possible line, word, and character breaks for a string of Unicode text.
//!< @param text The text to process.
//!< @param analysis An Analysis structure from Pango::Context::itemize().
//!< @param attrs A vector of LogAttr to store the character information in.

void find_paragraph_boundary(const String& text, int *paragraph_delimiter_index, int *next_paragraph_start);
//!< Locates a paragraph boundary in text. 
//!< @param text The UTF-8 text.
//!< @param paragraph_delimiter_index The return location for index of delimiter.
//!< @param next_paragraph_start The return location for start of next paragraph.
//!<
//!< <BR>A boundary is caused by delimiter characters, such as a newline, carriage return,
//!< carriage return-newline pair, or Unicode paragraph separator character. The index of
//!< the run of delimiters is returned in paragraph_delimiter_index. The index of the start
//!< of the paragraph (index after all delimiters) is stored in next_paragraph_start. If no
//!< delimiters are found, both paragraph_delimiter_index and next_paragraph_start are filled
//!< with the length of text (an index one off the end).

void get_log_attrs(const String& text, PangoLanguage *language, std::vector<LogAttr>& attrs, int level = -1);
//!< Computes a LogAttr for each character in <EM>text</EM>. 
//!< @param text The text to process.
//!< @param language The language tag.
//!< @param attrs A vector of LogAttr with one LogAttr per character in text, plus one extra, to be filled in.
//!< @param level The embedding level, or -1 if unknown.
//!<
//!< <BR>The <EM>log_attrs</EM> vector must have one LogAttr for each position in 
//!< <EM>text</EM>; if text contains N characters, it has N+1 positions, including
//!< the last position at the end of the text. text should be an entire paragraph;
//!< logical attributes can't be computed without context (for example you need to
//!< see spaces on either side of a word to know the word is a word).

//! @}

} // namespace Pango

} // namespace Inti

#endif // INTI_PANGO_BREAK_H

