// Copyright 2025 International Digital Economy Academy
//
// Licensed 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.
///|
fn fr_track_weight(track : Dimension) -> Double {
match track {
DimFr(w) => if w > 0.0 { w } else { 0.0 }
_ => 0.0
}
}
///|
fn apply_col_contribution(
col_tracks : Array[Dimension],
start : Int,
span : Int,
needed : Double,
contrib : Array[Double],
) -> Unit {
if span <= 1 {
if needed > contrib[start] {
contrib[start] = needed
}
return
}
let mut all_fr = true
let weights : Array[Double] = Array::make(span, 0.0)
let mut positive_weight_sum = 0.0
for offset in 0.. 0.0 {
positive_weight_sum = positive_weight_sum + weight
}
}
if all_fr {
if positive_weight_sum > 0.0 {
for offset in 0.. contrib[idx] {
contrib[idx] = share
}
}
} else {
let share = needed / span.to_double()
for offset in 0.. contrib[idx] {
contrib[idx] = share
}
}
}
} else if positive_weight_sum > 0.0 {
let mut current_sum = 0.0
for offset in 0.. 0.0 {
for offset in 0.. 0.0 {
contrib[idx] = contrib[idx] + deficit * weight / positive_weight_sum
}
}
}
} else {
let share = needed / span.to_double()
for offset in 0.. contrib[idx] {
contrib[idx] = share
}
}
}
}
///|
fn track_definite_len(track : Dimension) -> Double? {
match track {
DimLength(v) => Some(v)
DimMinMax(min_d, max_d) =>
match (min_d, max_d) {
(DimLength(a), DimLength(b)) if a == b => Some(a)
_ => None
}
_ => None
}
}
///|
fn spanned_definite_len(
tracks : Array[Dimension],
start : Int,
span : Int,
gap : Double,
) -> Double? {
if span <= 0 {
return Some(0.0)
}
let mut total = 0.0
for i in start..<(start + span) {
match track_definite_len(tracks[i]) {
Some(v) => total = total + v
None => return None
}
}
if span > 1 {
total = total + gap * (span - 1).to_double()
}
Some(total)
}
///|
fn track_min_sizing_kind(track : Dimension) -> Int {
// 0 = fixed/other, 1 = min-content, 2 = max-content, 3 = auto
match track {
DimMinContent => 1
DimMaxContent => 2
DimAuto => 3
DimFitContent(_) => 3
DimMinMax(min_d, _) =>
match min_d {
DimMinContent => 1
DimMaxContent => 2
DimAuto => 3
DimFitContent(_) => 3
_ => 0
}
_ => 0
}
}
///|
fn grid_track_base_state(
dimension : Dimension,
percent_basis : Double?,
) -> GridTrack {
let mut base_size = 0.0
match dimension {
DimLength(v) => base_size = v
DimPercent(p) =>
match percent_basis {
Some(b) => base_size = b * p
None => base_size = 0.0
}
DimMinMax(min_d, _) =>
match min_d {
DimLength(v) => base_size = v
DimPercent(p) =>
match percent_basis {
Some(b) => base_size = b * p
None => ()
}
_ => ()
}
_ => ()
}
{
dimension,
base_size,
base_size_planned_increase: 0.0,
item_incurred_increase: 0.0,
}
}
///|
fn track_max_is_min_content(track : Dimension) -> Bool {
match track {
DimMinContent => true
DimMinMax(_, max_d) => max_d is DimMinContent
_ => false
}
}
///|
fn track_has_intrinsic_min(track : Dimension, percent_basis : Double?) -> Bool {
match track {
DimAuto | DimMinContent | DimMaxContent | DimFitContent(_) => true
DimPercent(_) => percent_basis is None
DimMinMax(min_d, _) =>
match min_d {
DimAuto | DimMinContent | DimMaxContent | DimFitContent(_) => true
DimPercent(_) => percent_basis is None
_ => false
}
_ => false
}
}
///|
fn track_has_intrinsic_max(track : Dimension, percent_basis : Double?) -> Bool {
match track {
DimAuto | DimMinContent | DimMaxContent | DimFitContent(_) => true
DimPercent(_) => percent_basis is None
DimFr(_) => true
DimMinMax(_, max_d) =>
match max_d {
DimAuto | DimMinContent | DimMaxContent | DimFitContent(_) => true
DimPercent(_) => percent_basis is None
DimFr(_) => true
_ => false
}
_ => false
}
}
///|
fn track_has_max_content_or_fit_max(track : Dimension) -> Bool {
match track {
DimMaxContent | DimFitContent(_) => true
DimMinMax(_, max_d) =>
match max_d {
DimMaxContent | DimFitContent(_) => true
_ => false
}
_ => false
}
}
///|
fn track_fit_content_limit(
track : Dimension,
percent_basis : Double?,
inf : Double,
) -> Double {
let limit = match track {
DimFitContent(limit) => Some(limit)
DimMinMax(_, DimFitContent(limit)) => Some(limit)
_ => None
}
match limit {
Some(DimPercent(p)) =>
match percent_basis {
Some(b) => b * p
None => inf
}
Some(d) => resolve_track_dimension(d, 0.0)
None => inf
}
}
///|
fn track_uses_percentage(track : Dimension) -> Bool {
match track {
DimPercent(_) => true
DimFitContent(DimPercent(_)) => true
DimMinMax(min_d, max_d) =>
match (min_d, max_d) {
(DimPercent(_), _) => true
(_, DimPercent(_)) => true
(_, DimFitContent(DimPercent(_))) => true
_ => false
}
_ => false
}
}
///|
fn track_flex_weight(track : Dimension) -> Double {
match track {
DimFr(w) => if w > 0.0 { w } else { 0.0 }
DimMinMax(_, DimFr(w)) => if w > 0.0 { w } else { 0.0 }
_ => 0.0
}
}
///|
fn track_has_flexible_max(track : Dimension) -> Bool {
track_flex_weight(track) > 0.0
}