/*
 * (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: dvdrvidtrans.c,v 1.124 2006/02/05 15:40:24 kutzner Exp $
 *
 */

/**
 * \file dvdrvidtrans.c
 * \brief A plugin for the Video Disk Recorder.
 *
 * See the README file for copyright information and how to reach the author.
 *
 * $Id: dvdrvidtrans.c,v 1.124 2006/02/05 15:40:24 kutzner Exp $
 */

// libc
#include <getopt.h>

// vdr
#include <plugin.h>

// stdlib
using namespace std;

#include "vtmain.h"


/// Version string used by the makefile.
static const char *VERSION        = "0.2.4";
/// All plugins should have a description.
static const char *DESCRIPTION    = "dvdr video transport";
/// The appliction type we will register with igor
const char *VT_APPTYPE = "DVDR_VIDDATA";


// --------------

/**
 * The main plugin class.
 * This class does all the VDR interface stuff and starts the main plugin thread.
 */

class cPluginVidTrans : public cPlugin {
	private:

	// --- cMenuSetupVidTrans -------------------------------------------------------
	/**
	 * Setup class.
	 * An instance of this class is passed to the VDR if VDR wants to
	 * present a setup page for this plugin to the user. All user
	 * configurable stuff should therefore go here. Changes made by the
	 * user are at first local to this class. Such changes are propagated
	 * to disk via Store() and to the main plugin class via VDR and
	 * SetupParse()
	 */
	class cMenuSetupVidTrans : public cMenuSetupPage {
		private:
			/// Number of seconds from where video sources are considered old.
			int videosource_age_max;
			/// Upper limit for number of threads.
			int client_threads_max;
			/// Intervall between two rounds of publications.
			int publish_interval;
			/// Number of publications per round.
			int _publications_per_round;
			/// Intervall between two housekeeping actions.
			int housekeeping_interval;
			/// the local transport address
			char transport[256];
			/// the maximum uplink speed (in bytes per second)
			char chspeedlimit[15];
			/// The directory to save downloads
			char downloaddir[MAXPATHLENGTH];
			/// remember the plugin for later use in Store()
			cPluginVidTrans * _plugin;
		protected:
			/// Push the values to permanent storage.
			virtual void Store(void);
		public:
			/** it receives this pointer to access parameters in the main class.
			 */
			cMenuSetupVidTrans(cPluginVidTrans *);
	};


		// Add any member variables or functions you may need here.
	public:
		cPluginVidTrans(void);
		virtual ~cPluginVidTrans();
		/// Tell everybody how premature we are.
		virtual const char *Version(void) { return VERSION; }
		/// Tell those who care how we call ourself.
		virtual const char *Description(void) { return tr(DESCRIPTION); }
		/// We don't parse the command line, tell the user.
		virtual const char *CommandLineHelp(void);
		/// We don't parse the command line, therefor this method is a dummy.
		virtual bool ProcessArgs(int argc, char *argv[]);
		/// Start the plugin. Called by VDR.
		virtual bool Start(void);
		/// Do we have to do homework?
		virtual void Housekeeping(void);
		/// Tell VDR we have something to present in the main menu.
		//virtual const char *MainMenuEntry(void) { return tr(MAINMENUENTRY); }
		/// What we have to do in the main menu.
		//virtual cOsdObject *MainMenuAction(void);
		/// Return an object representing our configurability.
		virtual cMenuSetupPage *SetupMenu(void) { return new cMenuSetupVidTrans(this); }
		/// User supplied config information.
		virtual bool SetupParse(const char *Name, const char *Value);
		

	private:
		/// the main thread
		vtmain _vtmain;

};

