///|
/// CSS border-collapse property (for tables)
pub(all) enum BorderCollapse {
  Separate // Default - borders have spacing
  Collapse // Adjacent borders merge
} derive(Show, Eq)

///|
/// Table layout algorithm
pub(all) enum TableLayout {
  Auto // Default - column widths based on content
  Fixed // Column widths based on first row only
} derive(Show, Eq)

///|
/// CSS caption-side property (for table captions)
pub(all) enum CaptionSide {
  Top // Caption above the table (default)
  Bottom // Caption below the table
} derive(Show, Eq)

///|
/// CSS white-space property (for text wrapping)
pub(all) enum WhiteSpace {
  Normal // Default - collapse whitespace, wrap text
  Nowrap // Collapse whitespace, no wrapping
  Pre // Preserve whitespace, only wrap at newlines
  PreWrap // Preserve whitespace, wrap when needed
  PreLine // Collapse whitespace, wrap at newlines
} derive(Show, Eq)

///|
/// CSS writing-mode property (for text direction and flow)
pub(all) enum WritingMode {
  HorizontalTb // Default - left-to-right, top-to-bottom
  VerticalRl // Top-to-bottom, right-to-left (e.g., traditional Japanese)
  VerticalLr // Top-to-bottom, left-to-right (e.g., Mongolian)
} derive(Show, Eq)

///|
/// Check if writing mode is vertical
pub fn WritingMode::is_vertical(self : WritingMode) -> Bool {
  match self {
    HorizontalTb => false
    VerticalRl | VerticalLr => true
  }
}

///|
/// Check if block direction is right-to-left (vertical-rl)
/// In vertical-rl, blocks flow from right to left
pub fn WritingMode::is_block_rtl(self : WritingMode) -> Bool {
  match self {
    VerticalRl => true
    HorizontalTb | VerticalLr => false
  }
}

///|
/// CSS direction property (for inline text direction)
pub(all) enum Direction {
  Ltr // Left-to-right (default)
  Rtl // Right-to-left (e.g., Arabic, Hebrew)
} derive(Show, Eq)

///|
/// Check if direction is right-to-left
pub fn Direction::is_rtl(self : Direction) -> Bool {
  match self {
    Rtl => true
    Ltr => false
  }
}

///|
/// CSS visibility property
pub(all) enum Visibility {
  Visible // Element is visible (default)
  Hidden // Element is invisible but takes up space
  Collapse // Same as hidden for most elements
} derive(Show, Eq)

///|
/// CSS z-index property
pub(all) enum ZIndex {
  Auto // Stacking order determined by DOM order
  Value(Int) // Explicit stacking level
} derive(Show, Eq)

///|
/// CSS transform translate value (can be length or percent)
pub(all) enum TranslateValue {
  Length(Double) // Fixed length in pixels
  Percent(Double) // Percentage of element's own dimension (0.0 - 1.0)
} derive(Show, Eq)

///|
/// CSS transform property - list of transform functions
/// Supports translate and scale for layout purposes
pub(all) struct Transform {
  translate_x : TranslateValue // translateX or first arg of translate()
  translate_y : TranslateValue // translateY or second arg of translate()
  scale_x : Double // scaleX or first arg of scale() (default 1.0)
  scale_y : Double // scaleY or second arg of scale() (default 1.0)
} derive(Show, Eq)

///|
/// Create a none/identity transform
pub fn Transform::none() -> Transform {
  {
    translate_x: TranslateValue::Length(0.0),
    translate_y: TranslateValue::Length(0.0),
    scale_x: 1.0,
    scale_y: 1.0,
  }
}

///|
/// Check if transform is identity (no visual change)
pub fn Transform::is_none(self : Transform) -> Bool {
  let translate_none = match (self.translate_x, self.translate_y) {
    (TranslateValue::Length(0.0), TranslateValue::Length(0.0)) => true
    (TranslateValue::Percent(0.0), TranslateValue::Percent(0.0)) => true
    _ => false
  }
  let scale_none = self.scale_x == 1.0 && self.scale_y == 1.0
  translate_none && scale_none
}

///|
/// Check if transform has scale applied
pub fn Transform::has_scale(self : Transform) -> Bool {
  self.scale_x != 1.0 || self.scale_y != 1.0
}

