// Modified version of the String class (c) Scott Robert Ladd 1991,1992
// Modifications by Brad Pitzel

#ifndef __STR__
#define __STR__

class String;

#include <stdlib.h>
#include <iostream.h>
#include "stddef.h"

enum StrCompVal  
    {
    SC_LESS, 
    SC_EQUAL, 
    SC_GREATER, 
    SC_ERROR
    };

enum StrCompMode 
    {
    SM_SENSITIVE, 
    SM_IGNORE
    };

enum StrError
    {
    SE_ALLOC, 
    SE_TOO_LONG, 
    SE_INVALID
    };

class String
    {
    public:
        // constructor
        String();
        String(const String & str);
        String(const char * cstr);
        String(size_t count,   char fillCh = '\0');
        String(size_t maxsize, const char * format, ... );

        // destructor
        ~String();

        // version number
        static int Version();

        // value return methods
        size_t Length() const;
        size_t Size() const;

        // create a c-string from String method
        operator const char * () const;

        // assignment method
        String operator = (const String & str);

        // concatenation methods
        friend String operator + (const String & str1, 
                                  const String & str2);

        friend String operator + (const String & str1, char ch);

        void operator += (const String & str);
        void operator += (char ch);

        // comparison methods
        int operator <  (const String & str) const;
        int operator >  (const String & str) const;
        int operator <= (const String & str) const;
        int operator >= (const String & str) const;
        int operator == (const String & str) const;
        int operator != (const String & str) const;

        StrCompVal Compare(const String & str,
                           StrCompMode caseChk = SM_IGNORE) const;

        // substring search methods
	void InsertAfter( char search, String replace );
	

        char Find(const String & str,
                     size_t & pos,
                     StrCompMode caseChk = SM_IGNORE) const;

        // substring deletion method
        void Delete(size_t pos, size_t count);

        // substring insertion methods
        void Insert(size_t pos, char ch);
        void Insert(size_t pos, const String & str);

	// pad string on right to fixed length
	void rPad( size_t len, char ch )
		{ *this += String( len-Length(), ch ); }
		
	void rPad( size_t len )
		{ *this += String( len-Length(), ' ' ); }


        // substring retrieval method
        String Cut(size_t start, size_t count) const;
        String CutHead(size_t count) const;
        String CutTail(size_t count) const;

        // character retrieval method
        char operator [] (size_t pos) const;

        // case-modification methods
        void ToUpper();
        void ToLower();

        String AsUpper() const;
        String AsLower() const;

	double val() {return atof(Txt); }

        // stream input/output methods
        friend ostream & operator << (ostream & strm,
                                      const String & str);

        friend istream & operator >> (istream & strm,
                                      String & str);
	
    private:
        // instance variables
        size_t Siz; // allocated size
        size_t Len; // current length
        char * Txt; // pointer to text


        // class constant
        static size_t AllocIncr;

        // calc alloc size for needed bytes
        static size_t CalcSiz(size_t needed);
    };

// obtain version number
inline int String::Version()
    {
    return 0x0500;
    }

// value return methods
inline size_t String::Length() const
    {
    return Len;
    }

inline size_t String::Size() const
    {
    return Siz;
    }

// add-assignment operator
inline void String::operator += (const String & str)
    {
    if (str.Len>0)
	    *this = *this + str;
    }

inline void String::operator += (char ch)
    {
    *this = *this + ch;
    }

// create a c-string from String method
inline String::operator const char * () const
    {
    return Txt;
    }

// comparison methods
inline int String::operator <  (const String & str) const
    {
    return (Compare(str) == SC_LESS);
    }

inline int String::operator >  (const String & str) const
    {
    return (Compare(str) == SC_GREATER);
    }

inline int String::operator <= (const String & str) const
    {
    return (Compare(str) != SC_GREATER);
    }

inline int String::operator >= (const String & str) const
    {
    return (Compare(str) != SC_LESS);
    }

inline int String::operator == (const String & str) const
    {
    return (Compare(str) == SC_EQUAL);
    }

inline int String::operator != (const String & str) const
    {
    return (Compare(str) != SC_EQUAL);
    }

// character retrieval method
inline char String::operator [] (size_t pos) const
    {
    if (pos >= Len)
        return '\x00';
    else
        return Txt[pos];
    }


// stream I/O functions
inline ostream & operator << (ostream & strm, const String & str)
    {
    if (str.Txt != NULL)
    	strm << str.Txt;

    return strm;
    }


//convert a string to upper or lower case
char *strupr( char *str );
char *strlwr( char *str );

#endif
