#ifndef _CHAIN_H_INCLUDED_
#define _CHAIN_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// Chain.h
// --------
// String class definition
//                                                         
// Design and Implementation by Bjoern Lemke               
//                                                         
// (C)opyright 2000-2016 Bjoern Lemke                        
//
// INTERFACE MODULE
//
// Class: Chain
// 
// Description: All base operations on strings
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// INCLUDES

#include <iostream>
using namespace std;

// To improve performance, string values are statically allocated with STATICBUFSIZE
// String values greater than this have to be allocated dynamically

#define STATICBUFSIZE 100

class Chain {

public:
  
  Chain();
  Chain(const char* s);
  Chain(const char* s, int len);
  Chain(const Chain& str);
  Chain(const char c);

  Chain(unsigned long ul);
  Chain(unsigned long long ull);
  Chain(long l);
  Chain(long long ll);

  Chain(unsigned ui);
  Chain(int i);
  Chain(float l);
  Chain(double l, const char* format = "%f");
  
  ~Chain();

  void setData(char* s);

  // member methods
  unsigned long length() const;
  unsigned long visibleLength() const;
  Chain toUpper() const;
  Chain toLower() const;

  int asUnsigned(bool doStrict) const;
  int asInteger(bool doStrict = false) const;
  long asLong(bool doStrict = false) const;
  unsigned long asUnsignedLong(bool doStrict = false) const;
  long long asLongLong(bool doStrict = false) const;
  unsigned long long asUnsignedLongLong(bool doStrict = false) const;

  bool asBool() const;
  bool isNum() const;
  bool isDec() const;
  float asFloat() const;
  double asDouble() const;
  short asShort() const;
  char asChar() const;

  Chain cutTrailing(const Chain& str) const;
  Chain truncLeft(const Chain& str) const;
  Chain truncRight(const Chain& str) const;

  bool posStr(const Chain& s1, int& result, int start = 0, int occur = 1) const;
    
  bool replace(const Chain& s1, const Chain& s2, Chain& result) const;
  int replaceAll(const Chain& s1, const Chain& s2, Chain& result) const;

  void setChar(int i, char c);

  int getHashPos(int hashSize) const;

  // member operators

  char operator[] (int i) const;
  Chain subChain(int l, int u) const;
  operator char* () const;
  Chain& operator = ( const Chain& str);
  Chain& operator += ( const Chain& str);
  bool operator == ( const Chain& str) const;
  bool operator != ( const Chain& str) const;
  bool operator < ( const Chain& str) const;
  bool operator > ( const Chain& str) const;
  bool operator <= ( const Chain& str) const;
  bool operator >= ( const Chain& str) const;

  // friend operators
  friend Chain operator + ( const Chain& str1, const Chain& str2);
  friend ostream& operator << (ostream& s, const  Chain& str);  
  friend istream& operator >> (istream& s, Chain &str);

private:

  bool matchAtPos(const Chain& s1, int pos) const;

  char *_buf;
  unsigned long _len;
  char _staticBuf[STATICBUFSIZE];

};

#endif
