use std::iter::{Fuse, FusedIterator};
use super::size_hint;

pub trait IntersperseElement<Item> {
    fn generate(&mut self) -> Item;
}

#[derive(Debug, Clone)]
pub struct IntersperseElementSimple<Item>(Item);

impl<Item: Clone> IntersperseElement<Item> for IntersperseElementSimple<Item> {
    fn generate(&mut self) -> Item {
        self.0.clone()
    }
}

/// An iterator adaptor to insert a particular value
/// between each element of the adapted iterator.
///
/// Iterator element type is `I::Item`
///
/// This iterator is *fused*.
///
/// See [`.intersperse()`](crate::Itertools::intersperse) for more information.
pub type Intersperse<I> = IntersperseWith<I, IntersperseElementSimple<<I as Iterator>::Item>>;

/// Create a new Intersperse iterator
pub fn intersperse<I>(iter: I, elt: I::Item) -> Intersperse<I>
    where I: Iterator,
{
    intersperse_with(iter, IntersperseElementSimple(elt))
}

impl<Item, F: FnMut()->Item> IntersperseElement<Item> for F {
    fn generate(&mut self) -> Item {
        self()
    }
}

/// An iterator adaptor to insert a particular value created by a function
/// between each element of the adapted iterator.
///
/// Iterator element type is `I::Item`
///
/// This iterator is *fused*.
///
/// See [`.intersperse_with()`](crate::Itertools::intersperse_with) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
#[derive(Clone, Debug)]
pub struct IntersperseWith<I, ElemF>
    where I: Iterator,
{
    element: ElemF,
    iter: Fuse<I>,
    peek: Option<I::Item>,
}

/// Create a new IntersperseWith iterator
pub fn intersperse_with<I, ElemF>(iter: I, elt: ElemF) -> IntersperseWith<I, ElemF>
    where I: Iterator,
{
    let mut iter = iter.fuse();
    IntersperseWith {
        peek: iter.next(),
        iter,
        element: elt,
    }
}

impl<I, ElemF> Iterator for IntersperseWith<I, ElemF>
    where I: Iterator,
          ElemF: IntersperseElement<I::Item>
{
    type Item = I::Item;
    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        if self.peek.is_some() {
            self.peek.take()
        } else {
            self.peek = self.iter.next();
            if self.peek.is_some() {
                Some(self.element.generate())
            } else {
                None
            }
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        // 2 * SH + { 1 or 0 }
        let has_peek = self.peek.is_some() as usize;
        let sh = self.iter.size_hint();
        size_hint::add_scalar(size_hint::add(sh, sh), has_peek)
    }

    fn fold<B, F>(mut self, init: B, mut f: F) -> B where
        Self: Sized, F: FnMut(B, Self::Item) -> B,
    {
        let mut accum = init;

        if let Some(x) = self.peek.take() {
            accum = f(accum, x);
        }

        let element = &mut self.element;

        self.iter.fold(accum,
            |accum, x| {
                let accum = f(accum, element.generate());
                let accum = f(accum, x);
                accum
        })
    }
}

impl<I, ElemF> FusedIterator for IntersperseWith<I, ElemF>
    where I: Iterator,
          ElemF: IntersperseElement<I::Item>
{}
