/////////////////////////////////////////////////////////////////////////////
//
// File Name : strng.hpp
// File Type : 'CPP' Source File
// Purpose   : Manages character strings.
//
/////////////////////////////////////////////////////////////////////////////

#ifndef STRNG_H
#define STRNG_H

#include    <iostream.h>
#include    <string.h>
#include    <math.h>
#include    <stdlib.h>
#include    <stdio.h>

#include    "object.hpp"
#include    "memalloc.h"

#define LEFT_JUSTIFY    0               // obsolete - use LEFT
#define CENTER_JUSTIFY  1               // obsolete - use CENTER
#define RIGHT_JUSTIFY   2               // obsolete - use RIGHT
#define LEFT            0
#define CENTER          1
#define RIGHT           2
#define NOCLIP          0
#define CLIP            1
#define WHITESPACE      0
//
//  String object definition
//
class String : public Object
{
protected:
    char far  *s;

public:
//
//  Constructors & Destructors
//
    TOOLDLL String();
    TOOLDLL String( const char far *aCharArray );
    TOOLDLL String( const String &aString );
    TOOLDLL String( const unsigned int length );
    isA() { return OBJTYPE_STRING; }

//    String(const char c,                // initialize with a character,
//	 unsigned n = 1);               //   optional # of characters


    ~String();

	// Overloaded new & delete
 	 void *  TOOLDLL operator new(size_t size);
	 void   TOOLDLL operator delete(void *ptr);

    operator const char far * ()	{ return s; }	// char* "cast" operator
//
//  Misc String Methods
//
    void clear()        { operator = ( "" ); }
    String& TOOLDLL lTrim();
    String& TOOLDLL rTrim();
    String& TOOLDLL trim()      { return lTrim().rTrim(); }

//
//  Overloaded Operator Methods
//
    String& TOOLDLL operator =  (const String &aString);
    String& TOOLDLL operator =  (const char far *aCharArray);
    String  TOOLDLL operator  +  (const String &aString);
    String  TOOLDLL operator  +  (const char far *aCharArray);
    String& TOOLDLL operator += (const String &aString);
    String& TOOLDLL operator += (const char far*); // str1 += char*

  String& TOOLDLL operator=(const char);        // str1 = char
  String& TOOLDLL operator=(const int);         // str1 = n
  String& TOOLDLL operator=(const long);        // str1 = n
  String& TOOLDLL operator=(const float);       // str1 = x
  String& TOOLDLL operator=(const double);      // str1 = x
  String& TOOLDLL operator+=(const float);      // str1 += float
  String& TOOLDLL operator+=(const int);        // str1 += int
  String& TOOLDLL operator+=(const char);       // str1 += char
  String& TOOLDLL operator*=(unsigned n);       // str1 *= n

  friend String operator +  (const String&, const String&);
  friend String operator +  (const String&, const char far *);
  friend String operator +  (const char far *,   const String&);
  friend String operator *  (const String&, int n);
  friend int    operator == (const String&, const char far *);
  friend int    operator == (const char far *,   const String&);
  friend int    operator == (const String&, const String&);
  friend int    operator != (const String&, const char far *);
  friend int    operator != (const String&, const String&);
  friend int    operator != (const char far *,   const String&);
  friend int    operator <  (const String&, const char far *);
  friend int    operator <  (const char far *,   const String&);
  friend int    operator <  (const String&,   const String&);
  friend int    operator >  (const String&, const char far *);
  friend int    operator >  (const char far *,   const String&);
  friend int    operator >  (const String&,   const String&);
  friend int    operator <= (const String&, const char far *);
  friend int    operator <= (const char far *,   const String&);
  friend int    operator <= (const String&,   const String&);
  friend int    operator >= (const String&, const char far *);
  friend int    operator >= (const char far *,   const String&);
  friend int    operator >= (const String&,   const String&);

  String& append(const char far *aString)
			    { return operator += ( aString ); }

