/*
 * validate.h
 *
 * Turbo Vision - Version 2.0
 *
 * Copyright (c) 1994 by Borland International
 * All Rights Reserved.
 *
 * Modified by Sergio Sigala <sergio@sigala.it>
 */

#if defined(Uses_TValidator) && !defined(__TValidator)
#define __TValidator

// TValidator Status constants

/** \file validate.h
 * validate.h
 */

static const int
  vsOk     =  0,
  vsSyntax =  1,      // Error in the syntax of either a TPXPictureValidator
                      // or a TDBPictureValidator

// Validator option flags
  voFill     =  0x0001,
  voTransfer =  0x0002,
  voReserved =  0x00FC;

// TVTransfer constants

enum TVTransfer {vtDataSize, vtSetData, vtGetData};

// Abstract TValidator object

/**
 * TValidator defines an abstract data validation object. You will never
 * actually create an instance of TValidator, but it provides much of the
 * abstract functions for the other data validation objects.
 * @see TObject
 * @see TStreamable
 * @short Implements an abstract data validation object
 */
class TValidator : public TObject, public TStreamable
{
public:
    /**
     * Undocumented.
     */
    TValidator();
    /**
     * This is an abstract method called by @ref validate() when it detects
     * that the user has entered invalid information. By default, error() does
     * nothing, but descendant types can override it to provide feedback to
     * the user.
     */
    virtual void error();
    /**
     * If an input line has an associated validator object, it calls
     * isValidInput() after processing each keyboard event. This gives
     * validators such as filter validators an opportunity to catch errors
     * before the user fills the entire item or screen.
     *
     * By default, isValidInput() returns True. Descendant data validators can
     * override isValidInput() to validate data as the user types it,
     * returning True if `s' holds valid data and False otherwise.
     *
     * `s' is the current input string. `suppressFill' determines whether the
     * validator should automatically format the string before validating it.
     *
     * If `suppressFill' is True, validation takes place on the unmodified
     * string `s'. If `suppressFill' is False, the validator should apply any
     * filling or padding before validating data.
     *
     * Of the standard validator objects, only @ref TPXPictureValidator checks
     * `suppressFill'. Because `s' is passed by pointer, isValidInput() can
     * modify the contents of the input string, such as forcing characters to
     * uppercase or inserting literal characters from a format picture.
     *
     * isValidInput() should not, however, delete invalid characters from the
     * string. By returning False, isValidInput() indicates that the input
     * line should erase the offending characters.
     */
    virtual Boolean isValidInput(char* s, Boolean suppressFill);
    /**
     * By default, isValid() returns True. Descendant validator types can
     * override isValid() to validate data for a completed input line.
     *
     * If an input line has an associated validator object, its
     * @ref TInputLine::valid() method calls the validator object's
     * @ref validate()
     * method, which in turn calls @ref isValid() to determine whether the
     * contents of the input line are valid.
     */
    virtual Boolean isValid(const char* s);
    /**
     * transfer() allows a validator to take over setting and reading the
     * values of its associated input line, which is mostly useful for
     * validators that check non-string data, such as numeric values.
     *
     * For example, @ref TRangeValidator uses transfer() to read and write
     * long int type values to a data record, rather than transferring an
     * entire string.
     *
     * By default, input lines with validators give the validator the first
     * chance to respond to @ref TInputLine::dataSize(),
     * @ref TInputLine::getData(), and @TInputLine::setData() by calling the
     * validator's transfer() method.
     *
     * If transfer() returns anything other than 0, it indicates to the input
     * line that it has handled the appropriate transfer.
     * The default action of transfer() is to return 0 always. If you want the
     * validator to transfer data, you need to override its transfer() method.
     *
     * transfer()'s first two parameters are the associated input line's text
     * string and the @ref getData() or @ref setData() data record.
     * Depending on the value of `flag', transfer() can set `s' from `buffer'
     * or read the data from `s' into `buffer'. The return value is always the
     * number of bytes transferred.
     *
     * If `flag' is vtDataSize, transfer() doesn't change either `s' or
     * `buffer', but just returns the data size. If `flag' is vtSetData,
     * Transfer reads the appropriate number of bytes from `buffer', converts
     * them into the proper string form, and sets them into `s', returning the
     * number of bytes read.
     *
     * If `flag' is vtGetData, transfer() converts `s' into the appropriate
     * data type and writes the value into `buffer', returning the number of
     * bytes written.
     *
     * <pre>
     * enum TVTransfer {vtDataSize, vtSetData, vtGetData};
     * </pre>
     *
     * Validator objects use parameters of type TVTransfer in their transfer()
     * methods to control data transfer when setting or reading the value of
     * the associated input line.
     */
    virtual ushort transfer(char *s, void* buffer, TVTransfer flag);
    /**
     * Returns True if @ref isValid(s) returns True. Otherwise calls
     * @ref error() and returns False. A validator's validate() method is
     * called by the @ref TInputLine::valid() method of its associated
     * input line.
     *
     * Input lines with associated validator objects call the validator's
     * validate() method under two conditions: either the input line has its
     * @ref ofValidate option set, in which case it calls validate() when it
     * loses focus, or the dialog box that contains the input line calls
     * validate() for all its controls, usually because the user requested to
     * close the dialog box or accept an entry screen.
     */
    Boolean validate(const char* s);
    /**
     * Indicates the status of the validator object. If status is vsOK, the
     * validator object constructed correctly. Any value other than vsOK
     * indicates that an error occurred.
     *
     * Input line objects use vsOK to check that their associated validator
     * objects were constructed properly. When called with a command parameter
     * of cmValid, an input line object's @ref TInputLine::valid() method
     * checks its validator's status field.
     *
     * If status data member is vsOK, the input line's valid() returns True,
     * indicating that the validator object is ready to use. The only value
     * defined for status other than vsOK is vsSyntax, used by
     * @ref TPXPictureValidator to indicate that it could not interpret the
     * picture string passed to it. If you create your own validator objects,
     * you can define error codes and pass them in the status field.
     * 
     * <pre>
     * Constant Value Meaning
     *
     * vsOK     0     Validator constructed properly
     * vsSyntax 1     Error in the syntax of a picture validator's picture
     * </pre>
     */
    ushort status;
    /**
     * This is a bitmapped field used to control options for various
     * descendants of TValidator. By default, TValidator constructor clears
     * all the bits in options.
     *
     * Constants voXXXX represent the bits in the bitmapped options word in
     * validator objects.
     *
     * <pre>
     * Constant   Value  Meaning
     *
     * voFill     0x0001 Used by picture validators to indicate whether to fill
     *                   in literal characters as the user types
     *
     * voTransfer 0x0002 The validator handles data transfer for the input
     *                   line; currently only used by range validators
     *
     * voReserved 0x00fc The bits in this mask are reserved by Borland
     * </pre>
     */
    ushort options;
protected:
    /**
     * Each streamable class needs a "builder" to allocate the correct memory
     * for its objects together with the initialized virtual table pointers.
     * This is achieved by calling this constructor with an argument of type
     * @ref StreamableInit.
     */
    TValidator( StreamableInit );
    /**
     * Writes to the output stream `os'.
     */
    virtual void write( opstream& os );
    /**
     * Reads from the input stream `is'.
     */
    virtual void* read( ipstream& is );
private:
    virtual const char *streamableName() const  {return name;};
public:
    /**
     * Called to create an object in certain stream-reading situations.
     */
    static TStreamable *build();
    /**
     * Undocumented.
     */
    static const char * const name;
};

