//
//Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
//Copyright (C) 2013 LunarG, Inc.
//
//All rights reserved.
//
//Redistribution and use in source and binary forms, with or without
//modification, are permitted provided that the following conditions
//are met:
//
//    Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//
//    Redistributions in binary form must reproduce the above
//    copyright notice, this list of conditions and the following
//    disclaimer in the documentation and/or other materials provided
//    with the distribution.
//
//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
//    contributors may be used to endorse or promote products derived
//    from this software without specific prior written permission.
//
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
//POSSIBILITY OF SUCH DAMAGE.
//

#ifndef _CONSTANT_UNION_INCLUDED_
#define _CONSTANT_UNION_INCLUDED_

namespace glslang {

class TConstUnion {
public:
    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())

    TConstUnion() : iConst(0), type(EbtInt) { }

    void setIConst(int i)
    { 
        iConst = i; 
        type = EbtInt;
    }

    void setUConst(unsigned int u)
    {
        uConst = u; 
        type = EbtUint;
    }

    void setDConst(double d)
    {
        dConst = d; 
        type = EbtDouble;
    }

    void setBConst(bool b)
    {
        bConst = b; 
        type = EbtBool;
    }

    int getIConst() const          { return iConst; }
    unsigned int getUConst() const { return uConst; }
    double getDConst() const       { return dConst; }
    bool getBConst() const         { return bConst; }

    bool operator==(const int i) const
    {
        if (i == iConst)
            return true;

        return false;
    }

    bool operator==(unsigned const int u) const
    {
        if (u == uConst)
            return true;

        return false;
    }

    bool operator==(const double d) const
    {
        if (d == dConst)
            return true;

        return false;
    }

    bool operator==(const bool b) const
    {
        if (b == bConst)
            return true;

        return false;
    }

    bool operator==(const TConstUnion& constant) const
    {
        if (constant.type != type)
            return false;

        switch (type) {
        case EbtInt:
            if (constant.iConst == iConst)
                return true;

            break;
        case EbtUint:
            if (constant.uConst == uConst)
                return true;

            break;
        case EbtDouble:
            if (constant.dConst == dConst)
                return true;

            break;
        case EbtBool:
            if (constant.bConst == bConst)
                return true;

            break;
        default:
            assert(false && "Default missing");
        }

        return false;
    }

    bool operator!=(const int i) const
    {
        return !operator==(i);
    }

    bool operator!=(const unsigned int u) const
    {
        return !operator==(u);
    }

    bool operator!=(const float f) const
    {
        return !operator==(f);
    }

    bool operator!=(const bool b) const
    {
        return !operator==(b);
    }

    bool operator!=(const TConstUnion& constant) const
    {
        return !operator==(constant);
    }

    bool operator>(const TConstUnion& constant) const
    { 
        assert(type == constant.type);
        switch (type) {
        case EbtInt:
            if (iConst > constant.iConst)
                return true;

            return false;
        case EbtUint:
            if (uConst > constant.uConst)
                return true;

            return false;
        case EbtDouble:
            if (dConst > constant.dConst)
                return true;

            return false;
        default:
            assert(false && "Default missing");
            return false;
        }
    }

    bool operator<(const TConstUnion& constant) const
    { 
        assert(type == constant.type);
        switch (type) {
        case EbtInt:
            if (iConst < constant.iConst)
                return true;

            return false;
        case EbtUint:
            if (uConst < constant.uConst)
                return true;

            return false;
        case EbtDouble:
            if (dConst < constant.dConst)
                return true;

            return false;
        default:
            assert(false && "Default missing");
            return false;
        }
    }

    TConstUnion operator+(const TConstUnion& constant) const
    { 
        TConstUnion returnValue;
        assert(type == constant.type);
        switch (type) {
        case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
        case EbtUint: returnValue.setUConst(uConst + constant.uConst); break;
        case EbtDouble: returnValue.setDConst(dConst + constant.dConst); break;
        default: assert(false && "Default missing");
        }

        return returnValue;
    }

    TConstUnion operator-(const TConstUnion& constant) const
    { 
        TConstUnion returnValue;
        assert(type == constant.type);
        switch (type) {
        case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
        case EbtUint: returnValue.setUConst(uConst - constant.uConst); break;
        case EbtDouble: returnValue.setDConst(dConst - constant.dConst); break;
        default: assert(false && "Default missing");
        }

        return returnValue;
    }

    TConstUnion operator*(const TConstUnion& constant) const
    { 
        TConstUnion returnValue;
        assert(type == constant.type);
        switch (type) {
        case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
        case EbtUint: returnValue.setUConst(uConst * constant.uConst); break;
        case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break; 
        default: assert(false && "Default missing");
        }

        return returnValue;
    }

    TConstUnion operator%(const TConstUnion& constant) const
    { 
        TConstUnion returnValue;
        assert(type == constant.type);
        switch (type) {
        case EbtInt:  returnValue.setIConst(iConst % constant.iConst); break;
        case EbtUint: returnValue.setUConst(uConst % constant.uConst); break;
        default:     assert(false && "Default missing");
        }

        return returnValue;
    }

    TConstUnion operator>>(const TConstUnion& constant) const
    { 
        TConstUnion returnValue;
        switch (type) {
        case EbtInt:
            switch (constant.type) {
            case EbtInt:   returnValue.setIConst(iConst >> constant.iConst); break;
            case EbtUint:  returnValue.setIConst(iConst >> constant.uConst); break;
            default:       assert(false && "Default missing");           
            }
            break;
        case EbtUint:
            switch (constant.type) {
            case EbtInt:   returnValue.setUConst(uConst >> constant.iConst); break;
            case EbtUint:  returnValue.setUConst(uConst >> constant.uConst); break;
            default:       assert(false && "Default missing");           
            }
            break;
        default:     assert(false && "Default missing");
        }

        return returnValue;
    }

