// Derived from PDFium's constants/form_flags.h
// Original: Copyright 2018 The PDFium Authors
// Licensed under BSD-3-Clause / Apache-2.0
// See pdfium-upstream/LICENSE for the original license.

//! AcroForm field flag bit values.
//!
//! Corresponds to `pdfium::form_flags` namespace.
//! PDF 1.7 spec, tables 8.70, 8.75, 8.77, 8.79.

// -----------------------------------------------------------------------
// Table 8.70 — field flags common to all field types
// -----------------------------------------------------------------------

/// Field is read-only.
pub const K_READ_ONLY: u32 = 1 << 0;

/// Field value must be supplied before the form is submitted.
pub const K_REQUIRED: u32 = 1 << 1;

/// Field must not be exported by a submit-form action.
pub const K_NO_EXPORT: u32 = 1 << 2;

// -----------------------------------------------------------------------
// Table 8.75 — field flags specific to button fields
// -----------------------------------------------------------------------

/// Radio button: no toggle off (at least one must be selected).
pub const K_BUTTON_NO_TOGGLE_TO_OFF: u32 = 1 << 14;

/// Field is a radio button group.
pub const K_BUTTON_RADIO: u32 = 1 << 15;

/// Field is a pushbutton.
pub const K_BUTTON_PUSHBUTTON: u32 = 1 << 16;

/// Radio buttons in the same group are turned on/off in unison.
pub const K_BUTTON_RADIOS_IN_UNISON: u32 = 1 << 25;

// -----------------------------------------------------------------------
// Table 8.77 — field flags specific to text fields
// -----------------------------------------------------------------------

/// Text field allows multiple lines of text.
pub const K_TEXT_MULTILINE: u32 = 1 << 12;

/// Text in the field is a password and should not be echoed visibly.
pub const K_TEXT_PASSWORD: u32 = 1 << 13;

/// Field is used to select a file whose path is submitted as its value.
pub const K_TEXT_FILE_SELECT: u32 = 1 << 20;

/// Text shall not be spell-checked.
pub const K_TEXT_DO_NOT_SPELL_CHECK: u32 = 1 << 22;

/// Field shall not scroll to accommodate more text than fits in its annotation rectangle.
pub const K_TEXT_DO_NOT_SCROLL: u32 = 1 << 23;

/// Each character in the field is combed into equal-width areas.
pub const K_TEXT_COMB: u32 = 1 << 24;

/// Value of this field shall be a rich text string.
pub const K_TEXT_RICH_TEXT: u32 = 1 << 25;

// -----------------------------------------------------------------------
// Table 8.79 — field flags specific to choice fields
// -----------------------------------------------------------------------

/// Field is a combo box.
pub const K_CHOICE_COMBO: u32 = 1 << 17;

/// Combo box includes an editable text box as well as a drop-down list.
pub const K_CHOICE_EDIT: u32 = 1 << 18;

/// The field's option items shall be sorted alphabetically.
pub const K_CHOICE_SORT: u32 = 1 << 19;

/// More than one item may be selected simultaneously.
pub const K_CHOICE_MULTI_SELECT: u32 = 1 << 21;

/// Text shall not be spell-checked.
pub const K_CHOICE_DO_NOT_SPELL_CHECK: u32 = 1 << 22;

/// Selection shall be committed as soon as it is selected with the pointing device.
pub const K_CHOICE_COMMIT_ON_SEL_CHANGE: u32 = 1 << 26;

// ---------------------------------------------------------------------------
// Tests — verify bit positions match PDF 1.7 spec Tables 8.70, 8.75, 8.77, 8.79
// ---------------------------------------------------------------------------

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_common_field_flags_bit_positions() {
        // Table 8.70: bits 1-3 (0-based: 0-2)
        assert_eq!(K_READ_ONLY, 1 << 0);
        assert_eq!(K_REQUIRED, 1 << 1);
        assert_eq!(K_NO_EXPORT, 1 << 2);
    }

    #[test]
    fn test_button_field_flags_bit_positions() {
        // Table 8.75: bits 15, 16, 17, 26 (0-based: 14, 15, 16, 25)
        assert_eq!(K_BUTTON_NO_TOGGLE_TO_OFF, 1 << 14);
        assert_eq!(K_BUTTON_RADIO, 1 << 15);
        assert_eq!(K_BUTTON_PUSHBUTTON, 1 << 16);
        assert_eq!(K_BUTTON_RADIOS_IN_UNISON, 1 << 25);
    }

    #[test]
    fn test_text_field_flags_bit_positions() {
        // Table 8.77
        assert_eq!(K_TEXT_MULTILINE, 1 << 12);
        assert_eq!(K_TEXT_PASSWORD, 1 << 13);
        assert_eq!(K_TEXT_FILE_SELECT, 1 << 20);
        assert_eq!(K_TEXT_DO_NOT_SPELL_CHECK, 1 << 22);
        assert_eq!(K_TEXT_DO_NOT_SCROLL, 1 << 23);
        assert_eq!(K_TEXT_COMB, 1 << 24);
        assert_eq!(K_TEXT_RICH_TEXT, 1 << 25);
    }

    #[test]
    fn test_choice_field_flags_bit_positions() {
        // Table 8.79
        assert_eq!(K_CHOICE_COMBO, 1 << 17);
        assert_eq!(K_CHOICE_EDIT, 1 << 18);
        assert_eq!(K_CHOICE_SORT, 1 << 19);
        assert_eq!(K_CHOICE_MULTI_SELECT, 1 << 21);
        assert_eq!(K_CHOICE_DO_NOT_SPELL_CHECK, 1 << 22);
        assert_eq!(K_CHOICE_COMMIT_ON_SEL_CHANGE, 1 << 26);
    }

    #[test]
    fn test_all_common_flags_are_disjoint() {
        let common = [K_READ_ONLY, K_REQUIRED, K_NO_EXPORT];
        for (i, &a) in common.iter().enumerate() {
            for (j, &b) in common.iter().enumerate() {
                if i != j {
                    assert_eq!(a & b, 0, "common flags at indices {i} and {j} overlap");
                }
            }
        }
    }
}