#endif


#if defined(Uses_TPXPictureValidator) && !defined(__TPXPictureValidator)
#define __TPXPictureValidator

// TPXPictureValidator result type

enum TPicResult {prComplete, prIncomplete, prEmpty, prError, prSyntax,
    prAmbiguous, prIncompNoFill};

// TPXPictureValidator

/**
 * Picture validator objects compare user input with a picture of a data
 * format to determine the validity of entered data. The pictures are
 * compatible with the pictures Borland's Paradox relational database uses to
 * control data entry.
 *
 * For a complete description of picture specifiers see method
 * @ref TPXPictureValidator::picture()
 * @short Compare user input with a picture of a data format to determine the
 * validity of entered data
 */
class TPXPictureValidator : public TValidator
{
    static const char * errorMsg;
public:
    /**
     * Constructs a picture validator object by first calling the constructor
     * inherited from TValidator, then allocating a copy of `aPic' on the heap
     * and setting @ref pic data member to point to it, then setting the
     * voFill bit in @ref TValidator::options data member if `autoFill' is
     * True.
     */
    TPXPictureValidator(const char* aPic, Boolean autoFill);
    /**
     * Disposes of the string pointed to by @ref pic data member, then
     * disposes of the picture validator object by calling the destructor
     * inherited from @ref TValidator.
     */
    ~TPXPictureValidator();
    /**
     * Displays a message box indicating an error in the picture format,
     * displaying the string pointed to by @ref pic data member.
     */
    virtual void error();
    /**
     * Checks the string passed in `s' against the format picture specified in
     * @ref pic data member and returns True if @ref pic is null or
     * @ref picture() does not return prError for `s'; otherwise returns
     * False.
     *
     * The `suppressFill' parameter overrides the value in voFill for the
     * duration of the call to isValidInput().
     *
     * `s' is a pointer to string, so isValidInput() can modify its value. For
     * example, if `suppressFill' is False and voFill is set, the call to
     * @ref picture() returns a filled string based on `s', so the image in
     * the input line automatically reflects the format specified in pic.
     */
    virtual Boolean isValidInput(char* s, Boolean suppressFill);
    /**
     * Compares the string passed in `s' with the format picture specified in
     * @ref pic data member and returns True if @ref pic is null or if
     * @ref picture() returns prComplete for `s', indicating that `s' needs
     * no further input to meet the specified format.
     */
    virtual Boolean isValid(const char* s);
    /**
     * Formats the string passed in `input' according to the format specified
     * by the picture string pointed to by @ref pic data member. Returns
     * prError if there is an error in the picture string or if `input'
     * contains data that cannot fit the specified picture.
     *
     * Returns prComplete if `input' can fully satisfy the specifed picture.
     * Returns prIncomplete if `input' contains data that fits the specified
     * picture but not completely.
     *
     * The following table shows the characters used in creating format
     * pictures.
     *
     * <pre>
     * Type of character Character Description
     *
     * Special           #         Accept only a digit
     *                   ?         Accept only a letter (case-insensitive)
     *                   &         Accept only a letter, force to  uppercase
     *                   @         Accept any character
     *                   !         Accept any character, force to uppercase
     *
     * Match             ;         Take next character literally
     *                   *         Repetition count
     *                   []        Option
     *                   {}        Grouping operators
     *                   ,         Set of alternatives
     *
     * All others                  Taken literally
     * </pre>
     *
     * Here are some advanced pictures, which show the power of TPXPictureValidator;
     * these examples come from an old Pascal FAQ written by Berend de Boer,
     * <berend@beard.nest.nl>.
     *
     * <pre>
     * Name           Value                Description
     *
     * UnsignedPic1   #[#][#]*{[;,]###}    unsigned int with optional commas
     * UnsignedPic2   #[#][#]*{;,###}      unsigned int with commas
     * SignedPic1     [-]#[#][#]*{[;,]###} signed int with optional commas
     * SignedPic2     [-]#[#][#]*{;,###}   signed int with commas
     * MoneyPic1      [$]*#.{##,00}        dollars, with comma and optinal dollar sign
     * MoneyPic2      $*#{.##,.00}         dollars, with comma and dollar sign
     * DatePic1       #[#]/#[#]/##         date with 2 digit year (dd/mm/yy or mm/dd/yy)
     * DatePic2       #[#]/#[#]/##[##]     date with 2 or 4 digit year (mm/dd/yy or mm/dd/yyyy)
     * DatePic3       #[#]/#[#]/####       date with 4 digit year (mm/dd/yyyy)
     * TimePic1       {##}:{##}[:{##}]     HH:MM:SS with optional seconds
     * TimePic2       {##}:{##}:{##}       HH:MM:SS
     * PhonePic1      [(###) ]###-####     phone number with optional area code
     * PhonePic2      (###) ###-####       phone number with area code
     * SSNPic         ###-##-####
     * FirstCharUpPic *{&*? }              uppercase the first char of every word
     * FilenamePic    {&*7[&]}.{*3[&]}     filename (no path) with extension
     * </pre>
     *
     * Note the *7 and *3 in this last example. A number after a `*' says
     * how many times the next sequence should be repeated; uncovered in
     * the manuals. But this example is not completely correct (is this a
     * bug?), because the `*' is interpreted as that there should be exactly 8
     * characters! No more, no less. Correct is:
     *
     * <pre>
     * FilenamePic    {&[&][&][&][&][&][&][&]}.{[&][&][&]}
     * </pre>
     *
     * The following examples were given by Sean Wenzel in the Borland Turbo Vision forum
     * on CompuServe:
     *
     * - US Phone with optional area code: [(*3{#})]*3{#}-*4{#}
     *
     * - Colors with autofill-in: {Red,Gr{ay,een},B{l{ack,ue},rown},White,Yellow}
     *
     * - A date in the format "Jan, 31, 1999" with auto fill-in:
     * {J{AN ,U{N ,L }},FEB ,MA{R ,Y },A{PR ,UG },SEP ,OCT ,NOV ,DEC} {1[#],2[#],30,31,#};, 19##
     *
     * Finally, here my solution for a real validator, for the format "1.234E-6" or "3.14159":
     *
     * [-]#[*#][[.]#[*#]][E[-]#[#]]
     */
    virtual TPicResult picture(char* input, Boolean autoFill);
protected:
    /**
     * Each streamable class needs a "builder" to allocate the correct memory
     * for its objects together with the initialized virtual table pointers.
     * This is achieved by calling this constructor with an argument of type
     * @ref StreamableInit.
     */
    TPXPictureValidator( StreamableInit );
    /**
     * Writes to the output stream `os'.
     */
    virtual void write( opstream& os );
    /**
     * Reads from the input stream `is'.
     */
    virtual void* read( ipstream& is );
    /**
     * Points to a string containing the picture that specifies the format for
     * data in the associated input line. The constructor sets pic to the
     * string passed as one of its parameters.
     */
    char* pic;
private:
    /**
     * Undocumented.
     */
    void consume(char ch, char* input);
    /**
     * Undocumented.
     */
    void toGroupEnd(int& i, int termCh);
    /**
     * Undocumented.
     */
    Boolean skipToComma(int termCh);
    /**
     * Undocumented.
     */
    int calcTerm(int);
    /**
     * Undocumented.
     */
    TPicResult iteration(char* input, int termCh);
    /**
     * Undocumented.
     */
    TPicResult group(char* input, int termCh);
    /**
     * Undocumented.
     */
    TPicResult checkComplete(TPicResult rslt, int termCh);
    /**
     * Undocumented.
     */
    TPicResult scan(char* input, int termCh);
    /**
     * Undocumented.
     */
    TPicResult process(char* input, int termCh);
    /**
     * Undocumented.
     */
    Boolean syntaxCheck();
    /**
     * Undocumented.
     */
    virtual const char *streamableName() const  {return name;};
    /**
     * Undocumented.
     */
    int index, jndex;
public:
    /**
     * Called to create an object in certain stream-reading situations.
     */
    static TStreamable *build();
    /**
     * Undocumented.
     */
    static const char * const name;
};

