/********************************************************************************
 * transponders.h 
 * supports transponder data. 
 * writen by reel-multimedia
 *  
 * Contact to mhahn@reel-multimedia.com
 * 
 ********************************************************************************/


#ifndef _TRANSPONDERS__H
#define _TRANSPONDERS__H m 


#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <ios>
#include <iostream>
#include <fstream>
#include <sstream> // zeicheketten streams
#include <string>
#include <list>
#include <vector>
#include <vdr/sources.h>
#include <vdr/channels.h>

#include "channelscan.h"

class cTransponder;

typedef std::vector<cTransponder *>::const_iterator vTpIter;

// the source below ist taken from http://www.parashift.com/c++-faq-lite/

inline int strToInt(const std::string& s)
{
   std::istringstream i(s);
   int x = -1;
   if (!(i >> x))
     std::cerr << " error in strToInt(): " << s << std::endl;
   return x;
}
// --- Class cTransponder: base class which actual transponders can be derived

class cTransponder {
public:
   virtual ~cTransponder() {}
   int TpNumber(void) const; 
   int Frequency() const;
	///<  set transponder Data to channel
   virtual bool SetTransponderData(cChannel *c, int Code=0) = 0;

   std::string IntToStr(int num);
   int StrToInt(std::string str);
   int IntToFec(int val);
protected:
   cTransponder(int Frequency);
   int frequency_;
	int transponderNum_;
private:
   cTransponder(const cTransponder&);
   cTransponder &operator=(const cTransponder&);
   std::string service_; 
};


// --- class cSatTransponder ----------------------------------------------------

class cSatTransponder : public cTransponder {
private:
   int symbolRate_;
   char pol_;
	int fec_;
public:
   cSatTransponder(void);
	cSatTransponder(int Frequency, char Pol, int SymbolRate, int FEC);
   bool SetTransponderData(cChannel *c, int Code=0);
	///<  set transponder Data to channel
   bool Parse(std::string line);
};


// --- class cTerrTransponder ---------------------------------------------------

class cTerrTransponder : public cTransponder {
public:
	cTerrTransponder(int ChannelNr, int Frequency, int Bandwidth);
   ///< channelNr is only for debunging purposes
   cTerrTransponder();
   ~cTerrTransponder();
   bool SetTransponderData(cChannel *c, int Code=0); 
	///<  set transponder Data to channel

private:
   int channelNum_;
   int bandwidth_;
   int symbolrate_;
   int modulation_;
	int fec_l_;
	int fec_h_;
	int hierarchy_;
	int transmission_;
   int guard_;
};


// --- class cCableTransponder --------------------------------------------------

class cCableTransponder : public cTransponder {
public:
   cCableTransponder(int ChannelNr, int Frequency, int Bandwidth, int sRate, int Mod);
   ~cCableTransponder();
   bool SetTransponderData(cChannel *c, int Code=0); 
private:
   int channelNum_;
   int bandwidth_;
   int symbolrate_;
   int modulation_;
	int fec_h_;
	int hierarchy_;
	int transmission_;
   int guard_;
};

// ---- Class cTransponders --------------------------------------
///< Container class for cTransponder class
///< can be createt only once, and can hold
///< only one type of cTransponder 

class cTransponders 
{
public:
   static void Create();
	///< call Constructor and instance_
   static void Destroy();
	///<  put this to your destructor of class calling Create()
   static cTransponders &GetInstance();
	///<  gives you reference to existing cTransponders
	void Clear();
	///< Clears all transponders in vector. deletes all allocatet memmory 
	///< don`t  use v_tp_.clear() 
   std::vector<cTransponder *> v_tp_;

	// XXX Refact until next mark
   void Load(int source, int srate, int modulation); //Ok
   void Load(int source, int freqency, char pol, int symbolrate, int fec); //xx
   ///< for manual scan on single dvb-s transponder
	bool LoadTpl(std::string tpList);
	void CalcTerrTpl(); 
   ///< Calculates terrestrial transponder lists and load them to cTransponder 
	void CalcCableTpl(int sRate, int Mod);
   ///< Calculates cable Transponder lists and load them to cTransponder 

   ///< Common data of signal source:

   int SourceCode() const { return sourceCode_; }
   ///< returns vdr internal code of signal source
   std::string TplFileName(int source);
	///< returns complete path and filename to transponder list
   std::string Position() const { return position_; }
	///< returns abrev. of sources eg. S19.2E
   std::string Description() const { return description_; }
	///< returns Descr. of sources eg. ASTRA ... 
   int LockMs() const { return lockMs_; }

private:
   cTransponders();
	~cTransponders();
	cTransponders(const cTransponders&);
	cTransponders &operator=(const cTransponders&);
	static cTransponders *instance_;
   int sourceCode_; 

   std::string SetPosition(std::string tplFileName);
   std::string SetDescription();

   std::string position_;
   std::string description_;
   std::string fileName_;
   int lockMs_;
};


// --- Class cTransponders 
inline cTransponders::~cTransponders()
{
   Clear();
}
inline cTransponders &cTransponders::GetInstance()
{
    assert(instance_);
	 return *instance_;
}

inline void cTransponders::Create()
{
	 if (!instance_)
    {
        dsyslog(DBG " Create Transponders");
        instance_ = new cTransponders();
    }
    else 
      dsyslog(DBG " Transponders have been Created already");
}
inline void cTransponders::Destroy()
{
    delete instance_;
    instance_ = NULL;
}

#endif //_TRANSPONDERS__H