///|
/// Compute translate X offset given element width
pub fn Transform::compute_translate_x(
  self : Transform,
  element_width : Double,
) -> Double {
  match self.translate_x {
    TranslateValue::Length(v) => v
    TranslateValue::Percent(p) => element_width * p
  }
}

///|
/// Compute translate Y offset given element height
pub fn Transform::compute_translate_y(
  self : Transform,
  element_height : Double,
) -> Double {
  match self.translate_y {
    TranslateValue::Length(v) => v
    TranslateValue::Percent(p) => element_height * p
  }
}

///|
/// CSS contain property - uses flags since multiple values can be combined
/// e.g., "contain: layout paint" or "contain: strict"
pub(all) struct Contain {
  size : Bool // Size containment - element size computed independently
  inline_size : Bool // Inline-size containment only (mutually exclusive with size)
  layout : Bool // Layout containment - isolates internal layout
  paint : Bool // Paint containment - clips overflow, creates stacking context
  style : Bool // Style containment - scopes counters/quotes
} derive(Show, Eq)

///|
pub fn Contain::none() -> Contain {
  { size: false, inline_size: false, layout: false, paint: false, style: false }
}

///|
/// strict = size + layout + paint + style
pub fn Contain::strict() -> Contain {
  { size: true, inline_size: false, layout: true, paint: true, style: true }
}

///|
/// content = layout + paint + style (no size)
pub fn Contain::content() -> Contain {
  { size: false, inline_size: false, layout: true, paint: true, style: true }
}

///|
pub fn Contain::has_containment(self : Contain) -> Bool {
  self.size || self.inline_size || self.layout || self.paint || self.style
}

///|
/// Vertical alignment for inline elements
pub(all) enum VerticalAlign {
  Baseline // Align baseline (default, simplified to bottom for now)
  Top // Align to top of line box
  Middle // Align middle
  Bottom // Align to bottom of line box
  TextTop // Align to top of parent's font (simplified to Top)
  TextBottom // Align to bottom of parent's font (simplified to Bottom)
  Sub // Subscript position
  Super // Superscript position
} derive(Show, Eq)

///|
/// CSS Style definition for layout computation
/// All fields are mutable to support Yoga-like setter API
pub(all) struct Style {
  mut display : @types.Display
  mut position : @types.Position
  mut float : @types.Float
  mut clear : @types.Clear
  // Box sizing
  mut box_sizing : @types.BoxSizing
  // Overflow
  mut overflow_x : @types.Overflow
  mut overflow_y : @types.Overflow
  // Sizing
  mut width : @types.Dimension
  mut height : @types.Dimension
  mut min_width : @types.Dimension
  mut min_height : @types.Dimension
  mut max_width : @types.Dimension
  mut max_height : @types.Dimension
  // Box model
  mut margin : @types.Rect[@types.Dimension]
  mut padding : @types.Rect[@types.Dimension]
  mut border : @types.Rect[@types.Dimension]
  // Flexbox
  mut flex_direction : @types.FlexDirection
  mut flex_wrap : @types.FlexWrap
  mut justify_content : @types.Alignment
  mut align_items : @types.Alignment
  mut align_content : @types.Alignment
  mut align_self : @types.AlignSelf
  mut flex_grow : Double
  mut flex_shrink : Double
  mut flex_basis : @types.Dimension
  mut order : Int // Flex item order (default 0)
  // Gap
  mut row_gap : @types.Dimension
  mut column_gap : @types.Dimension
  // Aspect ratio (width / height)
  mut aspect_ratio : Double?
  // Inset for position: absolute (left, right, top, bottom)
  mut inset : @types.Rect[@types.Dimension]
  // Grid container properties
  mut grid_template_rows : Array[@types.TrackSizingFunction]
  mut grid_template_columns : Array[@types.TrackSizingFunction]
  mut grid_auto_rows : Array[@types.TrackSizingFunction]
  mut grid_auto_columns : Array[@types.TrackSizingFunction]
  mut grid_auto_flow : @types.GridAutoFlow
  // Grid template areas (each string is a row, e.g. ["header header", "sidebar main"])
  mut grid_template_areas : Array[String]
  // Grid item properties
  mut grid_row : @types.GridLine
  mut grid_column : @types.GridLine
  mut grid_area : String? // Named area for item placement
  // justify-items for grid (different from justify-content)
  mut justify_items : @types.Alignment
  // justify-self for grid items (horizontal self-alignment)
  mut justify_self : @types.AlignSelf
  // Font properties (for baseline calculation)
  mut font_size : Double // Computed font size in pixels (default 16.0)
  mut line_height : Double // Computed line height in pixels (default = font_size)
  // Text wrapping and direction
  mut white_space : WhiteSpace // white-space: normal | nowrap | pre | pre-wrap | pre-line
  mut writing_mode : WritingMode // writing-mode: horizontal-tb | vertical-rl | vertical-lr
  mut direction : Direction // direction: ltr | rtl (inline text direction)
  // Vertical alignment for inline elements
  mut vertical_align : VerticalAlign
  // Clip (legacy, deprecated but widely used for a11y)
  mut clip : @types.ClipRect
  // Paint properties (visual, not layout)
  mut visibility : Visibility
  mut z_index : ZIndex
  mut opacity : Double // 0.0 = transparent, 1.0 = opaque
  // Color properties (resolved RGBA values)
  mut color : @types.Color // Text color (inherited)
  mut background_color : @types.Color // Background color (not inherited)
  // Containment (for layout optimization)
  mut contain : Contain
  // CSS transform (visual offset, applied in paint phase)
  mut transform : Transform
  // CSS zoom (affects layout scaling, inherited)
  mut zoom : Double // zoom factor (1.0 = 100%, 2.0 = 200%)
  // Table properties
  mut border_spacing : Double // border-spacing in pixels (horizontal and vertical, simplified)
  mut border_collapse : BorderCollapse // border-collapse: separate | collapse
  mut table_layout : TableLayout // table-layout: auto | fixed
  mut caption_side : CaptionSide // caption-side: top | bottom
  // Table cell properties (from HTML attributes)
  mut rowspan : Int // rowspan attribute (default 1)
  mut colspan : Int // colspan attribute (default 1)
}

