namespace InteractiveReadLine.Tokenizing
{
///
/// A contract for a single token produced from a line of text by a lexer.
///
///
///
/// A lexer takes a string and splits it into a sequence of tokens. In order for the autocomplete
/// mechanism to work, there are additional constraints placed on lexers and tokens in the InteractiveReadLine
/// codebase that might not be necessary for other applications.
///
/// Any implementation of IToken must make sure to properly implement the four different Previous/Next
/// links, meaning that the lexer itself must connect the token objects such that the entire sequence
/// of tokens can be walked by following these links from beginning to end and back again.
///
/// Additionally, the Cursor property setter must ensure that setting the cursor on one token
/// will remove it from the previous token in the sequence on which it resided.
///
///
public interface IToken
{
///
/// Gets or sets the text of this particular token. If the cursor is currently on this token, the cursor
/// will be adjusted if necessary if the length of the text changes.
///
string Text { get; set; }
///
/// Gets or sets the cursor position as an offset from the first character in the the Text property. Setting
/// the cursor on this token will remove it from any other token in the sequence.
///
int? Cursor { get; set; }
///
/// Gets the next token in the sequence, regardless of whether the next token is hidden or not. Returns null
/// if this is the last token in the sequence.
///
IToken Next { get; }
///
/// Gets the previous token in the sequence, regardless of whether the previous token is hidden or not. Returns
/// null if this is the first token in the sequence.
///
IToken Previous { get; }
///
/// Gets the next token in the sequence, ignoring hidden tokens. Returns null if this is the last non-hidden
/// token in the sequence.
///
IToken NextNotHidden { get; }
///
/// Gets the previous token in the sequence, ignoring hidden tokens. Returns null if this is the first non-hidden
/// token in the sequence.
///
IToken PreviousNotHidden { get; }
///
/// Gets a value indicating whether or not this token is considered a hidden (grammatically meaningless) token. An
/// example of a typical hidden token in most grammars is whitespace.
///
bool IsHidden { get; }
///
/// Determines the distance between two tokens as the number of links that must be followed to get from this token
/// to the other. Adjacent tokens, for example, have a distance of 1. Returns null if the two tokens are not in
/// the same sequence.
///
/// Another token in the same sequence to measure the distance to
/// Specifies whether or not hidden tokens count as part of the distance
/// The distance between tokens, or null if the distance cannot be found
int? DistanceTo(IToken other, bool ignoreHidden=false);
///
/// Gets the integer type code associated with this token. The lexer has the option of assigning an integer type code
/// to tokens, typically with some semantic meaning known by the lexer as it processed the text. If so, that value
/// it assigned is available here.
///
int TypeCode { get; }
}
}