#include <string>
#include <iostream>  
#include <fstream>   
#include "recstatus.h"
#include "grabberthread.h"
#include "log.h"

using std::string;
using std::ofstream;

cRecStatusMonitor* gl_recStatusMonitor = NULL;

cRecStatusMonitor::cRecStatusMonitor()
{
    cGrabberThread::channelsSupported.clear();
    // Deluxe
    cGrabberThread::channelsSupported.insert(cChannelSupported("S19.2E-1-1092-10100", DELUXE_EPG));
}

const cChannel* cRecStatusMonitor::GetDeluxeChannel()
{
    return Channels.GetByChannelID(tChannelID::FromString("S19.2E-1-1092-10100"));
}

void cRecStatusMonitor::Recording(const cDevice *Device, const char *Name, const char* Filename, bool On) 
{
    // insert new timers currently recording in TimersRecording
    if (On && Name)
    {
	for (cTimer *ti = Timers.First(); ti; ti = Timers.Next(ti)) 
	    if (ti->Recording())
	    {
		// check if this is a new entry
		cRecTimerObj *tiRFound = NULL;
		for (cRecTimerObj *tiR = TimersRecording.First(); tiR; tiR = TimersRecording.Next(tiR)) 
		    if (tiR->timer == ti)
		    {
			tiRFound = tiR;
			break;
		    }

		if (tiRFound) continue; 

		cRecTimerObj* timerObj = new cRecTimerObj(ti, Device->DeviceNumber());
		TimersRecording.Add(timerObj);

		string channelID = *ti->Channel()->GetChannelID().ToString();
		if (cGrabberThread::ChannelSupported(channelID))
		{
		    LogFile.Log(1,"deluxe recording started '%s' on device %d", Name, Device->CardIndex());
		    // create a marker file in the recording dir to mark this recording for later processing
		    string filenameMarker = string(Filename) + "/deluxe";
		    // open output file
		    ofstream file(filenameMarker.c_str());
		    // file opened?
		    if (! file) 
			LogFile.eSysLog( "could not create file '%s'", filenameMarker.c_str());
		    else
			file << channelID;

		    set<cChannelSupported>::iterator chit = cGrabberThread::GetChannel(channelID);
		    cChannelSupported chSup = *chit;
		    chSup.currentRecs++;
		    cGrabberThread::channelsSupported.erase(chit);
		    cGrabberThread::channelsSupported.insert(chSup);
		}
	    }
    }
    
    if (!On)
    {
	// remove timers that finished recording from TimersRecording
	cRecTimerObj *tiR = TimersRecording.First();
	while(tiR)
	{
	    // check if timer still exists
	    bool found = false;
	    for (cTimer *ti = Timers.First(); ti; ti = Timers.Next(ti)) 
		if (ti == tiR->timer) 
		{
		    found = true;
		    break;
		}

	    if (!found || (found && !tiR->timer->Recording()))
	    {
		if (found)
		{
		    string channelID = *tiR->timer->Channel()->GetChannelID().ToString();
		    if (cGrabberThread::ChannelSupported(channelID))
		    {
			set<cChannelSupported>::iterator chit = cGrabberThread::GetChannel(channelID);
			cChannelSupported chSup = *chit;
			chSup.currentRecs--;
			cGrabberThread::channelsSupported.erase(chit);
			cGrabberThread::channelsSupported.insert(chSup);
		    }
		}
		cRecTimerObj *tiRNext = TimersRecording.Next(tiR);
		TimersRecording.Del(tiR);
		tiR = tiRNext;
		continue;
	    }
	    tiR = TimersRecording.Next(tiR);
	}
    }

    bool deluxeActive = false;
    // check current timers for any active recording on supported channels
    for (cTimer *ti = Timers.First(); ti; ti = Timers.Next(ti)) 
	if (ti->Recording()) 
	{
	    string channelID = *ti->Channel()->GetChannelID().ToString();		    
	    if (cGrabberThread::ChannelSupported(channelID))
		deluxeActive = true;
	    break;
	}
    if (deluxeActive)
	cGrabberThread::Init();
    else
	cGrabberThread::Exit();
}


