//! Register system — a yank ring for clipboard history.
//!
//! The yank ring is the authoritative source of clipboard history.  The
//! system clipboard is only a best-effort synchronisation target; all paste
//! operations read from the ring rather than the OS clipboard.

use std::collections::VecDeque;

/// A fixed-capacity ring of yanked strings, newest at the front.
#[derive(Debug, Default)]
pub struct Registers {
    ring: VecDeque<String>,
    max: usize,
}

impl Registers {
    pub fn new(max: usize) -> Self {
        Self {
            ring: VecDeque::with_capacity(max),
            max,
        }
    }

    /// Push a new entry.  Consecutive duplicates are silently dropped.
    pub fn push(&mut self, text: String) {
        if text.is_empty() {
            return;
        }
        if self.ring.front().map(|t| t == &text).unwrap_or(false) {
            return;
        }
        self.ring.push_front(text);
        if self.ring.len() > self.max {
            self.ring.pop_back();
        }
    }

    /// The most recently yanked text.
    pub fn latest(&self) -> Option<&str> {
        self.ring.front().map(|s| s.as_str())
    }

    /// Get the entry at position `idx` (0 = newest).
    pub fn get(&self, idx: usize) -> Option<&str> {
        self.ring.get(idx).map(|s| s.as_str())
    }

    pub fn len(&self) -> usize {
        self.ring.len()
    }

    pub fn is_empty(&self) -> bool {
        self.ring.is_empty()
    }

    pub fn iter(&self) -> impl Iterator<Item = &String> {
        self.ring.iter()
    }
}
