#pragma once

#include <functional>
#include <sstream>

#include "Reader.h"
#include "ReferenceCounter.h"

namespace Framework
{
    namespace SpecialCharacters
    {
        const char SMALL_UE = '\xFC';
        const char BIG_UE = '\xDC';
        const char SMALL_AE = '\xE4';
        const char BIG_AE = '\xC4';
        const char SMALL_OE = '\xF6';
        const char BIG_OE = '\xD6';
        const char SZ = '\xDF';
        const char DEGREE_SIGN = '\xB0';
        const char CARET = '\x5E';
        const char SECTION_SIGN = '\xA7';
        const char ACUTE_ACCENT = '\xB4';
    } // namespace SpecialCharacters

    namespace Regex
    {
        class Result;
        class RegexConfig;
    } // namespace Regex

    class DynamicBuffer : public std::stringbuf
    {
    private:
        std::function<int(std::stringbuf&)> onAppend;

    public:
        DLLEXPORT DynamicBuffer(std::function<int(std::stringbuf&)> onAppend);

        DLLEXPORT virtual int sync() override;
    };

    class FlushingOStream : public std::ostream
    {
    private:
        std::function<void()> onDestroy;

    public:
        DLLEXPORT FlushingOStream(
            DynamicBuffer* buffer, std::function<void()> onDestroy = []() {});
        DLLEXPORT FlushingOStream(const Framework::FlushingOStream& stream);

        DLLEXPORT ~FlushingOStream();
    };

    //! A replacement for String
    class Text : public virtual ReferenceCounter
    {
    private:
        char* txt;
        int length;
        char suchGBeg;
        char suchGEnd;
        int precision;
        DynamicBuffer* stringWriter;

        DLLEXPORT Text(char* txt, int l);

    public:
        //! Creates a new Text object with the value ""
        DLLEXPORT Text();
        //! Creates a new Text object by copying the value from (txt)
        //! \param txt The text to be copied
        DLLEXPORT Text(const Text& txt);
        //! Creates a new Text object by copying the value from (txt)
        //! \param txt The string to be copied
        DLLEXPORT Text(const char* txt);
        //! Creates a new Text object by copying a section from (txt)
        //! \param txt The string from which a section should be copied
        //! \param offset Start position from which to copy
        //! \param length Number of characters to copy
        DLLEXPORT Text(const char* txt, int offset, int length);
        //! Creates a new Text object with a number as text
        //! \param zahl The number to be contained in the text
        DLLEXPORT Text(int zahl);
        //! Creates a new Text object with a number as text
        //! \param num The number to be contained in the text
        DLLEXPORT Text(double num);
        //! Creates a new Text object with a number as text
        //! \param num The number to be contained in the text
        DLLEXPORT Text(float num);
        //! Deletes the text
        DLLEXPORT ~Text();

    private:
        DLLEXPORT void setTextZ(char* t, int l);

