
package uk.co.wingpath.modbus;

/**
* Instances of this class specify how values larger than 16 bits are handled.
* <p>Instances are immutable.
*/
public class BigValueFlags
    implements Cloneable
{
    private final boolean littleEndian;
    private final boolean wordRegisters;
    private final boolean wordCount;

    /**
    * Constructs a {@code BigValueFlags} instance with the specified field
    * values.
    * @param littleEndian whether little-endian or big-endian
    * @param wordRegisters whether registers can hold arbitrary-sized values or
    * only 16 bits
    * @param wordCount whether count in request is number of 16-bit words or
    * number of values
    */
    public BigValueFlags (boolean littleEndian, boolean wordRegisters,
        boolean wordCount)
    {
        this.littleEndian = littleEndian;
        this.wordRegisters = wordRegisters;
        this.wordCount = wordCount;
    }

    /**
    * Constructs a {@code BigValueFlags} instance with all fields set to
    * {@code false}.
    */
    public BigValueFlags ()
    {
        this (false, false, false);
    }

    /**
    * Gets the little-endian flag.
    * @return little-endian flag.
    */
    public boolean getLittleEndian ()
    {
        return littleEndian;
    }

    /**
    * Gets the big-registers flag.
    * @return big-registers flag.
    */
    public boolean getWordRegisters ()
    {
        return wordRegisters;
    }

    /**
    * Gets the word-count flag.
    * @return word-count flag.
    */
    public boolean getWordCount ()
    {
        return wordCount;
    }

    /**
    * Computes how much a register address needs to be incremented to
    * refer to the next register.
    * @param size size of register in bytes.
    * @return address increment.
    */
    public int addressIncrement (int size)
    {
        if (size > 2 && wordRegisters)
            return (size + 1) / 2;
        return 1;
    }

    @Override
    public boolean equals (Object obj)
    {
        if (!(obj instanceof BigValueFlags))
            return false;
        BigValueFlags bvf = (BigValueFlags) obj;
        return littleEndian == bvf.littleEndian &&
            wordRegisters == bvf.wordRegisters &&
            wordCount == bvf.wordCount;
    }

    @Override
    public int hashCode ()
    {
        return (littleEndian ? 4 : 0) +
            (wordRegisters ? 2 : 0) +
            (wordCount ? 1 : 0);
    }

    @Override
    public String toString ()
    {
        return "[BigValueFlags " +
            littleEndian + " " +
            wordRegisters + " " +
            wordCount + "]";
    }
}


