use crate::excel::Sheet;
#[derive(Debug, Clone, Copy)]
pub enum Direction {
Left,
Right,
Up,
Down,
}
#[must_use]
pub fn find_non_empty_cell(
sheet: &Sheet,
current_pos: (usize, usize),
direction: Direction,
max_bounds: (usize, usize),
) -> Option<(usize, usize)> {
let (row, col) = current_pos;
let (max_row, max_col) = max_bounds;
match direction {
Direction::Left if col <= 1 => return None,
Direction::Right if col >= max_col => return None,
Direction::Up if row <= 1 => return None,
Direction::Down if row >= max_row => return None,
_ => {}
}
let current_cell_is_empty = row >= sheet.data.len()
|| col >= sheet.data[row].len()
|| sheet.data[row][col].value.is_empty();
if current_cell_is_empty {
match direction {
Direction::Left => {
for c in (1..col).rev() {
if row < sheet.data.len()
&& c < sheet.data[row].len()
&& !sheet.data[row][c].value.is_empty()
{
return Some((row, c));
}
}
Some((row, 1))
}
Direction::Right => {
for c in (col + 1)..=max_col {
if row < sheet.data.len()
&& c < sheet.data[row].len()
&& !sheet.data[row][c].value.is_empty()
{
return Some((row, c));
}
}
Some((row, max_col))
}
Direction::Up => {
for r in (1..row).rev() {
if r < sheet.data.len()
&& col < sheet.data[r].len()
&& !sheet.data[r][col].value.is_empty()
{
return Some((r, col));
}
}
Some((1, col))
}
Direction::Down => {
for r in (row + 1)..=max_row {
if r < sheet.data.len()
&& col < sheet.data[r].len()
&& !sheet.data[r][col].value.is_empty()
{
return Some((r, col));
}
}
Some((max_row, col))
}
}
} else {
match direction {
Direction::Left => {
let mut last_non_empty = col;
for c in (1..col).rev() {
if row < sheet.data.len() && c < sheet.data[row].len() {
if sheet.data[row][c].value.is_empty() {
return Some((row, c + 1));
}
last_non_empty = c;
} else {
return Some((row, c + 1));
}
}
Some((row, last_non_empty))
}
Direction::Right => {
let mut last_non_empty = col;
for c in (col + 1)..=max_col {
if row < sheet.data.len() && c < sheet.data[row].len() {
if sheet.data[row][c].value.is_empty() {
return Some((row, c - 1));
}
last_non_empty = c;
} else {
return Some((row, c - 1));
}
}
Some((row, last_non_empty))
}
Direction::Up => {
let mut last_non_empty = row;
for r in (1..row).rev() {
if r < sheet.data.len() && col < sheet.data[r].len() {
if sheet.data[r][col].value.is_empty() {
return Some((r + 1, col));
}
last_non_empty = r;
} else {
return Some((r + 1, col));
}
}
Some((last_non_empty, col))
}
Direction::Down => {
let mut last_non_empty = row;
for r in (row + 1)..=max_row {
if r < sheet.data.len() && col < sheet.data[r].len() {
if sheet.data[r][col].value.is_empty() {
return Some((r - 1, col));
}
last_non_empty = r;
} else {
return Some((r - 1, col));
}
}
Some((last_non_empty, col))
}
}
}
}