/*
 * See the files COPYING and README for copyright information and how to reach
 * the author.
 *
 *  $Id: process.h,v 1.4 2006/03/12 16:58:58 thomas Exp $
 */

#ifndef VDR_BURN_PROCESS_H
#define VDR_BURN_PROCESS_H

#include "common.h"
#include "pipe.h"
#include "environment.h"
#include <vdr/thread.h>
#include <string.h>
#include <locale.h>

class cBurnEnvironment;

using namespace vdr_burn;

class cBurnProcess: public cThread
{
	friend class cBurnPoller;

private:
	cBurnPipes       mPipes;
	eReturnStatus    mStatus;
	cBurnEnvironment mEnvironment;
	bool             mActive;
	bool             mBurning;
	int              mProgress;
	int              mBurnProgress;
	cString          mDataDir;
	cString          mTempDir;
	FILE            *mLogFile;

	int              mNumSteps;
	int              mCurStep;
	int              mSubStep;
	eNextStep        mNextStep;

protected:
	bool HasNext(void);
	void PutLine(const char *Line);

	virtual void Action(void);
	virtual void Process(int Step, int SubStep, const char *Line) = 0;
	virtual bool Continue(int Step, int SubStep) = 0;

	void SetProgress(int SubSteps, int Percent);
	void SetProgress(int SubSteps, int Subsub, int Subsubs, int Percent);

	void AddCmdline(const char *Command);
	//void AddProcedure(tBurnProc Procedure, void *Data);
	void SetStatus(eReturnStatus Status) { mStatus = Status; }
	void SetNextStep(eNextStep Next = nsNext) { mNextStep = Next; }
	void SetBurning(bool Burning, int Progress = 0);
	void SetLogFile(const char *FileName);
	void MakeDirectory(const char *Path) { mkdir(Path, 0700); }
	void MakeFifo(const char *FileName) { mkfifo(FileName, 0600); }
	void Execute(const char *Format, ...)
			__attribute__ ((format (printf, 2, 3)));
	bool Execute(cBurnPipe *Pipe);
	void PutEnvironment(const char *Name, const char *Value);
	void PutEnvironment(const char *Name, double Value);
	void PutEnvironment(const char *Name, int Value);

public:
	cBurnProcess(int NumSteps);
	virtual ~cBurnProcess();
	
	virtual void Stop(void);

	int Progress(void) const { return mProgress; }
	eReturnStatus Status(void) const { return mStatus; }
	bool Burning(int &Progress) const;
	const cString &TempDir(void) const { return mTempDir; }
	const cString &DataDir(void) const { return mDataDir; }
};

inline void cBurnProcess::PutEnvironment(const char *Name, const char *Value)
{
	mEnvironment.Put(Name, Value);
}

inline void cBurnProcess::PutEnvironment(const char *Name, double Value)
{
        char *old_locale, *saved_locale;
        old_locale = setlocale (LC_NUMERIC, NULL);
        saved_locale = strdup (old_locale);
        setlocale (LC_NUMERIC, "POSIX");
	mEnvironment.Put(Name, cString::sprintf("%f", Value));
        setlocale (LC_NUMERIC, saved_locale);
        free (saved_locale);	
}

inline void cBurnProcess::PutEnvironment(const char *Name, int Value)
{
	mEnvironment.Put(Name, cString::sprintf("%d", Value));
}

inline void cBurnProcess::SetBurning(bool Burning, int Progress) {
	mBurning = Burning;
	mBurnProgress = Progress;
}

inline bool cBurnProcess::Burning(int &Progress) const {
	if (mBurning)
		Progress = mBurnProgress;
	return mBurning;
}

#endif // VDR_BURN_PROCESS_H
