
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef Sk64_DEFINED
#define Sk64_DEFINED

#include "SkFixed.h"

/** \class Sk64

    Sk64 is a 64-bit math package that does not require long long support from the compiler.
*/
struct SK_API Sk64 {
    int32_t  fHi;   //!< the high 32 bits of the number (including sign)
    uint32_t fLo;   //!< the low 32 bits of the number

    /** Returns non-zero if the Sk64 can be represented as a signed 32 bit integer
    */
    SkBool is32() const { return fHi == ((int32_t)fLo >> 31); }

    /** Returns non-zero if the Sk64 cannot be represented as a signed 32 bit integer
    */
    SkBool is64() const { return fHi != ((int32_t)fLo >> 31); }

    /** Returns non-zero if the Sk64 can be represented as a signed 48 bit integer. Used to know
        if we can shift the value down by 16 to treat it as a SkFixed.
    */
    SkBool isFixed() const;

    /** Return the signed 32 bit integer equivalent. Asserts that is32() returns non-zero.
    */
    int32_t get32() const { SkASSERT(this->is32()); return (int32_t)fLo; }

    /** Return the number >> 16. Asserts that this does not loose any significant high bits.
    */
    SkFixed getFixed() const {
        SkASSERT(this->isFixed());

        uint32_t sum = fLo + (1 << 15);
        int32_t  hi = fHi;
        if (sum < fLo) {
            hi += 1;
        }
        return (hi << 16) | (sum >> 16);
    }

    /** Return the number >> 30. Asserts that this does not loose any
        significant high bits.
    */
    SkFract getFract() const;

    /** Returns the square-root of the number as a signed 32 bit value. */
    int32_t getSqrt() const;

    /** Returns the number of leading zeros of the absolute value of this.
        Will return in the range [0..64]
    */
    int getClzAbs() const;

    /** Returns non-zero if the number is zero */
    SkBool  isZero() const { return (fHi | fLo) == 0; }

    /** Returns non-zero if the number is non-zero */
    SkBool  nonZero() const { return fHi | fLo; }

    /** Returns non-zero if the number is negative (number < 0) */
    SkBool  isNeg() const { return (uint32_t)fHi >> 31; }

    /** Returns non-zero if the number is positive (number > 0) */
    SkBool  isPos() const { return ~(fHi >> 31) & (fHi | fLo); }

    /** Returns -1,0,+1 based on the sign of the number */
    int     getSign() const { return (fHi >> 31) | Sk32ToBool(fHi | fLo); }

    /** Negate the number */
    void    negate();

    /** If the number < 0, negate the number
    */
    void    abs();

    /** Returns the number of bits needed to shift the Sk64 to the right
        in order to make it fit in a signed 32 bit integer.
    */
    int     shiftToMake32() const;

    /** Set the number to zero */
    void    setZero() { fHi = fLo = 0; }

    /** Set the high and low 32 bit values of the number */
    void    set(int32_t hi, uint32_t lo) { fHi = hi; fLo = lo; }

    /** Set the number to the specified 32 bit integer */
    void    set(int32_t a) { fHi = a >> 31; fLo = a; }

    /** Set the number to the product of the two 32 bit integers */
    void    setMul(int32_t a, int32_t b);

    /** extract 32bits after shifting right by bitCount.
        Note: itCount must be [0..63].
        Asserts that no significant high bits were lost.
    */
    int32_t getShiftRight(unsigned bitCount) const;

    /** Shift the number left by the specified number of bits.
        @param bits How far to shift left, must be [0..63]
    */
    void    shiftLeft(unsigned bits);

    /** Shift the number right by the specified number of bits.
        @param bits How far to shift right, must be [0..63]. This
        performs an arithmetic right-shift (sign extending).
    */
    void    shiftRight(unsigned bits);

    /** Shift the number right by the specified number of bits, but
        round the result.
        @param bits How far to shift right, must be [0..63]. This
        performs an arithmetic right-shift (sign extending).
    */
    void    roundRight(unsigned bits);

    /** Add the specified 32 bit integer to the number */
    void add(int32_t lo) {
        int32_t  hi = lo >> 31; // 0 or -1
        uint32_t sum = fLo + (uint32_t)lo;

        fHi = fHi + hi + (sum < fLo);
        fLo = sum;
    }

    /** Add the specified Sk64 to the number */
    void add(int32_t hi, uint32_t lo) {
        uint32_t sum = fLo + lo;

        fHi = fHi + hi + (sum < fLo);
        fLo = sum;
    }

    /** Add the specified Sk64 to the number */
    void    add(const Sk64& other) { this->add(other.fHi, other.fLo); }

    /** Subtract the specified Sk64 from the number. (*this) = (*this) - num
    */
    void    sub(const Sk64& num);

    /** Subtract the number from the specified Sk64. (*this) = num - (*this)
    */
    void    rsub(const Sk64& num);

    /** Multiply the number by the specified 32 bit integer
    */
    void    mul(int32_t);

    enum DivOptions {
        kTrunc_DivOption,   //!< truncate the result when calling div()
        kRound_DivOption    //!< round the result when calling div()
    };

    /** Divide the number by the specified 32 bit integer, using the specified
        divide option (either truncate or round).
    */
    void    div(int32_t, DivOptions);

    /** return (this + other >> 16) as a 32bit result */
    SkFixed addGetFixed(const Sk64& other) const {
        return this->addGetFixed(other.fHi, other.fLo);
    }

    /** return (this + Sk64(hi, lo) >> 16) as a 32bit result */
    SkFixed addGetFixed(int32_t hi, uint32_t lo) const {
#ifdef SK_DEBUG
        Sk64    tmp(*this);
        tmp.add(hi, lo);
#endif

        uint32_t sum = fLo + lo;
        hi += fHi + (sum < fLo);
        lo = sum;

        sum = lo + (1 << 15);
        if (sum < lo)
            hi += 1;

        hi = (hi << 16) | (sum >> 16);
        SkASSERT(hi == tmp.getFixed());
        return hi;
    }

    /** Return the result of dividing the number by denom, treating the answer
        as a SkFixed. (*this) << 16 / denom. It is an error for denom to be 0.
    */
    SkFixed getFixedDiv(const Sk64& denom) const;

    friend bool operator==(const Sk64& a, const Sk64& b) {
        return a.fHi == b.fHi && a.fLo == b.fLo;
    }

    friend bool operator!=(const Sk64& a, const Sk64& b) {
        return a.fHi != b.fHi || a.fLo != b.fLo;
    }

    friend bool operator<(const Sk64& a, const Sk64& b) {
        return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo < b.fLo);
    }

    friend bool operator<=(const Sk64& a, const Sk64& b) {
        return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo <= b.fLo);
    }

    friend bool operator>(const Sk64& a, const Sk64& b) {
        return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo > b.fLo);
    }

    friend bool operator>=(const Sk64& a, const Sk64& b) {
        return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo >= b.fLo);
    }

#ifdef SkLONGLONG
    SkLONGLONG getLongLong() const;
#endif
};

#endif
