/*
 * See the files COPYING and README for copyright information and how to reach
 * the author.
 *
 *  $Id: adaptor.h,v 1.4 2006/09/16 18:33:36 lordjaxom Exp $
 */

#ifndef VDR_BURN_ADAPTOR_H
#define VDR_BURN_ADAPTOR_H

#include <iterator>
#include <vdr/epg.h>
#include <vdr/tools.h>

namespace vdr_burn
{
	namespace adaptor
	{

		class component_iterator:
				public std::iterator<std::forward_iterator_tag, tComponent>
		{
		public:
			component_iterator(): m_components(0), m_index(0) {}
			explicit component_iterator(const cComponents* components):
					m_components(components), m_index(0) {}

			bool operator==(const component_iterator& rhs);
			bool operator!=(const component_iterator& rhs) { return !(*this == rhs); }
			component_iterator& operator++();
			component_iterator operator++(int);

			reference operator*() { return *m_components->Component(m_index); }
			pointer operator->() { return m_components->Component(m_index); }

		private:
			const cComponents* m_components;
			int m_index;
		};

		inline
		bool component_iterator::operator==(const component_iterator& rhs)
		{
			if (m_components != rhs.m_components)
				return false;
			if (m_components == 0)
				return true;
			return m_index == rhs.m_index;
		}

		inline
		component_iterator& component_iterator::operator++()
		{
			if (m_index < m_components->NumComponents() - 1)
				++m_index;
			else
				m_components = 0;
			return *this;
		}

		inline
		component_iterator component_iterator::operator++(int)
		{
			component_iterator temp( *this );
			++*this;
			return temp;
		}

		template<typename FwdIt, typename Pred>
		FwdIt find_nth(FwdIt first, FwdIt last, int nth, Pred pred)
		{
			while ((first = std::find_if(first, last, pred)) != last && --nth)
				++first;
			return first;
		}

        template<typename Item>
		class list_iterator: public std::iterator<std::bidirectional_iterator_tag, Item>
		{
        public:
		    typedef std::iterator<std::bidirectional_iterator_tag, Item> base_type;
		    typedef typename base_type::reference reference;
		    typedef typename base_type::pointer pointer;

            list_iterator(cList<Item>& list): m_item( list.First() ) { }
            list_iterator(): m_item( 0 ) { }
            list_iterator(const list_iterator<Item>& right): m_item( right.m_item ) { }

            list_iterator<Item>& operator=(const list_iterator<Item>& right) { m_item = right.m_item; }

            reference operator*() { return *m_item; }
            pointer operator->() { return m_item; }

            list_iterator<Item>& operator++() { m_item = static_cast<pointer>( m_item->Next() ); return *this; }
            list_iterator<Item> operator++(int) { list_iterator<Item> result( *this ); ++*this; return result; }
            list_iterator<Item>& operator--() { m_item = static_cast<pointer>( m_item->Prev() ); return *this; }
            list_iterator<Item> operator--(int) { list_iterator<Item> result( *this ); --*this; return result; }

            bool operator==(const list_iterator<Item>& right) { return m_item == right.m_item; }
            bool operator!=(const list_iterator<Item>& right) { return m_item != right.m_item; }

        private:
            Item* m_item;
		};

	}
}

#endif // VDR_BURN_ADAPTOR_H