/**
 * Undocumented.
 */
inline ipstream& operator >> ( ipstream& is, TValidator& v )
    { return is >> (TStreamable&)v; }
/**
 * Undocumented.
 */
inline ipstream& operator >> ( ipstream& is, TValidator*& v )
    { return is >> (void *&)v; }

/**
 * Undocumented.
 */
inline opstream& operator << ( opstream& os, TValidator& v )
    { return os << (TStreamable&)v; }
/**
 * Undocumented.
 */
inline opstream& operator << ( opstream& os, TValidator* v )
    { return os << (TStreamable *)v; }

#endif


#if defined(Uses_TFilterValidator) && !defined(__TFilterValidator)
#define __TFilterValidator

// TFilterValidator

/**
 * Filter validator objects check an input field as the user types into it.
 * The validator holds a set of allowed characters. If the user types one of
 * the legal characters, the filter validator indicates that the character is
 * valid.
 *
 * If the user types any other character, the validator indicates that the
 * input is invalid.
 * @short Check an input field as the user types into it
 */
class TFilterValidator : public TValidator
{
    static const char * errorMsg;
public:
    /**
     * Constructs a filter validator object by first calling the constructor
     * inherited from @ref TValidator, then setting @ref validChars data
     * member to `aValidChars'.
     */
    TFilterValidator(const char* aValidChars);
    /**
     * Undocumented.
     */
    ~TFilterValidator();
    /**
     * Undocumented.
     */
    virtual void error();
    /**
     * Checks each character in the string `s' to make sure it is in the set
     * of allowed characters, @ref validChars. Returns True if all characters
     * in `s' are valid; otherwise returns False.
     */
    virtual Boolean isValidInput(char* s, Boolean suppressFill);
    /**
     * Checks each character in the string `s' to make sure it is in the set
     * of allowed characters, @ref validChars. Returns True if all characters
     * in `s' are valid; otherwise returns False.
     */
    virtual Boolean isValid(const char* s);
protected:
    /**
     * Each streamable class needs a "builder" to allocate the correct memory
     * for its objects together with the initialized virtual table pointers.
     * This is achieved by calling this constructor with an argument of type
     * @ref StreamableInit.
     */
    TFilterValidator( StreamableInit );
    /**
     * Writes to the output stream `os'.
     */
    virtual void write( opstream& os);
    /**
     * Reads from the input stream `is'.
     */
    virtual void* read( ipstream& is );
    /**
     * Contains the set of all characters the user can type. For example, to
     * allow only numeric digits, set validChars to ['0'..'9']. validChars is
     * set by the `aValidChars' parameter passed to the constructor.
     */
    char* validChars;
private:
    /**
     * Undocumented.
     */
    virtual const char *streamableName() const  {return name;};
public:
    /**
     * Called to create an object in certain stream-reading situations.
     */
    static TStreamable *build();
    /**
     * Undocumented.
     */
    static const char * const name;
};

