//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / pf
//
//File: integer.h
//
//Version: $Revision: 1.2 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/10/05 07:24:27 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications and Multimedia
//
//Author:
//      Juhana Räsänen
//
//Description:
//      Class for integers using modulo arithmetic
//     This class implements integers that use modulo arithmetic.
//     User selects modulus as a constructor parameter. Most common
//     operators are defined for pfIntegers, in binary operators
//     the other argument can be either pfInteger or unsigned long.
//     NOTE: Some operators return unsigned long instead of class to
//     make them more practical to use.
//
//Copyright:
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//
//Licence:
//
//
//History: 
//
//

#ifndef __PF_INTEGER_H__
#define __PF_INTEGER_H__

#include <typeinfo>

class pfInteger
{
    public:
        explicit pfInteger(unsigned long modulus_);
        pfInteger(const pfInteger &other_);
        virtual ~pfInteger(void);

        unsigned long getValue(void) const;
        unsigned long getModulus(void) const;

        const pfInteger &operator=(unsigned long value_);
        const pfInteger &operator=(const pfInteger &other_);
        int operator==(unsigned long value_) const;
        int operator==(const pfInteger &other_) const;
        int operator!=(unsigned long value_) const;
        int operator!=(const pfInteger &other_) const;
        int operator<(unsigned long value_) const;
        int operator<(const pfInteger &other_) const;
        int operator>(unsigned long value_) const;
        int operator>(const pfInteger &other_) const;
        int operator<=(unsigned long value_) const;
        int operator<=(const pfInteger &other_) const;
        int operator>=(unsigned long value_) const;
        int operator>=(const pfInteger &other_) const;
        unsigned long operator+(unsigned long value_) const;
        unsigned long operator+(const pfInteger &other_) const;
        unsigned long operator-(unsigned long value_) const;
        unsigned long operator-(const pfInteger &other_) const;
        unsigned long operator+=(unsigned long value_);
        unsigned long operator+=(const pfInteger &other_);
        unsigned long operator-=(unsigned long value_);
        unsigned long operator-=(const pfInteger &other_);
        unsigned long operator++(void);
        unsigned long operator--(void);
        unsigned long operator++(int);
        unsigned long operator--(int);

        static int compareWithBase(const pfInteger &left_,
                                   const pfInteger &right_,
                                   const pfInteger &base_);
        
        friend unsigned long operator+(unsigned long lhs_,
                                       const pfInteger &rhs_);
        friend unsigned long operator-(unsigned long lhs_,
                                       const pfInteger &rhs_);
        friend int operator==(unsigned long lhs_,
                              const pfInteger &rhs_);
        friend int operator!=(unsigned long lhs_,
                              const pfInteger &rhs_);
        friend int operator<(unsigned long lhs_,
                             const pfInteger &rhs_);
        friend int operator>(unsigned long lhs_,
                             const pfInteger &rhs_);
        friend int operator<=(unsigned long lhs_,
                              const pfInteger &rhs_);
        friend int operator>=(unsigned long lhs_,
                              const pfInteger &rhs_);

    private:
        unsigned long _value;
        unsigned long _modulus;
};

#endif // __PF_INTEGER_H__

