#ifndef __REAL_H
#define __REAL_H

#ifndef GMDOTH
#include <gmsys1.h>
#include <gfd.h>
#endif

#ifndef __IOSTREAM_H
#include <iostream.h>
#endif

#ifndef __STDTYPES_H
#include <stdtypes.h>
#endif

#ifndef __OBJECT_H
#include <object.h>
#endif

#ifndef __ARRAY_H
#include <array.h>
#endif
// @C
class real : public TObject
{
  // @DPRIV
  DEC _dec;
  // @END

protected:
  virtual TObject* dup() const;
  char* literals() const;
  char* points(int decimals = 0) const;

public:

  static char* eng2ita(char* s);
  static char* ita2eng(const char* s);
  static bool is_real(const char* n);

  // @FPUB
  DEC* ptr() const { return (DEC*)&_dec; }
  char* string(int len = 0, int dec = UNDEFINED, char pad = ' ') const;
  char* stringa(int len = 0, int dec = UNDEFINED, char pad = ' ') const;
  char* string(const char* picture) const;

  int precision() ;
  bool is_zero() const;
  int sign() const;
  int integer() const;  // operator int is too dangerous

  real& round(int prec = 0) ;
  real& trunc(int prec = 0) ;
  real& ceil(int prec = 0);
  real& operator =(double a);
  real& operator =(const real& b);
  real& operator +=(const real& b);
  real& operator +=(double a);
  real& operator -=(const real& b);
  real& operator *=(const real& b);
  real& operator /=(const real& b);
  bool operator !() const { return is_zero(); }
  real operator -() const;

  real();
  real(const real& b);
  real(double a);
  real(const char* s);
  virtual ~real() {}
};

///////////////////////////////////////////////////////////
// Math operators
///////////////////////////////////////////////////////////

ostream& operator <<(ostream& out, const real& a) ;
istream& operator >>(istream& in, real& a) ;

real operator +(const real& a, const real& b) ;
real operator +(double a, const real& b) ;
real operator +(const real& a, double b) ;
real operator -(const real& a, const real& b) ;
real operator -(double a, const real& b) ;
real operator -(const real& a, double b) ;
real operator *(const real& a, const real& b) ;
real operator *(double a, const real& b) ;
real operator *(const real& a, double b) ;
real operator /(const real& a, const real& b) ;
real operator /(double a, const real& b) ;
real operator /(const real& a, double b) ;

bool operator <(const real& a, const real& b) ;
bool operator <(double a, const real& b) ;
bool operator >(const real& a, const real& b) ;
bool operator >(double a, const real& b) ;
bool operator <=(const real& a, const real& b) ;
bool operator <=(double a, const real& b) ;
bool operator >=(const real& a, const real& b) ;
bool operator >=(double a, const real& b) ;
bool operator ==(const real& a, const real& b) ;
bool operator ==(double a, const real& b) ;
bool operator !=(const real& a, const real& b) ;
bool operator !=(double a, const real& b) ;

inline bool operator <(const real& a, double b) { return operator >(b, a); }
inline bool operator >(const real& a, double b) { return operator <(b, a); }
inline bool operator <=(const real& a, double b) { return operator >=(b, a); }
inline bool operator >=(const real& a, double b) { return operator <=(b, a); }
inline bool operator ==(const real& a, double b) { return operator ==(b, a); }
inline bool operator !=(const real& a, double b) { return operator !=(b, a); }

real operator %(const real& a, const long b) ;
void swap(real& a, real& b) ;
real fnc_min(const real& a, const real& b) ;
real fnc_max(const real& a, const real& b) ;
real sqrt(const real& a) ;
real sqr(const real& a) ;
real exp10(const real& a) ;
real pow(const real& a, const real& b) ;
real exp(const real& a) ;
real log10(const real& a) ;
real log(const real& a) ;
real sin(const real& a) ;
real cos(const real& a) ;
real tan(const real& a) ;
real abs(const real& a) ;
extern const real ZERO;

class TDistrib : public TObject
{
  real    _tot;
  real    _prog;
  bool    _ready;
  TArray  _slices;
  int     _current;
  int     _decs;

public:

  void add(real slice);
  real get();

  void init(const real& r);
  void operator =(const real& r) { init(r); }
  const real& last_slice() const
  {
    CHECK(_current,"TDistrib: slices not set");
    return (const real&)_slices[_current-1];
  }
  
  TDistrib(const real& r, int round = UNDEFINED) :
  _prog(0.0), _tot(r), _ready(FALSE),
  _current(0), _decs(round), _slices(4)
  {}
  virtual ~TDistrib() {}  
};



#endif // __REAL_H