use serde::{Deserialize, Serialize};
use crate::editor::position::Position;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct Selection {
    pub anchor: Position,
    pub active: Position,
}

impl Selection {
    pub fn new(anchor: Position, active: Position) -> Self {
        Self { anchor, active }
    }

    pub fn is_empty(&self) -> bool {
        self.anchor == self.active
    }

    pub fn min(&self) -> Position {
        if self.anchor.line < self.active.line
            || (self.anchor.line == self.active.line && self.anchor.column <= self.active.column)
        {
            self.anchor
        } else {
            self.active
        }
    }

    pub fn max(&self) -> Position {
        if self.anchor.line > self.active.line
            || (self.anchor.line == self.active.line && self.anchor.column >= self.active.column)
        {
            self.anchor
        } else {
            self.active
        }
    }

    pub fn covered_spans(&self) -> Vec<(usize, usize, usize)> {
        if self.is_empty() {
            return vec![];
        }
        let min = self.min();
        let max = self.max();
        if min.line == max.line {
            vec![(min.line, min.column, max.column)]
        } else {
            let mut spans = Vec::new();
            spans.push((min.line, min.column, usize::MAX));
            for row in (min.line + 1)..max.line {
                spans.push((row, 0, usize::MAX));
            }
            spans.push((max.line, 0, max.column));
            spans
        }
    }
}
