/*
 * See the files COPYING and README for copyright information and how to reach
 * the author.
 *
 *  $Id: menubase.h,v 1.2 2006/05/16 17:29:04 lordjaxom Exp $
 */

#ifndef VDR_BURN_MENUBASE_H
#define VDR_BURN_MENUBASE_H

#include "jobs.h"
#include "proctools/positioner.h"
#include "proctools/format.h"
#include <string>
#include <vdr/osdbase.h>

namespace vdr_burn
{

	namespace menu
	{

		// --- starter --------------------------------------------------------
		
		class starter: public cOsdMenu
		{
		public:
			enum display
			{
				none,
				recordings,
				job,
				status
			};

			starter(void);
			virtual ~starter();

			static void cycle_display(void);
			static std::string get_next_display(void);

		protected:
			eOSState show_menu(void);

			virtual eOSState ProcessKey(eKeys key);

		private:
			static const int count = status + 1;
			static const std::string strings[count];
			static starter* m_instance;

			display m_display;
			display m_nextDisplay;
		};

		inline
		void starter::cycle_display(void)
		{
			m_instance->m_nextDisplay = 
					display( (m_instance->m_display + 1) % count );
			if (m_instance->m_nextDisplay == none)
				m_instance->m_nextDisplay = recordings;
		}

		// --- pagebase -------------------------------------------------------

		class pagebase: public cOsdMenu
		{
			struct user_wait
			{
				bool        waiting;
				bool        result;
				std::string message;
				cMutex      lock;
				cCondVar    condition;

				user_wait(void): waiting(false) {}
			};

			enum item_type
			{
				label,
				recording,
				setup
			};
			
			typedef proctools::positioner<item_type, std::string> item_positioner;

		public:
			typedef item_positioner::item_info item_position;

			pagebase(const std::string& title, int tab0 = 0, int tab1 = 0);
			virtual ~pagebase() = 0;
	
			static bool wait_for_user(const std::string& message);

		protected:
			void set_help(const std::string& red = std::string(),
						  const std::string& green = std::string(),
						  const std::string& yellow = std::string());
			const item_position& current(void) { return m_positions[Current()]; }
			void set_current(int current);
			void set_current(const item_position& current_);
			void display(void);
			void check_waiting_user(void);

			void clear(void) { Clear(); m_positions.clear(); }
			void add_label(const char* text);
			void add_label(const proctools::format& fmt) { add_label(fmt.str().c_str()); }
			void add_item(recording_list::iterator& rec_);
			void add_item(const char* name, char* value, int length, const char* allowed);
			void add_item(const char* name, int& value, int count, const char* const* strings);
			void add_item(const char* name, int& value, const char* yes = 0, const char* no = 0);

			virtual void set_help_keys(void) { set_help(); }
			virtual eOSState dispatch_key(eKeys key);

			virtual bool menu_closing(void) { return true; }
			virtual eOSState menu_update(void) { return osContinue; }
			virtual eOSState ok_pressed(void) { return osContinue; }
			virtual eOSState red_pressed(void) { return osContinue; }
			virtual eOSState green_pressed(void) { return osContinue; }
			virtual eOSState yellow_pressed(void) { return osContinue; }

			virtual eOSState ProcessKey(eKeys key);

			friend class starter;
			static job* m_pending;

		private:
			static user_wait m_waitInfo;

			item_positioner m_positions;

			// <rant> must be constants, thanks for mentioning INSIDE THE 
			// ACTUAL IMPLEMENTATION. if you want to find out what I mean, 
			// look into MY impl :> </rant>
			std::string m_red;
			std::string m_green;
			std::string m_yellow;
			std::string m_blue;
		};

	}
}

#endif // VDR_BURN_MENUBASE_H