/**
 * Undocumented.
 */
inline ipstream& operator >> ( ipstream& is, TFilterValidator& v )
    { return is >> (TStreamable&)v; }
/**
 * Undocumented.
 */
inline ipstream& operator >> ( ipstream& is, TFilterValidator*& v )
    { return is >> (void *&)v; }

/**
 * Undocumented.
 */
inline opstream& operator << ( opstream& os, TFilterValidator& v )
    { return os << (TStreamable&)v; }
/**
 * Undocumented.
 */
inline opstream& operator << ( opstream& os, TFilterValidator* v )
    { return os << (TStreamable *)v; }

#endif


#if defined(Uses_TRangeValidator) && !defined(__TRangeValidator)
#define __TRangeValidator

// TRangeValidator

/**
 * A range validator object determines whether the data typed by a user falls
 * within a designated range of integers.
 * @short Determines whether the data typed by a user falls within a
 * designated range of integers
 */
class TRangeValidator : public TFilterValidator
{
    /**
     * Undocumented.
     */
    static const char * validUnsignedChars;
    /**
     * Undocumented.
     */
    static const char * validSignedChars;
    /**
     * Undocumented.
     */
    static const char * errorMsg;
public:
    /**
     * Constructs a range validator object by first calling the constructor
     * inherited from @ref TFilterValidator, passing a set of characters
     * containing the digits '0'..'9' and the characters '+' and '-'.
     *
     * Sets @ref min to `aMin' and @ref max to `aMax', establishing the range
     * of acceptable long integer values.
     */
    TRangeValidator(long aMin, long aMax);
    /**
     * Displays a message box indicating that the entered value did not fall
     * in the specified range.
     */
    virtual void error();
    /**
     * Converts the string `s' into an integer number and returns True if the
     * result meets all three of these conditions:
     *
     * -# it is a valid integer number
     * -# it value is greater than or equal to @ref min
     * -# it value is less than or equal to @ref max
     *
     * If any of those tests fails, isValid() returns False.
     */
    virtual Boolean isValid(const char* s);
    /**
     * Incorporates the three functions @ref TInputLine::dataSize(),
     * @ref TInputLine::getData(), and @ref TInputLine::setData() that a
     * range validator can handle for its associated input line.
     *
     * Instead of setting and reading the value of the numeric input line by
     * passing a string representation of the number, transfer() can use a
     * long int as its data record, which keeps your application from having
     * to handle the conversion.
     *
     * `s' is the input line's string value, and `buffer' is the data record
     * passed to the input line.
     *
     * Depending on the value of `flag', transfer either sets `s' from the
     * number in `buffer' or sets the number at `buffer' to the value of the
     * string `s'. If `flag' is vtSetData, transfer() sets `s' from `buffer'.
     *
     * If `flag' is vtGetData, transfer() sets `buffer' from `s'. If `flag' is
     * vtDataSize, transfer() neither sets nor reads data.
     *
     * transfer() always returns the size of the data transferred, in this
     * case the size of a long int.
     * @see TValidator::transfer
     */
    virtual ushort transfer(char* s, void* buffer, TVTransfer flag);
protected:
    /**
     * min is the lowest valid long integer value for the input line.
     */
    long min;
    /**
     * max is the highest valid long integer value for the input line.
     */
    long max;
    /**
     * Each streamable class needs a "builder" to allocate the correct memory
     * for its objects together with the initialized virtual table pointers.
     * This is achieved by calling this constructor with an argument of type
     * @ref StreamableInit.
     */
    TRangeValidator( StreamableInit );
    /**
     * Writes to the output stream `os'.
     */
    virtual void write( opstream& os );
    /**
     * Reads from the input stream `is'.
     */
    virtual void* read( ipstream& is );
private:
    /**
     * Undocumented.
     */
    virtual const char *streamableName() const  {return name;};
public:
    /**
     * Called to create an object in certain stream-reading situations.
     */
    static TStreamable *build();
    /**
     * Undocumented.
     */
    static const char * const name;
};

