/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (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.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */

package org.apache.poi.hwpf.model.types;


import org.apache.poi.util.BitField;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndian;

/**
 * The FFData structure specifies form field data for a text
        box, check box, or drop-down list box. <p>Class and fields
        descriptions are quoted from [MS-DOC] -- v20121003 Word (.doc) Binary
        File Format; Copyright (c) 2012 Microsoft Corporation; Release:
        October 8, 2012
    
 * <p>
 * NOTE: This source is automatically generated please do not modify this file.  Either subclass or
 *       remove the record in src/types/definitions.
 * <p>
 * This class is internal. It content or properties may change without notice 
 * due to changes in our knowledge of internal Microsoft Word binary structures.

 * @author Sergey Vladimirov; according to [MS-DOC] -- v20121003 Word
        (.doc) Binary File Format; Copyright (c) 2012 Microsoft Corporation;
        Release: October 8, 2012
    
 */
@Internal
public abstract class FFDataBaseAbstractType
{

    protected long field_1_version;
    protected short field_2_bits;
    /**/private static final BitField iType = new BitField(0x0003);
    /**   Specifies that the form field is a textbox. */
    /*  */public final static byte ITYPE_TEXT = 0;
    /**   Specifies that the form field is a checkbox. */
    /*  */public final static byte ITYPE_CHCK = 1;
    /**   Specifies that the form field is a dropdown list box. */
    /*  */public final static byte ITYPE_DROP = 2;
    /**/private static final BitField iRes = new BitField(0x007C);
    /**/private static final BitField fOwnHelp = new BitField(0x0080);
    /**/private static final BitField fOwnStat = new BitField(0x0100);
    /**/private static final BitField fProt = new BitField(0x0200);
    /**/private static final BitField iSize = new BitField(0x0400);
    /**/private static final BitField iTypeTxt = new BitField(0x3800);
    /**   Specifies that the textbox value is regular text. */
    /*  */public final static byte ITYPETXT_REG = 0;
    /**   Specifies that the textbox value is a number. */
    /*  */public final static byte ITYPETXT_NUM = 0;
    /**   Specifies that the textbox value is a date or time. */
    /*  */public final static byte ITYPETXT_DATE = 0;
    /**   Specifies that the textbox value is the current date. */
    /*  */public final static byte ITYPETXT_CURDATE = 0;
    /**   Specifies that the textbox value is the current time. */
    /*  */public final static byte ITYPETXT_CURTIME = 0;
    /**   Specifies that the textbox value is calculated from an expression. The expression is given by FFData.xstzTextDef. */
    /*  */protected final static byte ITYPETXT_CALC = 0;
    /**/private static final BitField fRecalc = new BitField(0x4000);
    /**/private static final BitField fHasListBox = new BitField(0x8000);
    protected int field_3_cch;
    protected int field_4_hps;

    protected FFDataBaseAbstractType()
    {
    }

    protected void fillFields( byte[] data, int offset )
    {
        field_1_version                = LittleEndian.getUInt( data, 0x0 + offset );
        field_2_bits                   = LittleEndian.getShort( data, 0x4 + offset );
        field_3_cch                    = LittleEndian.getShort( data, 0x6 + offset );
        field_4_hps                    = LittleEndian.getShort( data, 0x8 + offset );
    }

    public void serialize( byte[] data, int offset )
    {
        LittleEndian.putUInt( data, 0x0 + offset, field_1_version );
        LittleEndian.putShort( data, 0x4 + offset, field_2_bits );
        LittleEndian.putUShort( data, 0x6 + offset, field_3_cch );
        LittleEndian.putUShort( data, 0x8 + offset, field_4_hps );
    }

    public byte[] serialize()
    {
        final byte[] result = new byte[ getSize() ];
        serialize( result, 0 );
        return result;
    }

    /**
     * Size of record
     */
    public static int getSize()
    {
        return 0 + 4 + 2 + 2 + 2;
    }

    @Override
    public boolean equals( Object obj )
    {
        if ( this == obj )
            return true;
        if ( obj == null )
            return false;
        if ( getClass() != obj.getClass() )
            return false;
        FFDataBaseAbstractType other = (FFDataBaseAbstractType) obj;
        if ( field_1_version != other.field_1_version )
            return false;
        if ( field_2_bits != other.field_2_bits )
            return false;
        if ( field_3_cch != other.field_3_cch )
            return false;
        if ( field_4_hps != other.field_4_hps )
            return false;
        return true;
    }

    @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result
                 + (int) ( field_1_version ^ ( field_1_version >>> 32 ) );
        result = prime * result + field_2_bits;
        result = prime * result + field_3_cch;
        result = prime * result + field_4_hps;
        return result;
    }

    public String toString()
    {
        StringBuilder builder = new StringBuilder();

        builder.append("[FFDataBase]\n");
        builder.append( "    .version              = " );
        builder.append(" ( ").append( field_1_version ).append( " )\n" );
        builder.append( "    .bits                 = " );
        builder.append(" ( ").append( field_2_bits ).append( " )\n" );
        builder.append("         .iType                    = ").append(getIType()).append('\n');
        builder.append("         .iRes                     = ").append(getIRes()).append('\n');
        builder.append("         .fOwnHelp                 = ").append(isFOwnHelp()).append('\n');
        builder.append("         .fOwnStat                 = ").append(isFOwnStat()).append('\n');
        builder.append("         .fProt                    = ").append(isFProt()).append('\n');
        builder.append("         .iSize                    = ").append(isISize()).append('\n');
        builder.append("         .iTypeTxt                 = ").append(getITypeTxt()).append('\n');
        builder.append("         .fRecalc                  = ").append(isFRecalc()).append('\n');
        builder.append("         .fHasListBox              = ").append(isFHasListBox()).append('\n');
        builder.append( "    .cch                  = " );
        builder.append(" ( ").append( field_3_cch ).append( " )\n" );
        builder.append( "    .hps                  = " );
        builder.append(" ( ").append( field_4_hps ).append( " )\n" );

        builder.append("[/FFDataBase]");
        return builder.toString();
    }

    /**
     * An unsigned integer that MUST be 0xFFFFFFFF.
     */
    @Internal
    public long getVersion()
    {
        return field_1_version;
    }

    /**
     * An unsigned integer that MUST be 0xFFFFFFFF.
     */
    @Internal
    public void setVersion( long field_1_version )
    {
        this.field_1_version = field_1_version;
    }

    /**
     * An FFDataBits that specifies the type and state of this form field.
     */
    @Internal
    public short getBits()
    {
        return field_2_bits;
    }

    /**
     * An FFDataBits that specifies the type and state of this form field.
     */
    @Internal
    public void setBits( short field_2_bits )
    {
        this.field_2_bits = field_2_bits;
    }

    /**
     * An unsigned integer that specifies the maximum length, in characters, of the value of the textbox. This value MUST NOT exceed 32767. A value of 0 means there is no maximum length of the value of the textbox. If bits.iType is not iTypeText (0), this value MUST be 0..
     */
    @Internal
    public int getCch()
    {
        return field_3_cch;
    }

    /**
     * An unsigned integer that specifies the maximum length, in characters, of the value of the textbox. This value MUST NOT exceed 32767. A value of 0 means there is no maximum length of the value of the textbox. If bits.iType is not iTypeText (0), this value MUST be 0..
     */
    @Internal
    public void setCch( int field_3_cch )
    {
        this.field_3_cch = field_3_cch;
    }

    /**
     * An unsigned integer. If bits.iType is iTypeChck (1), hps specifies the size, in half-points, of the checkbox and MUST be between 2 and 3168, inclusive. If bits.iType is not iTypeChck (1), hps is undefined and MUST be ignored..
     */
    @Internal
    public int getHps()
    {
        return field_4_hps;
    }

    /**
     * An unsigned integer. If bits.iType is iTypeChck (1), hps specifies the size, in half-points, of the checkbox and MUST be between 2 and 3168, inclusive. If bits.iType is not iTypeChck (1), hps is undefined and MUST be ignored..
     */
    @Internal
    public void setHps( int field_4_hps )
    {
        this.field_4_hps = field_4_hps;
    }

    /**
     * Sets the iType field value.
     * An unsigned integer that specifies the type of the form field. 
     */
    @Internal
    public void setIType( byte value )
    {
        field_2_bits = (short)iType.setValue(field_2_bits, value);
    }

    /**
     * An unsigned integer that specifies the type of the form field. 
     * @return  the iType field value.
     */
    @Internal
    public byte getIType()
    {
        return ( byte )iType.getValue(field_2_bits);
    }

    /**
     * Sets the iRes field value.
     * An unsigned integer. If iType is iTypeText (0), then iRes MUST be 0. If iType is iTypeChck (1), iRes specifies the state of the checkbox and MUST be 0 (unchecked), 1 (checked), or 25 (undefined). Undefined checkboxes are treated as unchecked. If iType is iTypeDrop (2), iRes specifies the current selected list box item. A value of 25 specifies the selection is undefined. Otherwise, iRes is a zero-based index into FFData.hsttbDropList.
     */
    @Internal
    public void setIRes( byte value )
    {
        field_2_bits = (short)iRes.setValue(field_2_bits, value);
    }

    /**
     * An unsigned integer. If iType is iTypeText (0), then iRes MUST be 0. If iType is iTypeChck (1), iRes specifies the state of the checkbox and MUST be 0 (unchecked), 1 (checked), or 25 (undefined). Undefined checkboxes are treated as unchecked. If iType is iTypeDrop (2), iRes specifies the current selected list box item. A value of 25 specifies the selection is undefined. Otherwise, iRes is a zero-based index into FFData.hsttbDropList.
     * @return  the iRes field value.
     */
    @Internal
    public byte getIRes()
    {
        return ( byte )iRes.getValue(field_2_bits);
    }

    /**
     * Sets the fOwnHelp field value.
     * A bit that specifies whether the form field has custom help text in FFData.xstzHelpText. If fOwnHelp is 0, FFData.xstzHelpText contains an empty or auto-generated string.
     */
    @Internal
    public void setFOwnHelp( boolean value )
    {
        field_2_bits = (short)fOwnHelp.setBoolean(field_2_bits, value);
    }

    /**
     * A bit that specifies whether the form field has custom help text in FFData.xstzHelpText. If fOwnHelp is 0, FFData.xstzHelpText contains an empty or auto-generated string.
     * @return  the fOwnHelp field value.
     */
    @Internal
    public boolean isFOwnHelp()
    {
        return fOwnHelp.isSet(field_2_bits);
    }

    /**
     * Sets the fOwnStat field value.
     * A bit that specifies whether the form field has custom status bar text in FFData.xstzStatText. If fOwnStat is 0, FFData.xstzStatText contains an empty or auto-generated string.
     */
    @Internal
    public void setFOwnStat( boolean value )
    {
        field_2_bits = (short)fOwnStat.setBoolean(field_2_bits, value);
    }

    /**
     * A bit that specifies whether the form field has custom status bar text in FFData.xstzStatText. If fOwnStat is 0, FFData.xstzStatText contains an empty or auto-generated string.
     * @return  the fOwnStat field value.
     */
    @Internal
    public boolean isFOwnStat()
    {
        return fOwnStat.isSet(field_2_bits);
    }

    /**
     * Sets the fProt field value.
     * A bit that specifies whether the form field is protected and its value cannot be changed.
     */
    @Internal
    public void setFProt( boolean value )
    {
        field_2_bits = (short)fProt.setBoolean(field_2_bits, value);
    }

    /**
     * A bit that specifies whether the form field is protected and its value cannot be changed.
     * @return  the fProt field value.
     */
    @Internal
    public boolean isFProt()
    {
        return fProt.isSet(field_2_bits);
    }

    /**
     * Sets the iSize field value.
     * A bit that specifies whether the size of a checkbox is automatically determined by the text size where the checkbox is located. This value MUST be 0 if iType is not iTypeChck (1).
     */
    @Internal
    public void setISize( boolean value )
    {
        field_2_bits = (short)iSize.setBoolean(field_2_bits, value);
    }

    /**
     * A bit that specifies whether the size of a checkbox is automatically determined by the text size where the checkbox is located. This value MUST be 0 if iType is not iTypeChck (1).
     * @return  the iSize field value.
     */
    @Internal
    public boolean isISize()
    {
        return iSize.isSet(field_2_bits);
    }

    /**
     * Sets the iTypeTxt field value.
     * An unsigned integer that specifies the type of the textbox. If iType is not iTypeText (0), iTypeTxt MUST be 0 and MUST be ignored.
     */
    @Internal
    public void setITypeTxt( byte value )
    {
        field_2_bits = (short)iTypeTxt.setValue(field_2_bits, value);
    }

    /**
     * An unsigned integer that specifies the type of the textbox. If iType is not iTypeText (0), iTypeTxt MUST be 0 and MUST be ignored.
     * @return  the iTypeTxt field value.
     */
    @Internal
    public byte getITypeTxt()
    {
        return ( byte )iTypeTxt.getValue(field_2_bits);
    }

    /**
     * Sets the fRecalc field value.
     * A bit that specifies whether the value of the field is automatically calculated after the field is modified.
     */
    @Internal
    public void setFRecalc( boolean value )
    {
        field_2_bits = (short)fRecalc.setBoolean(field_2_bits, value);
    }

    /**
     * A bit that specifies whether the value of the field is automatically calculated after the field is modified.
     * @return  the fRecalc field value.
     */
    @Internal
    public boolean isFRecalc()
    {
        return fRecalc.isSet(field_2_bits);
    }

    /**
     * Sets the fHasListBox field value.
     * A bit that specifies that the form field has a list box. This value MUST be 1 if iType is iTypeDrop (2). Otherwise, this value MUST be 0.
     */
    @Internal
    public void setFHasListBox( boolean value )
    {
        field_2_bits = (short)fHasListBox.setBoolean(field_2_bits, value);
    }

    /**
     * A bit that specifies that the form field has a list box. This value MUST be 1 if iType is iTypeDrop (2). Otherwise, this value MUST be 0.
     * @return  the fHasListBox field value.
     */
    @Internal
    public boolean isFHasListBox()
    {
        return fHasListBox.isSet(field_2_bits);
    }

}  // END OF CLASS
