/*
 * See the files COPYING and README for copyright information and how to reach
 * the author.
 *
 *  $Id: menuburn.h,v 1.10 2006/04/24 19:43:37 lordjaxom Exp $
 */

#ifndef VDR_BURN_MENUBURN_H
#define VDR_BURN_MENUBURN_H

#include "manager.h"
#include <vector>
#include <utility>
#include <string>

namespace vdr_burn
{

	class job;

	namespace menu
	{
		// --- track_editor ---------------------------------------------------

		class track_editor: public cMenuSetupPage
		{
			typedef std::pair<track_info_list::iterator, int> data_pair;
			typedef std::vector<data_pair> data_list;
			typedef data_list::iterator data_iterator;

		public:
			track_editor(recording& recording_);

		protected:
			void refresh(void);
			void add_track(data_pair& track);
			bool can_move_down(void);
			void set_help_keys(void);
			eOSState dispatch_key(eKeys key);
			void move_down(void);

			virtual void Store(void);
			virtual eOSState ProcessKey(eKeys key);

		private:
			recording& m_recording;
			data_list  m_data;
		};

		// --- 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
		{
		public:
			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());
			void set_current(int current);
			void display(void);
			void check_waiting_user(void);

			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:
			struct user_wait
			{
				bool        waiting;
				bool        result;
				std::string message;
				cMutex      lock;
				cCondVar    condition;

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

			static user_wait m_waitInfo;

			// <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;
		};

		// --- recordings -----------------------------------------------------
		
		class recordings: public pagebase
		{
		public:
			recordings(void);

		protected:
			void display(void);

			virtual void set_help_keys(void);
			virtual bool menu_closing(void);
			virtual eOSState ok_pressed(void);
			virtual eOSState red_pressed(void);

		private:
			std::string m_basePath;
			int         m_pathLevel;
			bool        m_pathChanged;
		};

		// --- job ------------------------------------------------------------
		
		class job_editor: public pagebase
		{
		public:
			job_editor(void);

		protected:
			void display(void);
			
			virtual void set_help_keys(void);
			virtual eOSState ok_pressed(void);
			virtual eOSState red_pressed(void);
			virtual eOSState green_pressed(void);
			virtual eOSState yellow_pressed(void);

		private:
			uint m_offset;
		};

		// --- status ---------------------------------------------------------
		
		class status: public pagebase
		{
		public:
			status(void);

		protected:
			void display(void);

			virtual void set_help_keys(void);
			virtual eOSState menu_update(void);
			virtual eOSState green_pressed(void);
			virtual eOSState yellow_pressed(void);
		};
	}

}

#endif // VDR_BURN_MENUBURN_H