/**
 * Undocumented.
 */
inline ipstream& operator >> ( ipstream& is, TRangeValidator& v )
    { return is >> (TStreamable&)v; }
/**
 * Undocumented.
 */
inline ipstream& operator >> ( ipstream& is, TRangeValidator*& v )
    { return is >> (void *&)v; }

/**
 * Undocumented.
 */
inline opstream& operator << ( opstream& os, TRangeValidator& v )
    { return os << (TStreamable&)v; }
/**
 * Undocumented.
 */
inline opstream& operator << ( opstream& os, TRangeValidator* v )
    { return os << (TStreamable *)v; }

#endif

#if defined(Uses_TLookupValidator) && !defined(__TLookupValidator)
#define __TLookupValidator

// TLookupValidator

/**
 * A lookup validator compares the string typed by a user with a list of
 * acceptable values. TLookupValidator is an abstract validator type from
 * which you can derive useful lookup validators. You will never create an
 * instance of TLookupValidator.
 *
 * When you create a lookup validator type, you need to specify a list of
 * valid items and override the @ref lookup() method to return True only if
 * the user input matches an item in that list. One example of a working
 * descendant of TLookupValidator is @ref TStringLookupValidator.
 * @short Compares the string typed by a user with a list of acceptable values
 */
class TLookupValidator : public TValidator
{
public:
    /**
     * Undocumented.
     */
    TLookupValidator() {};
    /**
     * Calls @ref lookup() to find the string `s' in the list of valid input
     * items. Returns True if @ref lookup() returns True, meaning
     * @ref lookup() found `s' in its list; otherwise returns False.
     */
    virtual Boolean isValid(const char* s);
    /**
     * Searches for the string `s' in the list of valid entries and returns
     * True if it finds `s'; otherwise returns False. TLookupValidator's
     * lookup() is an abstract method that always returns False.
     *
     * Descendant lookup validator types must override lookup() to perform a
     * search based on the actual list of acceptable items.
     */
    virtual Boolean lookup(const char* s);
    /**
     * Called to create an object in certain stream-reading situations.
     */
    static TStreamable *build();
    /**
     * Undocumented.
     */
    static const char * const name;
protected:
    /**
     * Each streamable class needs a "builder" to allocate the correct memory
     * for its objects together with the initialized virtual table pointers.
     * This is achieved by calling this constructor with an argument of type
     * @ref StreamableInit.
     */
    TLookupValidator( StreamableInit );
private:
    /**
     * Undocumented.
     */
    virtual const char *streamableName() const  {return name;};
};