    public:
        //! Converts all letters to uppercase
        DLLEXPORT void toUpperCase();
        //! Converts all letters to lowercase
        DLLEXPORT void toLowerCase();
        //! Sets the search boundaries used by the search functions
        //! \param gBeg The character at which the search should begin
        //! \param gEnd The character at which the search should end
        DLLEXPORT void setSuchGrenzen(char gBeg, char gEnd);
        //! Sets the text stored by this object
        //! \param t A string whose content is copied
        DLLEXPORT void setText(const char* t);
        //! Sets the text stored by this object
        //! \param t A string whose content is copied
        //! \param l The length of the text to be copied from (t)
        DLLEXPORT void setText(const char* t, int l);
        //! Sets the text stored by this object
        //! \param t The Text object whose content should be copied
        DLLEXPORT void setText(const Text& t);
        //! Appends the given number as hex text (0-F) to the end of the text
        //! \param num The number to be converted to hex and appended
        DLLEXPORT void appendHex(char num);
        //! Appends the given number as hex text (0-F) to the end of the text
        //! \param num The number to be converted to hex and appended
        DLLEXPORT void appendHex(short num);
        //! Appends the given number as hex text (0-F) to the end of the text
        //! \param num The number to be converted to hex and appended
        DLLEXPORT void appendHex(int num);
        //! Appends the given number as hex text (0-F) to the end of the text
        //! \param num The number to be converted to hex and appended
        DLLEXPORT void appendHex(__int64 num);
        //! Appends the given character to the string
        //! \param c The character to be appended
        DLLEXPORT void append(char c);
        //! Appends the given string to the end of the text
        //! \param t The string whose copy should be appended to the end of the
        //! text
        DLLEXPORT void append(const char* t);
        //! Appends a part of the given string to the end of the text
        //! \param t The string whose copy should be appended
        //! \param l The length of the text section to be appended
        DLLEXPORT void append(const char* t, int l);
        //! Appends the content of a Text to the end of the text
        //! \param t The Text whose copy should be appended to the end of the
        //! text
        DLLEXPORT void append(const Text& t);
        //! Appends a number to the end of the text
        //! \param num The number to be converted to text and appended at the
        //! end
        DLLEXPORT void append(int num);
        //! Appends a number to the end of the text
        //! \param num The number to be converted to text and appended at the
        //! end
        DLLEXPORT void append(__int64 num);
        //! Appends an unsigned number to the end of the text
        //! \param num The number to be converted to text and appended at the
        //! end
        DLLEXPORT void append(unsigned int num);
        //! Appends a floating-point number to the end of the text
        //! \param num The floating-point number to be appended to the end of
        //! the text
        DLLEXPORT void append(double num);
        //! Appends a floating-point number to the end of the text
        //! \param num The floating-point number to be appended to the end of
        //! the text
        DLLEXPORT void append(float num);
        //! Returns an ostream that appends all output to this text
        DLLEXPORT FlushingOStream append();
        //! Inserts a character at a specific position in the text
        //! \param p The position in the text where the character should be
        //! inserted
        //! \param c The character to be inserted
        DLLEXPORT void insert(int p, char c);
        //! Inserts a string at a specific position in the text
        //! \param p The position in the text where the string should be
        //! inserted
        //! \param t The string whose copy should be inserted
        DLLEXPORT void insert(int p, const char* t);
        //! Inserts a string at a specific position in the text
        //! \param p The position in the text where the string should be
        //! inserted
        //! \param t The string whose copy should be inserted
        //! \param len The length of the text to be inserted
        DLLEXPORT void insert(int p, const char* t, int len);
        //! Inserts the content of a Text at a specific position in the text
        //! \param p The position in the text where the content should be
        //! inserted
        //! \param t The Text whose copy should be inserted at the position
        DLLEXPORT void insert(int p, const Text& t);
        // replaces all regular expression occurences by a static string
        // \param regex The regular expression to search for
        // \param replacement The string to replace the occurences with
        // \param config The configuration for the regular expression
        DLLEXPORT void regexReplace(const char* regex,
            const char* replacement,
            Regex::RegexConfig* config = 0);
        // replaces all regular expression occurences with a result of a
        // specified replacement function string \param regex The regular
        // expression to search for \param replacementFunction a function that
        // is called with the result of the regular expression and should return
        // the replacement string \param config The configuration for the
        // regular expression
        DLLEXPORT void regexReplace(const char* regex,
            std::function<Text(Regex::Result&)> replacementFunction,
            Regex::RegexConfig* config = 0);
        //! Replaces a specific text section with another string
        //! \param p1 The start position of the text section to be replaced
        //! \param p2 The end position of the text section to be replaced
        //! \param t The string to be copied to the corresponding position
        //! Example: ( "Hallo World" ).replace( 2, 5, "lt" );
        //! results in: "Halt World"
        DLLEXPORT void replace(int p1, int p2, const char* t);
        //! Replaces a specific text section with another string
        //! \param p1 The start position of the text section to be replaced
        //! \param p2 The end position of the text section to be replaced
        //! \param t The string to be copied to the corresponding position
        //! \param len The length of the text to be copied to the corresponding
        //! position Example: ( "Hallo World" ).replace( 2, 5, "lt", 2 );
        //! results in: "Halt World"
        DLLEXPORT void replace(int p1, int p2, const char* t, int len);
        //! Replaces a specific text section with the content of another Text
        //!  p1: The start position of the text section to be replaced
        //!  p2: The end position of the text section to be replaced
        //! \param t The Text whose content should be copied to the
        //! corresponding position Example: ( "Hallo World" ).replace( 2, 5, new
        //! Text( "lt" ) ); results in: "Halt World"
        DLLEXPORT void replace(int p1, int p2, const Text& t);
        //! Searches and replaces every occurrence of a specific character with
        //! another
        //!  c1: The character to be replaced
        //!  c2: The character to replace the other one with
        DLLEXPORT void replace(char c1, char c2);
        //! Searches and replaces every occurrence of a specific string with
        //! another
        //!  t1: The string to be replaced
        //!  t2: The string to replace the other one with
        DLLEXPORT void replace(const char* t1, const char* t2);
        //! Searches and replaces every occurrence of a specific string with
        //! another
        //! \param t1 The string to be replaced
        //! \param t2 The string to replace the other one with
        //! \param len1 The length of the string to be replaced
        //! \param len2 The length of the replacement string
        DLLEXPORT void replace(
            const char* t1, int len1, const char* t2, int len2);
        //! Searches and replaces every occurrence of the content of a Text with
        //! another string
        //!  t1: The Text whose content is searched for and replaced
        //!  t2: The string to replace the occurrences of the Text with
        DLLEXPORT void replace(const Text& t1, const char* t2);
        //! Searches and replaces every occurrence of a string with the
        //! content of a Text
        //!  t1: The string to be replaced
        //!  t2: The Text whose content should replace the occurrences of the
        //!  string
        DLLEXPORT void replace(const char* t1, const Text& t2);
        //! Searches and replaces every occurrence of the content of a Text with
        //! the content of another Text
        //!  t1: The Text whose occurrences should be replaced
        //!  t2: The Text whose content should replace the occurrences
        DLLEXPORT void replace(const Text& t1, const Text& t2);
        //! Replaces the i-th occurrence of a specific character with another
        //! character
        //! \param i Which occurrence of the character should be replaced
        //!  c1: The character whose i-th occurrence should be replaced
        //!  c2: The character to replace the i-th occurrence of the other
        //!  character
        DLLEXPORT void replace(int i, char c1, char c2);
        //! Replaces the i-th occurrence of a specific string with another
        //! string
        //! \param i Which occurrence of the string should be replaced
        //!  c1: The string whose i-th occurrence should be replaced
        //!  c2: The string to replace the i-th occurrence of the other string
        DLLEXPORT void replace(int i, const char* t1, const char* t2);
        //! Replaces the i-th occurrence of a specific string with another
        //! string
        //! \param i Which occurrence of the string should be replaced
        //! \param c1 The string whose i-th occurrence should be replaced
        //! \param c2 The string to replace the i-th occurrence of the other
        //! string
        //! \param len1 The length of the string to be replaced
        //! \param len2 The length of the replacement string
        DLLEXPORT void replace(
            int i, const char* t1, int len1, const char* t2, int len2);
        //! Replaces the i-th occurrence of the content of a Text with a string
        //! \param i Which occurrence of the Text should be replaced
        //!  c1: The Text whose i-th occurrence should be replaced
        //!  c2: The string to replace the i-th occurrence of the Text
        DLLEXPORT void replace(int i, const Text& t1, const char* t2);
        //! Replaces the i-th occurrence of a specific string with the content
        //! of a Text
        //! \param i Which occurrence of the string should be replaced
        //!  c1: The string whose i-th occurrence should be replaced
        //!  c2: The Text whose content should replace the i-th occurrence of
        //!  the string
        DLLEXPORT void replace(int i, const char* t1, const Text& t2);
        //! Replaces the i-th occurrence of a specific Text with the content
        //! of another Text
        //! \param i Which occurrence of the Text should be replaced
        //!  c1: The Text whose i-th occurrence should be replaced
        //!  c2: The Text whose content should replace the i-th occurrence of
        //!  the other Text
        DLLEXPORT void replace(int i, const Text& t1, const Text& t2);
        //! Clears the current text and creates a text consisting of a specific
        //! character with a specific length
        //! \param c The character the text should consist of
        //! \param length The length of the text
        DLLEXPORT void fillText(char c, int length);
        //! Deletes a specific character from the text
        //! \param p The position of the character to be deleted
        DLLEXPORT void remove(int p);
        //! Deletes a specific text section
        //!  p1: The start position of the section to be deleted
        //!  p2: The end position of the section to be deleted (the character at
        //!  p2 is preserved)
        DLLEXPORT void remove(int p1, int p2);
        //! Deletes every occurrence of a specific character
        //! \param c The character whose occurrences should be deleted
        DLLEXPORT void remove(char c);
        //! Deletes every occurrence of a specific string
        //! \param t The string whose occurrences should be removed
        DLLEXPORT void remove(const char* t);
        //! Deletes every occurrence of a specific string
        //! \param t The string whose occurrences should be removed
        //! \param len The length of the string to be deleted
        DLLEXPORT void remove(const char* t, int len);
        //! Deletes every occurrence of the content of a Text
        //! \param t The Text whose content should be deleted
        DLLEXPORT void remove(const Text& t);
        //! Deletes the i-th occurrence of a specific character
        //! \param i Which occurrence of the character should be deleted
        //! \param c The character whose i-th occurrence should be deleted
        DLLEXPORT void remove(int i, char c);
        //! Deletes the i-th occurrence of a specific string
        //! \param i Which occurrence of the string should be deleted
        //! \param t The string whose i-th occurrence should be deleted
        DLLEXPORT void remove(int i, const char* t);
        //! Deletes the i-th occurrence of a specific string
        //! \param i Which occurrence of the string should be deleted
        //! \param t The string whose i-th occurrence should be deleted
        //! \param len The length of the string to be deleted
        DLLEXPORT void remove(int i, const char* t, int len);
        //! Deletes the i-th occurrence of a specific text content
        //! \param i Which occurrence of the text content should be deleted
        //! \param t The Text whose i-th occurrence should be deleted
        DLLEXPORT void remove(int i, const Text& t);
        //! Deletes all ' ', '\n', '\r', '\t' until a non-whitespace character
        //! \param pos The position of the first character
        //! \return the number of removed characters
        DLLEXPORT int removeWhitespaceAfter(int pos);
        //! Deletes all ' ', '\n', '\r', '\t' until a non-whitespace character
        //! \param pos The position of the first character (starts at pos-1)
        //! \return the number of removed characters
        DLLEXPORT int removeWhitespaceBefore(int pos);
        //! Sets the number of decimal places when appending floating-point
        //! numbers
        //! \param p The number of digits after the decimal point
        DLLEXPORT void setPrecision(int p);
        //! Returns the length of the text
        DLLEXPORT int getLength() const;
        //! Determines the new cursor position after pressing the 'Left' arrow
        //! key
        //! \param pos The old cursor position
        DLLEXPORT int getLKick(int pos) const;
        //! Determines the new cursor position after pressing the 'Up' arrow key
        //! \param pos The old cursor position
        DLLEXPORT int getOKick(int pos) const;
        //! Determines the new cursor position after pressing the 'Right' arrow
        //! key
        //! \param pos The old cursor position
        DLLEXPORT int getRKick(int pos) const;
        //! Determines the new cursor position after pressing the 'Down' arrow
        //! key
        //! \param pos The old cursor position
        DLLEXPORT int getUKick(int pos) const;
        //! Checks whether the content of another Text occurs in the text
        //! \param t The Text whose content should be searched for
        //! \return (true) if the content of the Text is found. (false)
        //! otherwise
        DLLEXPORT bool has(const Text& t) const;
        //! Checks whether a specific string occurs in the text
        //! \param t The string to search for
        //! \return (true) if the string is found. (false) otherwise
        DLLEXPORT bool has(const char* t) const;
        //! Checks whether a specific string occurs in the text
        //! \param t The string to search for
        //! \param len The length of the string to search for
        //! \return (true) if the string is found. (false) otherwise
        DLLEXPORT bool has(const char* t, int len) const;
        //! Checks whether a specific string occurs in the text
        //! \param searchStartIndex The index from which to start searching
        //! \param t The string to search for
        //! \return (true) if the string is found. (false) otherwise
        DLLEXPORT bool has(int searchStartIndex, const char* t) const;
        //! Checks whether a specific string occurs in the text
        //! \param searchStartIndex The index from which to start searching
        //! \param t The string to search for
        //! \param len The length of the string to search for
        //! \return (true) if the string is found. (false) otherwise
        DLLEXPORT bool has(int searchStartIndex, const char* t, int len) const;
        //! Checks whether the content of another Text occurs at a specific
        //! position
        //! \param pos The position where the string should begin in the text
        //! \param t The Text whose content should be searched for
        //! \return (true) if the content of the Text is found. (false)
        //! otherwise
        DLLEXPORT bool hasAt(int pos, const Text& t) const;
        //! Checks whether a specific string occurs at a specific position
        //! \param pos The position where the string should begin in the text
        //! \param t The string to search for
        //! \return (true) if the string is found. (false) otherwise
        DLLEXPORT bool hasAt(int pos, const char* t) const;
        //! Checks whether a specific string occurs at a specific position
        //! \param pos The position where the string should begin in the text
        //! \param t The string to search for
        //! \param len The length of the string to search for
        //! \return (true) if the string is found. (false) otherwise
        DLLEXPORT bool hasAt(int pos, const char* t, int len) const;
        //! Checks whether a specific character occurs in the text
        //! \param c The character to search for
        //! \return (true) if the character is found. (false) otherwise
        DLLEXPORT bool has(char c) const;
        //! Checks whether the text starts with a specific string
        DLLEXPORT bool beginnsWith(const char* t) const;
        //! Checks whether the text ends with a specific string
        DLLEXPORT bool endsWith(const char* t) const;
        //! Checks whether the text has the same content as a string
        //! \param t The string to compare with
        //! \return (true) if the content of the text equals the string. (false)
        //! otherwise
        DLLEXPORT bool isEqual(const char* t) const;
        //! Checks whether the text has the same content as a string
        //! \param t The string to compare with
        //! \param len The length of the string to compare
        //! \return (true) if the content of the text equals the string. (false)
        //! otherwise
        DLLEXPORT bool isEqual(const char* t, int len) const;
        //! Checks whether the text has the same content as another Text
        //! \param t The Text whose content should be compared
        //! \return (true) if the contents match. (false) otherwise
        DLLEXPORT bool isEqual(const Text& t) const;
        //! Returns the content of the text as a string
        DLLEXPORT const char* getText() const;
        //! Counts how often a specific character occurs in the text
        //! \param c The character to be counted
        //! \return The number of occurrences of the character in the text
        DLLEXPORT int countOf(char c) const;
        //! Counts how often a specific string occurs in the text
        //! \param t The string to be counted
        //! \return The number of occurrences of the string in the text
        DLLEXPORT int countOf(const char* t) const;
        //! Counts how often a specific string occurs in the text
        //! \param t The string to be counted
        //! \param len The length of the string to be counted
        //! \return The number of occurrences of the string in the text
        DLLEXPORT int countOf(const char* t, int len) const;
        //! Counts how often the content of a Text occurs in the text
        //! \param t The Text whose content should be counted
        //! \return The number of occurrences of the text content
        DLLEXPORT int countOf(const Text& t) const;
        //! Returns the first position of a specific character in the text
        //! \param c The character to be found
        //! \return The position of the first occurrence of the character
        DLLEXPORT int positionOf(char c) const;
        //! Returns the first position of a specific string in the text
        //! \param t The string to be found
        //! \return The position of the first occurrence of the string
        DLLEXPORT int positionOf(const char* t) const;
        //! Returns the first position of a specific string in the text
        //! \param len The length of the string to be found
        //! \param t The string to be found
        //! \return The position of the first occurrence of the string
        DLLEXPORT int positionOf(int len, const char* t) const;
        //! Returns the first position of a specific string in the text
        //! \param searchStart Index from which to start searching
        //! \param t The string to be found
        //! \return The position of the first occurrence of the string
        DLLEXPORT int positionOf(
            int searchStart, const char* t, int len) const;
        //! Returns the first position of a Text's content in the text
        //! \param t The Text whose content should be found
        //! \return The position of the first occurrence of the text content
        DLLEXPORT int positionOf(const Text& t) const;
        //! Returns the i-th position of a specific character in the text
        //! \param c The character to be found
        //! \param i Which occurrence should be found
        //! \return The position of the i-th occurrence of the character
        DLLEXPORT int positionOf(char c, int i) const;
        //! Returns the i-th position of a specific string in the text
        //! \param t The string to be found
        //! \param i Which occurrence should be found
        //! \return The position of the i-th occurrence of the string
        DLLEXPORT int positionOf(const char* t, int i) const;
        //! Returns the i-th position of a specific string in the text
        //! \param t The string to be found
        //! \param len The length of the string to be found
        //! \param i Which occurrence should be found
        //! \return The position of the i-th occurrence of the string
        DLLEXPORT int positionOf(int i, int len, const char* t) const;
        //! Returns the i-th position of a Text's content in the text
        //! \param t The Text whose content should be found
        //! \param i Which occurrence should be found
        //! \return The position of the i-th occurrence of the text content
        DLLEXPORT int positionOf(const Text& t, int i) const;
        //! Returns a Text containing a copy of a specific text section
        //!  p1: The start position of the text section
        //!  p2: The end position of the text section (not included)
        DLLEXPORT Text* getTeilText(int p1, int p2) const;
        //! Returns a Text containing a copy of a specific text section
        //!  p1: The start position of the text section (the section extends to
        //!  the end of the text)
        DLLEXPORT Text* getTeilText(int p) const;
        //! Computes the hash code of the text
        DLLEXPORT int hashCode() const;
        //! Appends a number to the end of the text
        DLLEXPORT Text& operator+=(const int num);
        //! Appends a number to the end of the text
        DLLEXPORT Text& operator+=(const __int64 num);
        //! Appends a floating-point number to the end of the text
        DLLEXPORT Text& operator+=(const double num);
        //! Appends a floating-point number to the end of the text
        DLLEXPORT Text& operator+=(const float num);
        //! Appends a string to the end of the text
        DLLEXPORT Text& operator+=(const char* txt);
        //! Appends a copy of the content of a Text to the end of the text
        DLLEXPORT Text& operator+=(const Text& txt);
        //! Sets the content of the text equal to a number
        DLLEXPORT Text& operator=(const int num);
        //! Sets the content of the text equal to a floating-point number
        DLLEXPORT Text& operator=(const double num);
        //! Sets the content of the text equal to a floating-point number
        DLLEXPORT Text& operator=(const float num);
        //! Sets the content of the text equal to a string
        DLLEXPORT Text& operator=(const char* txt);
        //! Sets the content of the text equal to a copy of another Text's
        //! content
        DLLEXPORT Text& operator=(const Text& txt);
        //! Returns the content of the text as a string
        DLLEXPORT operator const char*() const;
        //! Converts the content of the text to a number
        DLLEXPORT explicit operator int() const;
        //! Converts the content of the text to a number
        DLLEXPORT explicit operator __int64() const;
        //! Converts the content of the text to a floating-point number
        DLLEXPORT explicit operator double() const;
        //! Converts the content of the text to a floating-point number
        DLLEXPORT explicit operator float() const;
        //! Checks whether the content of the text comes later in alphabetical
        //! order than the content of another text
        DLLEXPORT bool operator>(Text& t) const;
        //! Checks whether the content of the text comes earlier in alphabetical
        //! order than the content of another text
        DLLEXPORT bool operator<(Text& t) const;
        //! Creates a new Text consisting of this text and t2
        DLLEXPORT Text operator+(const Text& t2) const;
        //! Creates a new Text consisting of this text and t2
        DLLEXPORT Text operator+(const char* t2) const;
        //! Creates a new Text consisting of this text and num
        DLLEXPORT Text operator+(const int num) const;
        //! Creates a new Text consisting of this text and num
        DLLEXPORT Text operator+(const __int64 num) const;
        //! Creates a new Text consisting of this text and num
        DLLEXPORT Text operator+(const double num) const;
        //! Creates a new Text consisting of this text and num
        DLLEXPORT Text operator+(const float num) const;
        //! Checks whether the text matches another text
        DLLEXPORT bool operator==(const Text& right) const;
        //! creates a Text from a char array. the array will be deleted when the
        //! destructor of Text is called
        DLLEXPORT static Text fromArray(char* arr, int len);
        static const Text EMPTY;
    };