///|
pub fn Style::default() -> Style {
  {
    display: @types.Block,
    position: @types.Static,
    float: @types.Float::None,
    clear: @types.Clear::None,
    box_sizing: @types.ContentBox,
    overflow_x: @types.Visible,
    overflow_y: @types.Visible,
    width: @types.Auto,
    height: @types.Auto,
    min_width: @types.Auto,
    min_height: @types.Auto,
    max_width: @types.Auto,
    max_height: @types.Auto,
    margin: {
      left: @types.Length(0.0),
      right: @types.Length(0.0),
      top: @types.Length(0.0),
      bottom: @types.Length(0.0),
    },
    padding: {
      left: @types.Length(0.0),
      right: @types.Length(0.0),
      top: @types.Length(0.0),
      bottom: @types.Length(0.0),
    },
    border: {
      left: @types.Length(0.0),
      right: @types.Length(0.0),
      top: @types.Length(0.0),
      bottom: @types.Length(0.0),
    },
    flex_direction: @types.Row,
    flex_wrap: @types.NoWrap,
    justify_content: @types.Start,
    align_items: @types.Stretch,
    align_content: @types.Stretch,
    align_self: @types.AlignSelf::Auto,
    flex_grow: 0.0,
    flex_shrink: 1.0,
    flex_basis: @types.Auto,
    order: 0,
    row_gap: @types.Length(0.0),
    column_gap: @types.Length(0.0),
    aspect_ratio: None,
    inset: {
      left: @types.Auto,
      right: @types.Auto,
      top: @types.Auto,
      bottom: @types.Auto,
    },
    grid_template_rows: [],
    grid_template_columns: [],
    grid_auto_rows: [],
    grid_auto_columns: [],
    grid_auto_flow: @types.Row,
    grid_template_areas: [],
    grid_row: @types.GridLine::auto(),
    grid_column: @types.GridLine::auto(),
    grid_area: None,
    justify_items: @types.Stretch,
    justify_self: @types.AlignSelf::Auto,
    font_size: 16.0,
    line_height: 16.0,
    white_space: Normal,
    writing_mode: HorizontalTb,
    direction: Ltr,
    vertical_align: Baseline,
    clip: @types.ClipRect::Auto,
    visibility: Visible,
    z_index: Auto,
    opacity: 1.0,
    color: @types.Color::black(),
    background_color: @types.Color::transparent(),
    contain: Contain::none(),
    transform: Transform::none(),
    zoom: 1.0,
    border_spacing: 0.0,
    border_collapse: Separate,
    table_layout: Auto,
    caption_side: Top,
    rowspan: 1,
    colspan: 1,
  }
}