/**
 * Undocumented.
 */
inline ipstream& operator >> ( ipstream& is, TLookupValidator& v )
    { return is >> (TStreamable&)v; }
/**
 * Undocumented.
 */
inline ipstream& operator >> ( ipstream& is, TLookupValidator*& v )
    { return is >> (void *&)v; }

/**
 * Undocumented.
 */
inline opstream& operator << ( opstream& os, TLookupValidator& v )
    { return os << (TStreamable&)v; }
/**
 * Undocumented.
 */
inline opstream& operator << ( opstream& os, TLookupValidator* v )
    { return os << (TStreamable *)v; }

#endif


#if defined(Uses_TStringLookupValidator) && !defined(__TStringLookupValidator)
#define __TStringLookupValidator

// TStringLookupValidator

/**
 * A string lookup validator object verifies the data in its associated input
 * line by searching through a collection of valid strings. Use string lookup
 * validators when your input line needs to accept only members of a certain
 * set of strings.
 * @short Verifies the data in its associated input line by searching through
 * a collection of valid strings
 */
class TStringLookupValidator : public TLookupValidator
{
    static const char * errorMsg;
public:
    /**
     * Constructs a string lookup validator object by first calling the
     * constructor inherited from @ref TLookupValidator, then setting
     * @ref strings data member to `aStrings'.
     */
    TStringLookupValidator(TStringCollection* aStrings);
    /**
     * Disposes of the list of valid strings by calling newStringList(0),
     * then disposes of the string lookup object by calling the destructor
     * inherited from @ref TLookupValidator.
     * @see newStringList
     */
    ~TStringLookupValidator();
    /**
     * Displays a message box indicating that the typed string does not match
     * an entry in the string list.
     */
    virtual void error();
    /**
     * Returns True if the string passed in `s' matches any of the strings in
     * strings data member. Uses the strcmp() function to determine if `s' is
     * present.
     */
    virtual Boolean lookup(const char* s);
protected:
    /**
     * Each streamable class needs a "builder" to allocate the correct memory
     * for its objects together with the initialized virtual table pointers.
     * This is achieved by calling this constructor with an argument of type
     * @ref StreamableInit.
     */
    TStringLookupValidator( StreamableInit );
    /**
     * Writes to the output stream `os'.
     */
    virtual void write( opstream& os );
    /**
     * Reads from the input stream `is'.
     */
    virtual void* read( ipstream& is );
    /**
     * Points to a string collection containing all the valid strings the user
     * can type. If strings data member is 0, all input will be invalid.
     */
    TStringCollection* strings;
private:
    /**
     * Undocumented.
     */
    virtual const char *streamableName() const  {return name;};
public:
    /**
     * Sets the list of valid input strings for the string lookup validator.
     * Disposes of any existing string list, then sets @ref strings data
     * member to `aStrings'.
     *
     * Passing 0 in `aStrings' disposes of the existing list without assigning
     * a new one.
     */
    void newStringList(TStringCollection* aStrings);
    /**
     * Called to create an object in certain stream-reading situations.
     */
    static TStreamable *build();
    /**
     * Undocumented.
     */
    static const char * const name;
};


/**
 * Undocumented.
 */
inline ipstream& operator >> ( ipstream& is, TStringLookupValidator& v )
    { return is >> (TStreamable&)v; }
/**
 * Undocumented.
 */
inline ipstream& operator >> ( ipstream& is, TStringLookupValidator*& v )
    { return is >> (void *&)v; }

/**
 * Undocumented.
 */
inline opstream& operator << ( opstream& os, TStringLookupValidator& v )
    { return os << (TStreamable&)v; }
/**
 * Undocumented.
 */
inline opstream& operator << ( opstream& os, TStringLookupValidator* v )
    { return os << (TStreamable *)v; }


#endif