cPluginVidTrans::cMenuSetupVidTrans::cMenuSetupVidTrans(cPluginVidTrans * plugin) {
	//dsyslog("%s: begin", __PRETTY_FUNCTION__);
	videosource_age_max = plugin->_vtmain.param_videosource_age_max;
	client_threads_max = plugin->_vtmain.get_client_threads_max();
	publish_interval = plugin->_vtmain.publish_interval;
	_publications_per_round = plugin->_vtmain._publications_per_round;
	housekeeping_interval = plugin->_vtmain.housekeeping_interval;
	snprintf(transport, 256, "%s", plugin->_vtmain.transport.c_str());
	snprintf(chspeedlimit, 15, "%d", plugin->_vtmain.speedlimit); // this is handled as a string because otherwise changing the value would happen on 
								      // a one-per-key-pressed basis
	snprintf(downloaddir, MAXPATHLENGTH, "%s", plugin->_vtmain.downloaddir);
	Add(new cMenuEditIntItem("Maximum age of video sources (s)", &videosource_age_max));
	Add(new cMenuEditIntItem("Maximum number of client threads (#)", &client_threads_max));
	Add(new cMenuEditIntItem("Time between publication rounds (s)", &publish_interval));
	Add(new cMenuEditIntItem("Items to publish in each round", &_publications_per_round));
	Add(new cMenuEditIntItem("Housekeeping action interval (s)", &housekeeping_interval));
	Add(new cMenuEditStrItem(tr("Transport address (tcp://ip:port)"), transport, 256, tr("cdhptu1234567890.:/")));
	Add(new cMenuEditStrItem(tr("Maximum uplink speed (byte/s)"), chspeedlimit, 15, tr("0123456789")));
	Add(new cMenuEditStrItem(tr("Download directory (full path)"), downloaddir, MAXPATHLENGTH, tr("@/.abcdefghijklmnopqrstuvwxyz1234567890")));
	_plugin = plugin;
}

void cPluginVidTrans::cMenuSetupVidTrans::Store(void) {
	//dsyslog("%s: begin", __PRETTY_FUNCTION__);
	_plugin->_vtmain.param_videosource_age_max = videosource_age_max;
	_plugin->_vtmain.set_client_threads_max(client_threads_max);
	_plugin->_vtmain.publish_interval = publish_interval;
	_plugin->_vtmain._publications_per_round = _publications_per_round;
	_plugin->_vtmain.housekeeping_interval = housekeeping_interval;
	_plugin->_vtmain.transport = string(transport);
	_plugin->_vtmain.speedlimit = atoi(chspeedlimit);
	snprintf(_plugin->_vtmain.downloaddir, MAXPATHLENGTH, "%s", downloaddir);
	SetupStore("videosource_age_max", videosource_age_max);
	SetupStore("client_threads_max", client_threads_max);
	SetupStore("publish_interval", publish_interval);
	SetupStore("publications_per_round", _publications_per_round);
	SetupStore("housekeeping_interval", housekeeping_interval);
	SetupStore("transport", transport);
	SetupStore("speedlimit", chspeedlimit);
	SetupStore("downloaddir", downloaddir);
}

// --- cPluginVidTrans ----------------------------------------------------------

cPluginVidTrans::cPluginVidTrans(void)
{
}

cPluginVidTrans::~cPluginVidTrans()
{
  // XXX stop all the started threads
}

const char *cPluginVidTrans::CommandLineHelp(void)
{
  // Return a string that describes all known command line options.
  return "help yourself (use the source, Luke)" ;
}

bool cPluginVidTrans::ProcessArgs(int argc, char *argv[])
{
  // Implement command line argument processing here if applicable.
  static struct option long_options[] = {
	{ NULL, 0 , NULL, 0 }
     };

  int c;
  while ((c = getopt_long(argc, argv, "", long_options, NULL)) != -1) {
	switch (c) {
	  default:  return false;
	  }
	}
  return true;
}

/**
 * Start main thread.
 * The only action during plugin start is to start the main thread.
 */
bool cPluginVidTrans::Start(void)
{
	_vtmain.Start();
	return true;
}

void cPluginVidTrans::Housekeeping(void)
{
	//dsyslog("%s: begin", __PRETTY_FUNCTION__);
	// Perform any cleanup or other regular tasks.
}

/**
 * VDR wants to pass some configuration data. This method forwards the
 * configuration data to the main thread.
 */
bool cPluginVidTrans::SetupParse(const char *Name, const char *Value)
{
	//dsyslog("%s: forwarding name '%s' val %s to vtmain", __PRETTY_FUNCTION__, Name, Value);
	return _vtmain.SetupParse(Name, Value);
}




/// VDR magic
VDRPLUGINCREATOR(cPluginVidTrans); // Don't touch this!

