/*************************************************************************
 *
 *  $RCSfile: bigint.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: th $ $Date: 2001/07/25 10:41:59 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _BIGINT_HXX
#define _BIGINT_HXX

#ifndef _SOLAR_H
#include <tools/solar.h>
#endif
#ifndef _TOOLS_STRING_HXX
#include <tools/string.hxx>
#endif

class SvStream;
#ifdef _TLBIGINT_INT64
struct SbxINT64;
struct SbxUINT64;
#endif

// ----------
// - BigInt -
// ----------

#define MAX_DIGITS 8

class BigInt
{
private:
    long            nVal;
    unsigned short  nNum[MAX_DIGITS];
    BYTE            nLen        : 5;    // Aktuelle Laenge
    BOOL            bIsNeg      : 1,    // Is Sign negative
                    bIsBig      : 1,    // TRUE == BigInt
                    bIsSet      : 1;    // Not "Null" (not not 0)

public:
                    BigInt();
                    BigInt( short nVal );
                    BigInt( long nVal );
                    BigInt( int nVal );
                    BigInt( double nVal );
                    BigInt( USHORT nVal );
                    BigInt( ULONG nVal );
                    BigInt( const BigInt& rBigInt );
                    BigInt( const ByteString& rString );
                    BigInt( const UniString& rString );
#ifdef _TLBIGINT_INT64
                    BigInt( const SbxINT64  &r );
                    BigInt( const SbxUINT64 &r );
#endif

    operator        short() const;
    operator        long()  const;
    operator        int()   const;
    operator        double() const;
    operator        USHORT() const;
    operator        ULONG() const;

    void            Set( BOOL bSet ) { bIsSet = bSet; }
    ByteString      GetByteString() const;
    UniString       GetString() const;

    BOOL            IsSet() const { return bIsSet; }
    BOOL            IsNeg() const;
    BOOL            IsZero() const;
    BOOL            IsOne() const;
    BOOL            IsLong() const { return !bIsBig; }
    void            Abs();
    void            DivMod( const BigInt &rDivisor, BigInt &rMod );
#ifdef _TLBIGINT_INT64
    BOOL            INT64 ( SbxINT64  *p ) const;
    BOOL            UINT64( SbxUINT64 *p ) const;
#endif

    BigInt&         operator  =( const BigInt& rVal );
    BigInt&         operator +=( const BigInt& rVal );
    BigInt&         operator -=( const BigInt& rVal );
    BigInt&         operator *=( const BigInt& rVal );
    BigInt&         operator /=( const BigInt& rVal );
    BigInt&         operator %=( const BigInt& rVal );

    BigInt&         operator  =( const short    nValue );
    BigInt&         operator  =( const long     nValue );
    BigInt&         operator  =( const int      nValue );
    BigInt&         operator  =( const USHORT   nValue );

#ifdef __BORLANDC__
    friend          BigInt operator +( const BigInt& rVal1, const BigInt& rVal2 );
    friend          BigInt operator -( const BigInt& rVal1, const BigInt& rVal2 );
    friend          BigInt operator *( const BigInt& rVal1, const BigInt& rVal2 );
    friend          BigInt operator /( const BigInt& rVal1, const BigInt& rVal2 );
    friend          BigInt operator %( const BigInt& rVal1, const BigInt& rVal2 );

    friend          BOOL operator==( const BigInt& rVal1, const BigInt& rVal2 );
    friend          BOOL operator!=( const BigInt& rVal1, const BigInt& rVal2 );
    friend          BOOL operator< ( const BigInt& rVal1, const BigInt& rVal2 );
    friend          BOOL operator> ( const BigInt& rVal1, const BigInt& rVal2 );
    friend          BOOL operator<=( const BigInt& rVal1, const BigInt& rVal2 );
    friend          BOOL operator>=( const BigInt& rVal1, const BigInt& rVal2 );
#else
    friend inline   BigInt operator +( const BigInt& rVal1, const BigInt& rVal2 );
    friend inline   BigInt operator -( const BigInt& rVal1, const BigInt& rVal2 );
    friend inline   BigInt operator *( const BigInt& rVal1, const BigInt& rVal2 );
    friend inline   BigInt operator /( const BigInt& rVal1, const BigInt& rVal2 );
    friend inline   BigInt operator %( const BigInt& rVal1, const BigInt& rVal2 );

    friend          BOOL operator==( const BigInt& rVal1, const BigInt& rVal2 );
    friend inline   BOOL operator!=( const BigInt& rVal1, const BigInt& rVal2 );
    friend          BOOL operator< ( const BigInt& rVal1, const BigInt& rVal2 );
    friend          BOOL operator> ( const BigInt& rVal1, const BigInt& rVal2 );
    friend inline   BOOL operator<=( const BigInt& rVal1, const BigInt& rVal2 );
    friend inline   BOOL operator>=( const BigInt& rVal1, const BigInt& rVal2 );
#endif
};

inline BigInt::BigInt()
{
    bIsSet = FALSE;
    bIsBig = FALSE;
    nVal   = 0;
}

inline BigInt::BigInt( short nValue )
{
    bIsSet = TRUE;
    bIsBig = FALSE;
    nVal   = nValue;
}

inline BigInt::BigInt( long nValue )
{
    bIsSet = TRUE;
    bIsBig = FALSE;
    nVal   = nValue;
}

inline BigInt::BigInt( int nValue )
{
    bIsSet = TRUE;
    bIsBig = FALSE;
    nVal   = nValue;
}

inline BigInt::BigInt( USHORT nValue )
{
    bIsSet = TRUE;
    bIsBig = FALSE;
    nVal   = nValue;
}

inline BigInt::operator short() const
{
    if ( !bIsBig && (nVal == (long)(short)nVal) )
        return (short)nVal;
    else
        return 0;
}

inline BigInt::operator long() const
{
    if ( !bIsBig )
        return nVal;
    else
        return 0;
}

inline BigInt::operator int() const
{
    if ( !bIsBig && (nVal == (long)(int)nVal) )
        return (int)nVal;
    else
        return 0;
}

inline BigInt::operator USHORT() const
{
    if ( !bIsBig && (nVal == (long)(USHORT)nVal) )
        return (USHORT)nVal;
    else
        return 0;
}

inline BigInt& BigInt::operator =( const short nValue )
{
    bIsSet = TRUE;
    bIsBig = FALSE;
    nVal   = nValue;

    return *this;
}

inline BigInt& BigInt::operator =( const long nValue )
{
    bIsSet = TRUE;
    bIsBig = FALSE;
    nVal   = nValue;

    return *this;
}

inline BigInt& BigInt::operator =( const int nValue )
{
    bIsSet = TRUE;
    bIsBig = FALSE;
    nVal   = nValue;

    return *this;
}

inline BigInt& BigInt::operator =( const USHORT nValue )
{
    bIsSet = TRUE;
    bIsBig = FALSE;
    nVal   = nValue;

    return *this;
}

inline BOOL BigInt::IsNeg() const
{
    if ( !bIsBig )
        return (nVal < 0);
    else
        return (BOOL)bIsNeg;
}

inline BOOL BigInt::IsZero() const
{
    if ( bIsBig )
        return FALSE;
    else
        return (nVal == 0);
}

inline BOOL BigInt::IsOne() const
{
    if ( bIsBig )
        return FALSE;
    else
        return (nVal == 1);
}

inline void BigInt::Abs()
{
    if ( bIsBig )
        bIsNeg = FALSE;
    else if ( nVal < 0 )
        nVal = -nVal;
}

inline BigInt operator+( const BigInt &rVal1, const BigInt &rVal2 )
{
    BigInt aErg( rVal1 );
    aErg += rVal2;
    return aErg;
}

inline BigInt operator-( const BigInt &rVal1, const BigInt &rVal2 )
{
    BigInt aErg( rVal1 );
    aErg -= rVal2;
    return aErg;
}

inline BigInt operator*( const BigInt &rVal1, const BigInt &rVal2 )
{
    BigInt aErg( rVal1 );
    aErg *= rVal2;
    return aErg;
}

inline BigInt operator/( const BigInt &rVal1, const BigInt &rVal2 )
{
    BigInt aErg( rVal1 );
    aErg /= rVal2;
    return aErg;
}

inline BigInt operator%( const BigInt &rVal1, const BigInt &rVal2 )
{
    BigInt aErg( rVal1 );
    aErg %= rVal2;
    return aErg;
}

inline BOOL operator!=( const BigInt& rVal1, const BigInt& rVal2 )
{
    return !(rVal1 == rVal2);
}

inline BOOL operator<=( const BigInt& rVal1, const BigInt& rVal2 )
{
    return !( rVal1 > rVal2);
}

inline BOOL operator>=( const BigInt& rVal1, const BigInt& rVal2 )
{
    return !(rVal1 < rVal2);
}

#endif
