/*
 * (c) 2005 Research Group Dr. Fuhrmann, University of Karlsruhe, Germany
 * All rights reserved.
 *
 * Author:
 *         Stefan Denk <denk@ira.uka.de>
 *         Kendy Kutzner <kutzner@ira.uka.de>
 *
 * $Id: vtmain.h,v 1.6 2006/01/10 19:19:47 kutzner Exp $
 *
 */

#ifndef _VTMAIN_H_
#define _VTMAIN_H_

#include "dvdrvidtrans.h"
#include "task.h"
#include "watchdog.h"
#include "vdrrecording.h"
#include "igorinterface.h"
#include "serverthread.h"

/** The main thread of this plugin
 * This main thread of the VidTrans Plugin runs all periodic activities.
 * It starts other threads.
 */
class vtmain : public cThread {
	friend class clientthread; // It would be enough to say 'friend void clientthread::copydownloaddir()', but clientthread is not yet defined.
	public:
		/** Construct this thread*/
		vtmain();
		/// Destruction all arround
		~vtmain(){if (videosources) delete videosources;};
		/** Forward of the SetupParse function from the plugin class.
		 * The plugin class SetupParse() function just calls this method.
		 * \param Name The name of the setup variable.
		 * \param Value The value of the setup variable.
		 */
		bool SetupParse(const char *Name, const char *Value);
		/** Currently non-existing method to announce something*/
		void do_announce_to_igor();
		/** The main loop of this thread.
		 * Runs all periodic activities of this thread.
		 */
		void Action();
		/** How old is an old video source?*/
		time_t param_videosource_age_max;
		/** Get the limit on client threads*/
		int get_client_threads_max(){return _tasks.get_client_threads_max();}
		/** Set this limit*/
		void set_client_threads_max(int num){_tasks.set_client_threads_max(num);}
		/** Intervall between two publications */
		int publish_interval;
		/** Intervall between two calls to the ctasks::housekeeping function */
		int housekeeping_interval;
		/// Intervall between two calls to cvideosources::cleanup()
		int videosourcecleanup_interval;
		/// the local transport address
		string transport;
		/// the maximum uplink speed (in bytes per second)
		int speedlimit;
		/// number of publications per round
		int _publications_per_round;
		///\bug doc me
		char downloaddir[MAXPATHLENGTH];
		/// Get the latest instance of this class.
		static const vtmain * getthread();
	private:
		/** All recordings we should fetch.*/
		ctasks _tasks;
		/** All recordings we know a source of.
		 * This includes all local recordings and all foreign recordings announced through us.
		 */
		cvideosources * videosources;
		/** The communication queue between igor-receiver thread and this thread
		 * The igor-receive-thread puts message into this queue, we fetch them from this queue.
		 */
		cqueue _q;
		/** The receiver thread adding messages to _q*/
		igorinterface * receiver;
		/** the igor socket*/
		int _s;
		/** the speed controller */
		watchdog * _wd;
		/** pointer to vdrrecordings, used to initiate local operations and to pass on a pointer to ctasks to add tasks if merge fails */
		vdrrecordings * _local;
		/** pointer to the main serverthread */
		serverthread * _serverthread;
		/** this condion variable is used by the igor-receiver-thread to signal us*/
		cCondWait _w;
		/// A class to manage pending timers.
		class ctimerlist{
			public:
				/// The timers we support
				enum etimer { NONE, CTASKS_HOUSEKEEPING, PUBLISH, CLEANUP_VIDEOSOURCES };
				/// Retrieve the next timer.
				int getnextwhen();
				/// Retrieve the kind of the next timer
				etimer getnextwhat();
				/// Add a new timer.
				void add(etimer what, int when);
			private:
				/// Internal representation of a timer.
				struct timer_t {
					/// What to do if the timer fires.
					etimer what;
					/// When does the timer fire. In seconds since the epoch.
					int when;
				};
				/// The list of all pending timers.
				list<timer_t> _list;
		} _timerlist;
		/** Handle one received message*/
		void handle_msg();
		/** If the received message is of type REQ, handle it, e.g. try to answer or forward*/
		void handle_req(vtmsg *);
		/** If the received message is of type DATA, handle it, e.g. store it, eventually wake up who is waiting*/
		void handle_data(vtmsg *);
		/** A timer fired. Do the appropriate action*/
		void handle_timer();
		/** Send information about _publications_per_round video sources upstream*/
		bool publish();
		/** Send a single video source upstream. */
		bool publish_single();
		/// The latest instance of this class.
		static vtmain * _thethread;
};


#endif // _VTMAIN_H_
