use std::sync::Mutex;
use url::Url;

/// History.
/// 
/// This structure manages all aspects of browser history.
/// 
/// Internally, URLs are stored in a first-in-last-out (FILO) stack.
/// When a URL is visited, it gets pushed on top of the stack.  To go
/// back, the topmost URL (i.e. the current one) is popped off, and
/// the previous URL becomes the current URL.  Initially, the stack is
/// empty, signifying that the current page is the startup page.
pub struct History {
    /// The URL stack.
    urls: Vec<Url>,
}

impl History {
    /// Creates a new, empty [`History`].
    pub fn new() -> History {
        History { urls: Vec::new() }
    }

    /// Retrieves the current URL, if any.
    pub fn cur(&self) -> Option<&Url> {
        self.urls.last()
    }

    /// Pushes a new URL onto the stack.
    /// 
    /// This indicates that this new URL is being visited.
    pub fn push(&mut self, url: Url) {
        self.urls.push(url)
    }

    /// Pops off the current URL, if any.
    /// 
    /// This indicates that the previous URL is being visited.
    /// 
    /// The current URL (if any) is lost.
    /// 
    /// If there is only one URL on the stack, it gets removed.  If
    /// the stack is already empty, no action occurs.
    pub fn pop(&mut self) {
        self.urls.pop();
    }
}

lazy_static! {
    static ref HISTORY: Mutex<History> = Mutex::new(History::new());
}

pub fn append(url: Url) {
    HISTORY.lock().unwrap().push(url);
}

pub fn get_current_url() -> Option<Url> {
    HISTORY.lock().unwrap().cur().cloned()
}

pub fn get_previous_url() -> Option<Url> {
    let mut history = HISTORY.lock().unwrap();
    history.pop();
    history.cur().cloned()
}
