use qecs_core::{Event, BufferBase, EventBuffer, _EventBuffer};

use std::option;

pub struct SingleEventBuffer<E> {
    storage: Option<E>,
}

impl<E> From<Option<E>> for SingleEventBuffer<E>
    where E: Event
{
    fn from(storage: Option<E>) -> Self {
        SingleEventBuffer{ storage: storage }
    }
}

impl<E> Default for SingleEventBuffer<E>
    where E: Event
{
    fn default() -> Self {
        SingleEventBuffer{ storage: None }
    }
}

impl<E> BufferBase for SingleEventBuffer<E> 
    where E: Event
{
    fn len(&self) -> usize { 
        if self.storage.is_some() { 1 } else { 0 }
    }

    fn clear(&mut self) { 
        self.storage = None;
    }
}

pub type Iter<'a, E> = option::Iter<'a, E>;

impl<'a, E> _EventBuffer<'a> for SingleEventBuffer<E> 
    where E: Event
{
    type _Event = E;

    type Iter = Iter<'a, E>;
}

impl<E> EventBuffer for SingleEventBuffer<E> 
    where E: Event
{
    type Event = E;

    fn write<T>(&mut self, ev: T)
        where T: Into<Self::Event>
    {
        self.storage = Some(ev.into());
    }

    fn iter<'a>(&'a self) -> <Self as _EventBuffer<'a>>::Iter {
        self.storage.iter()
    }
}

impl<'a, E> IntoIterator for &'a SingleEventBuffer<E> 
    where E: Event
{
    type Item = <Self::IntoIter as Iterator>::Item;
    type IntoIter = Iter<'a, E>;
    fn into_iter(self) -> Self::IntoIter { self.iter() }
}