    TConstUnion operator<<(const TConstUnion& constant) const
    { 
        TConstUnion returnValue;
        switch (type) {
        case EbtInt:
            switch (constant.type) {
            case EbtInt:   returnValue.setIConst(iConst << constant.iConst); break;
            case EbtUint:  returnValue.setIConst(iConst << constant.uConst); break;
            default:       assert(false && "Default missing");           
            }
            break;
        case EbtUint:
            switch (constant.type) {
            case EbtInt:   returnValue.setUConst(uConst << constant.iConst); break;
            case EbtUint:  returnValue.setUConst(uConst << constant.uConst); break;
            default:       assert(false && "Default missing");           
            }
            break;
        default:     assert(false && "Default missing");
        }

        return returnValue;
    }

    TConstUnion operator&(const TConstUnion& constant) const
    { 
        TConstUnion returnValue;
        assert(type == constant.type);
        switch (type) {
        case EbtInt:  returnValue.setIConst(iConst & constant.iConst); break;
        case EbtUint: returnValue.setUConst(uConst & constant.uConst); break;
        default:     assert(false && "Default missing");
        }

        return returnValue;
    }

    TConstUnion operator|(const TConstUnion& constant) const
    { 
        TConstUnion returnValue;
        assert(type == constant.type);
        switch (type) {
        case EbtInt:  returnValue.setIConst(iConst | constant.iConst); break;
        case EbtUint: returnValue.setUConst(uConst | constant.uConst); break;
        default:     assert(false && "Default missing");
        }

        return returnValue;
    }

    TConstUnion operator^(const TConstUnion& constant) const
    { 
        TConstUnion returnValue;
        assert(type == constant.type);
        switch (type) {
        case EbtInt:  returnValue.setIConst(iConst ^ constant.iConst); break;
        case EbtUint: returnValue.setUConst(uConst ^ constant.uConst); break;
        default:     assert(false && "Default missing");
        }

        return returnValue;
    }

    TConstUnion operator~() const
    { 
        TConstUnion returnValue;
        switch (type) {
        case EbtInt:  returnValue.setIConst(~iConst); break;
        case EbtUint: returnValue.setUConst(~uConst); break;
        default:     assert(false && "Default missing");
        }

        return returnValue;
    }

    TConstUnion operator&&(const TConstUnion& constant) const
    { 
        TConstUnion returnValue;
        assert(type == constant.type);
        switch (type) {
        case EbtBool: returnValue.setBConst(bConst && constant.bConst); break;
        default:     assert(false && "Default missing");
        }

        return returnValue;
    }

    TConstUnion operator||(const TConstUnion& constant) const
    { 
        TConstUnion returnValue;
        assert(type == constant.type);
        switch (type) {
        case EbtBool: returnValue.setBConst(bConst || constant.bConst); break;
        default:     assert(false && "Default missing");
        }

        return returnValue;
    }

    TBasicType getType() const { return type; }

private:
    union  {
        int iConst;          // used for ivec, scalar ints
        unsigned int uConst; // used for uvec, scalar uints
        bool bConst;         // used for bvec, scalar bools
        double dConst;       // used for vec, dvec, mat, dmat, scalar floats and doubles
    };

    TBasicType type;
};

// Encapsulate having a pointer to an array of TConstUnion,
// which only needs to be allocated if it's size is going to be
// bigger than 0.
//
// One convenience is being able to use [] to go inside the array, instead
// of C++ assuming it as an array of pointers to vectors.
//
// General usage is that the size is known up front, and it is 
// created once with the proper size.
//
class TConstUnionArray {
public:
    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())

    TConstUnionArray() : unionArray(nullptr) { }
    virtual ~TConstUnionArray() { }

    explicit TConstUnionArray(int size)
    {
        if (size == 0)
            unionArray = nullptr;
        else
            unionArray =  new TConstUnionVector(size);
    }
    TConstUnionArray(const TConstUnionArray& a) : unionArray(a.unionArray) { }
    TConstUnionArray(const TConstUnionArray& a, int start, int size)
    {
        unionArray = new TConstUnionVector(size);
        for (int i = 0; i < size; ++i)
            (*unionArray)[i] = a[start + i];
    }

    // Use this constructor for a smear operation
    TConstUnionArray(int size, const TConstUnion& val)
    {
        unionArray = new TConstUnionVector(size, val);
    }

    int size() const { return unionArray ? (int)unionArray->size() : 0; }
    TConstUnion& operator[](size_t index) { return (*unionArray)[index]; }
    const TConstUnion& operator[](size_t index) const { return (*unionArray)[index]; }
    bool operator==(const TConstUnionArray& rhs) const
    {
        // this includes the case that both are unallocated
        if (unionArray == rhs.unionArray)
            return true;

        if (! unionArray || ! rhs.unionArray)
            return false;

        if (! unionArray || ! rhs.unionArray)
            return false;

        return *unionArray == *rhs.unionArray;
    }
    bool operator!=(const TConstUnionArray& rhs) const { return ! operator==(rhs); }

    double dot(const TConstUnionArray& rhs)
    {
        assert(rhs.unionArray->size() == unionArray->size());
        double sum = 0.0;

        for (size_t comp = 0; comp < unionArray->size(); ++comp)
            sum += (*this)[comp].getDConst() * rhs[comp].getDConst();

        return sum;
    }

    bool empty() const { return unionArray == nullptr; }

protected:
    typedef TVector<TConstUnion> TConstUnionVector;
    TConstUnionVector* unionArray;
};

} // end namespace glslang

#endif // _CONSTANT_UNION_INCLUDED_