    unsigned long   size()          { return ( _fstrlen( s ) + 1 ); }
    unsigned int    length()        { return _fstrlen( s ); }
    int             empty()         { return ( *s == '\0' ); }

//
//  String Indexing Methods
//
    char    at( unsigned int anInteger )    { return s[ anInteger ]; }
    char    atPut( unsigned int anInteger, char aChar )
					    { return (s[ anInteger ] = aChar); }
    char    TOOLDLL atRemove( const unsigned int anIndex );

//
//  String conversion methods
//
    int     asInteger()      { return atoi( s ); }
    double  asFloat()        { return atof( s ); }
    long    asLong()         { return atol( s ); }
    char far *asCharArray()  { return s; }
    char far *ptr()          { return s; }
    char far *cptr() const   { return s; }
    String  &toLower()     { strlwr( s ); return *this; }
    String  &toUpper()     { strupr( s ); return *this; }



  const char far * operator()() const                 { return s; }
  const char far * operator()(unsigned pos) const { return s + pos; }
  String      TOOLDLL operator()(unsigned pos, unsigned len);

  int&    TOOLDLL value(int& n);                // convert str to an integer
  long&   TOOLDLL value(long& n);               // convert str to a long int

  String& TOOLDLL left(unsigned len);           // left   len chars
  String& TOOLDLL right(unsigned len);          // right  len chars
  String& TOOLDLL mid(unsigned pos,             // middle len chars from pos
	      unsigned len);
  String& TOOLDLL justify(int mode,             // justify str according to mode
		  unsigned len,
		  int clip=0);

  String& TOOLDLL insert(unsigned pos,          // insert substring
		 const String& s);
  String& TOOLDLL DeleteStr(unsigned pos,          // delete substring
		 unsigned len = 10000);
  char far * TOOLDLL copy(char far *);           // copy str to char* (non-const)

  int     TOOLDLL index(const String& t);       // position of t in str
  String  TOOLDLL subStr(unsigned p,            // substring of str at position p
		 unsigned n=10000);
  int     TOOLDLL split(String far * far *a,    // split str into an array a on
		const String& fs);      //   field separator fs
  int     TOOLDLL sub(const String& from,       // substitute from with to in str
	      const String& to,
	      unsigned count=10000);

/* ----- Stream I/O --------------------------------------------------- */

ostream& TOOLDLL operator << (const String&);

void TOOLDLL operator >>(String&);


};

inline int operator==(const String& s1, const char far* s2) {
  return _fstrcmp(s1.cptr(),s2)==0;
}

inline int operator==(const char far* s1, const String& s2) {
  return _fstrcmp(s1,s2.cptr())==0;
}

inline int operator==(const String& s1, const String& s2) {
  return _fstrcmp(s1.cptr(),s2.cptr())==0;
}

inline int operator!=(const String& s1, const char far *s2) {
  return _fstrcmp(s1.cptr(),s2)!=0;
}

inline int operator!=(const char far *s1, const String& s2) {
  return _fstrcmp(s1,s2.cptr())!=0;
}

inline int operator!=(const String& s1, const String& s2) {
  return _fstrcmp(s1.cptr(), s2.cptr())!=0;
}

inline int operator<(const String& s1, const char far *s2) {
  return _fstrcmp(s1.cptr(),s2)< 0;
}

inline int operator<(const char far *s1, const String& s2) {
  return _fstrcmp(s1,s2.cptr())< 0;
}

inline int operator<(const String& s1, const String& s2) {
  return _fstrcmp(s1.cptr(), s2.cptr())< 0;
}


inline int operator>(const String& s1, const char far *s2) {
  return _fstrcmp(s1.cptr(),s2)> 0;
}

inline int operator>(const char far *s1, const String& s2) {
  return _fstrcmp(s1,s2.cptr())> 0;
}

inline int operator>(const String& s1, const String& s2) {
  return _fstrcmp(s1.cptr(),s2.cptr())> 0;
}

inline int operator<=(const String& s1, const char far *s2) {
  return _fstrcmp(s1.cptr(),s2)<=0;
}

inline int operator<=(const char far *s1, const String& s2) {
  return _fstrcmp(s1,s2.cptr())<=0;
}

inline int operator<=(const String& s1, const String& s2) {
  return _fstrcmp(s1.cptr(), s2.cptr())<=0;
}


inline int operator>=(const String& s1, const char far *s2) {
  return _fstrcmp(s1.cptr(),s2)>=0;
}

inline int operator>=(const char far *s1, const String& s2) {
  return _fstrcmp(s1,s2.cptr())>=0;
}

inline int operator>=(const String& s1, const String& s2) {
  return _fstrcmp(s1.cptr(), s2.cptr())>=0;
}




#endif