    class TextReader : public Reader,
                       public virtual ReferenceCounter
    {
    private:
        Text* txt;
        __int64 lPos;

    public:
        //! Constructor
        //! \param txt The text to be read. It is not copied but read directly.
        DLLEXPORT TextReader(Text* txt);
        //! Destructor
        DLLEXPORT virtual ~TextReader();
        //! Sets the position of the byte to be read next
        //! \param pos The index of the byte
        //! \param ende 1 if the index counts from the end of the text. 0 if the
        //! index counts from the beginning of the text
        DLLEXPORT void setReadPosition(__int64 pos, bool ende) override;
        //! Reads from the text
        //! \param bytes An array to be filled with bytes from the text
        //! \param len How many bytes should be read from the text
        DLLEXPORT void read(char* bytes, int len) override;
        //! Reads the next line of the text
        //! \return The read line as Text with line break
        DLLEXPORT Text* readLine() override;
        //! Checks whether the resource has been fully read
        //!  return 1 if the resource has been fully read. 0 otherwise
        DLLEXPORT bool isEnd() const override;
        //! Returns the index of the byte from the text that would be read next
        //! return -1 if an error occurred. Otherwise the position of the read
        //! pointer
        DLLEXPORT __int64 getReadPosition() const override;
        //! Returns the number of bytes to be read
        DLLEXPORT __int64 getSize() const override;
    };

