#ifndef _BLASR_SDP_FRAGMENT_HPP_
#define _BLASR_SDP_FRAGMENT_HPP_

class Fragment
{
public:
    unsigned int x;
    unsigned int y;
    unsigned int weight;
    unsigned int length;
    int index;
    int chainPrev;
    int cost;
    int above;
    unsigned int chainLength;

    inline Fragment(unsigned int px, unsigned int py, int pweight = 0);

    inline Fragment();

    unsigned int GetX() const { return x; }

    unsigned int GetY() const { return y; }

    bool SetAbove(int a);
    bool GetAbove(int &a);

    inline int LessThanXY(const Fragment &f) const;

    inline int LessThanYX(const Fragment &f) const;

    inline int operator<(const Fragment &f) const;

    inline Fragment &operator=(const Fragment &rhs);

    inline int operator==(const Fragment &f) const;

    int operator>(const Fragment &f) const;

    int GetLength();

    void SetLength(int _length);
};

inline Fragment::Fragment(unsigned int px, unsigned int py, int pweight)
{
    x = px;
    y = py;
    weight = pweight;
    length = index = 0;
    chainPrev = cost = chainLength = 0;
    above = -1;
}

//
// Provide default constructor that will
// give bad results if members are not properly initialized
// later on.
//
inline Fragment::Fragment()
{
    x = -1;
    y = -1;
    weight = length = index = 0;
    chainPrev = cost = chainLength = 0;
    above = -1;
}

inline int Fragment::LessThanXY(const Fragment &f) const
{
    if (x == f.x) {
        if (y == f.y) {
            if (length == f.length)
                return 0;
            else
                return length < f.length;
        } else
            return y < f.y;
    } else
        return x < f.x;
    /*
    if (x < f.x)
        return 1;
    else if (x == f.x)
        return y < f.y;
    else
        return 0;
    */
}

inline int Fragment::LessThanYX(const Fragment &f) const
{
    if (y == f.y) {
        if (x == f.x) {
            if (length == f.length)
                return 0;
            else
                return length < f.length;
        } else
            return x < f.x;
    } else
        return y < f.y;
    /*
    if (y < f.y)
        return 1;
    else if (y == f.y)
        return x < f.x;
    else
        return 0;
    */
}

inline Fragment &Fragment::operator=(const Fragment &rhs)
{
    x = rhs.x;
    y = rhs.y;
    index = rhs.index;
    cost = rhs.cost;
    weight = rhs.weight;
    length = rhs.length;
    chainLength = rhs.chainLength;
    chainPrev = rhs.chainPrev;
    above = rhs.above;
    return *this;
}

inline int Fragment::operator==(const Fragment &f) const { return (x == f.x and y == f.y); }

inline int Fragment::operator<(const Fragment &f) const
{
    //
    // Sort fragments by diagonal:
    //
    int diag, fDiag;
    diag = (y - x);
    fDiag = f.y - f.x;
    if (diag < fDiag)
        return 1;
    else if (diag == fDiag)
        return (x < f.x);
    else
        return 0;
}

#endif  // _BLASR_SDP_FRAGMENT_HPP_