    //! Searches a string for the num-th occurrence of a specific character
    //! \param string The string to be searched
    //! \param c The character to search for
    //! \param num Which occurrence of the character should be found
    //! \return (-1) if there is no num-th occurrence of the character.
    //! Otherwise the position of the num-th occurrence in the string
    DLLEXPORT int stringPositionOfChar(const char* string,
        char c,
        int num); //! searches the position of the num-th c in string, -1 if not
                  //! found
    //! Searches a string for another string
    //! \param string The string to be searched
    //! \param suche The string to search for
    //! \param sBegPos The position from which to start the search
    //! \return The position where the search string was first found.
    //! (-1) if nothing was found.
    DLLEXPORT int stringPositionOfString(
        const char* string, char* suche, int sBegPos);

    //! Copies a specific string to the operating system's clipboard
    //! \param txt The string to be copied
    DLLEXPORT void TextKopieren(const char* txt);
    //! Determines whether a string is stored in the operating system's
    //! clipboard.
    //! \return The string from the clipboard. If no string was copied, an empty
    //! string is returned.
    DLLEXPORT const char* TextInsert();
    //! Converts a specific writable character to uppercase or lowercase
    //! \param c The character to be converted
    //! \param big If (true), the character is converted to uppercase.
    //! If (false), it is converted to lowercase.
    //! \return The converted character
    DLLEXPORT char smallOrBig(char c, bool big);
    //! Determines whether a character is a printable character
    //! \param zeichen The character to be checked
    //! \return (true) if the character can be drawn. (false) otherwise
    DLLEXPORT bool isWritable(unsigned char zeichen);
    //! Converts a number from a string in any base to a number
    //! \param c The string containing the number
    //! \param system The base of the number
    //! \return The number that was in the text
    DLLEXPORT unsigned int TextZuInt(const char* c, int system);
    //! Converts a number from a string in any base to a number
    //! \param c The string containing the number
    //!  c_ende: Set by the function and may be 0. Points to the next character
    //!  in the string after the number
    //! \param system The base of the number
    //! \return The number that was in the text
    DLLEXPORT unsigned int TextZuInt(const char* c, char** c_ende, int system);
    //! Converts a number from a string in any base to a number
    //! \param c The string containing the number
    //! \param system The base of the number
    //! \return The number that was in the text
    DLLEXPORT unsigned __int64 TextZuInt64(const char* c, int system);
    //! Converts a number from a string in any base to a number
    //! \param c The string containing the number
    //!  c_ende: Set by the function and may be 0. Points to the next character
    //!  in the string after the number
    //! \param system The base of the number
    //! \return The number that was in the text
    DLLEXPORT unsigned __int64 TextZuInt64(
        const char* c, char** c_ende, int system);
    //! Converts a string to a double
    //! \param c The string to be converted
    //! \return The double that was in the string
    DLLEXPORT double TextZuDouble(const char* c);
    //! Converts a string to a float
    //! \param c The string to be converted
    //! \return The float that was in the string
    DLLEXPORT float TextZuFloat(const char* c);
    //! Converts a string to a double
    //! \param c The string to be converted
    //!  c_ende: Set by the function and may be 0. A pointer to the next
    //!  character after the double in the string
    //! \return The double that was in the string
    DLLEXPORT double TextZuDouble(const char* c, char** c_ende);
    //! Converts a string to a float
    //! \param c The string to be converted
    //!  c_ende: Set by the function and may be 0. A pointer to the next
    //!  character after the float in the string
    //! \return The float that was in the string
    DLLEXPORT float TextZuFloat(const char* c, char** c_ende);
    //! Determines the length of a specific string
    //! \param txt The string whose length should be determined
    //! \return The length of the string
    DLLEXPORT int textLength(const char* txt);
} // namespace Framework