//------------------------------------------------------------
// $Id: FileInfo.h,v 1.1.1.1 1999/11/25 06:26:11 yamauchi Exp $
//------------------------------------------------------------
//	(M\pi)^2 : file information 
//	1998年12月15日(火) option が繁雑になりすぎた．
// 	FileInfo  : 入出力のファイル情報 from option.h
//	Copyright (C) 1998 YAMAUCHI Hitoshi 山内 斉
//------------------------------------------------------------
#ifndef _FileInfo_h
#define _FileInfo_h 1

#include "mpi2.h"
#include "mpi2exit.h"
#include "myString.h"


// 残念ながらこの名前のファイル名は使えない
#define INIT_FILENAME "(none)"

//------------------------------------------------------------
// FileInfo : 読み，書くファイル情報と config file の Option 指定 
//------------------------------------------------------------
class FileInfo {
private:
    FileInfo(const FileInfo& rhs);
    const FileInfo& operator=(const FileInfo& rhs);

public:
    enum {
	FI_SAVE_PPM,		// save as ppm file 
	FI_SAVE_GFB,		// save as gfb file 
	FI_SAVE_ELSE
    };	

protected:
    // file In/Out
    myString mConfigFileName;	     // config file name
    myString mSpcFileName;	     // define space etc.. info file
    myString mSysInfoFileName;	     // system infomation
    myString mViewDataFileName;	     // view data information
    myString mMatFileName;	     // material info file
    myString mGeoFileName;	     // geometry information file
    myString mSaveResultFileName;    // output file name
    int      mSaveFileFormat;	     // output file format
    myString mVolumeInFileListName;  // volume data infile list name

    YorN     mIsRadioStageResOut;    // radiosity stage 終了時の結果の表示
    myString mRadioStageOutFileName; // radiosity result file base name    

    YorN     mIsRadioOutAt;	     // radiosity stage 指定 HC 破壊時
    int      mRadioOutStartHC;	     // for(i =  this->mRadioOutStartHC;
    int      mRadioOutEndHC;	     //     i <= this->mRadioOutEndHC;
    int      mRadioOutIncHCNum;	     //     i += this->mRadioOutIncHCNum)
    int      mRadioOutLoopVar;	     // loop 変数 i

    myString mRadioIntermFileBaseName;  // radiosity result file base name
    int      mRadioIntermFileType;	// shot,unshot,both intermediate result

    // Intensity Out : file info の名前に合わないかな?
    YorN     mIntensityImmediateOut; 

    // for genvol
    myString mCompressCommand;		// for compress output file (gzip)
    myString mGenvolOutFileNameFormat;	// volume 出力ファイル名 printf format

    // Profile Monitor 関係
    YorN     mIsTraceFileOut; 	     // trace file を作成するか
    YorN     mIsProgramMarkerOn;     // Program Marker を ON にするか
    YorN     mIsTraceOutUnshotRadiosity; // unshotradiosity を出力するか
    myString mTraceFileBaseName;	  

protected:			// for PRC method
    myString mDistanceDataFileName; // distance data information file

protected:
    YorN isFileNameOK(const myString apDataFname)
    {
	if(apDataFname == "")
	{
	    cerr << "Error! : illegal data filename (null data)" << endl;
	    commMpi2_exit(1);
	    return(NO);
	}else
	{
	    return(YES);
	}
    }

protected:
    // singleton pattern
    static FileInfo *PFileInfo;
public:
    static FileInfo *getInstance(void)
    {
	if(FileInfo::PFileInfo == NULL)
	{
	    FileInfo::PFileInfo = new FileInfo();
	}
	return(FileInfo::PFileInfo);
    }

public:
    FileInfo(void)
    {
	this->mConfigFileName 		= INIT_FILENAME;	
	this->mSpcFileName 		= INIT_FILENAME;
	this->mSysInfoFileName 		= INIT_FILENAME;
	this->mViewDataFileName 	= INIT_FILENAME;
	this->mMatFileName 		= INIT_FILENAME;
	this->mGeoFileName 		= INIT_FILENAME;
	this->mSaveResultFileName 	= INIT_FILENAME;
	this->mSaveFileFormat		= FI_SAVE_PPM;
	this->mVolumeInFileListName 	= INIT_FILENAME;

	this->mIsRadioStageResOut 	= NO;
	this->mRadioStageOutFileName 	= INIT_FILENAME;
	
	this->mIsRadioOutAt		=  NO;
	this->mRadioOutStartHC		=  -1;	     
	this->mRadioOutEndHC		=  -1;
	this->mRadioOutLoopVar		=   0;
	this->mRadioOutIncHCNum		= 256;
	this->mRadioIntermFileBaseName 	= INIT_FILENAME;
	this->mRadioIntermFileType	= -1;

	this->mDistanceDataFileName	= INIT_FILENAME;

	this->mIntensityImmediateOut	= NO;
	this->mCompressCommand		= "gzip";
	this->mGenvolOutFileNameFormat	= "volimg%04d.svol";

	// profile monitor
	this->mIsTraceFileOut		= NO;
	this->mIsProgramMarkerOn	= NO;
	this->mIsTraceOutUnshotRadiosity = NO;
	this->mTraceFileBaseName	= INIT_FILENAME;	  
    }

    // set filename functions
    void setConfigFileName(const myString& aConfigFname)
    {
	// この config filename のみは option で指定する
	isFileNameOK(aConfigFname);
	this->mConfigFileName = aConfigFname;
    }
    void setSpcFileName(const myString& aSpcFname)
    {
	isFileNameOK(aSpcFname);
	this->mSpcFileName = aSpcFname;
    }
    void setMatFileName(const myString& aMatFname)
    {
	isFileNameOK(aMatFname);
	this->mMatFileName = aMatFname;
    }
    void setGeoFileName(const myString& aGeoFname)
    {
	isFileNameOK(aGeoFname);
	this->mGeoFileName = aGeoFname;
    }
    void setSaveResultFileName(const myString& aSaveFname)
    {
	isFileNameOK(aSaveFname);
	this->mSaveResultFileName = aSaveFname;
    }
    void setSaveFileFormat(int format)
    {
	if((format < 0) || (FI_SAVE_ELSE <= format))
	{
	    cout << "Error! : FileInfo::setSaveFileFormat : no such "
	    "file format." << endl;
	}else
	{
	    this->mSaveFileFormat = format;
	}
    }
    void setSysInfoFileName(const myString& aSysinfoFname)
    {
	isFileNameOK(aSysinfoFname);
	this->mSysInfoFileName = aSysinfoFname;
    }
    void setViewDataFileName(const myString& aViewDataFname)
    {
	isFileNameOK(aViewDataFname);
	this->mViewDataFileName = aViewDataFname;
    }
    void setRadioStageOutFileName(const myString& aRadioStageOutFName)
    {
	isFileNameOK(aRadioStageOutFName);
	this->mRadioStageOutFileName = aRadioStageOutFName;
	this->mIsRadioStageResOut = YES;
    }
    void setRadioIntermediateBaseName(const myString& aRadioIntermFBName)
    {
	isFileNameOK(aRadioIntermFBName);
	this->mRadioIntermFileBaseName = aRadioIntermFBName;
    }
    void setVolumeInFileListName(const myString& aVolInFname)
    {
	isFileNameOK(aVolInFname);
	this->mVolumeInFileListName = aVolInFname;
    }
    void setDistanceDataFileName(const myString &aDistanceDataFname)// for PRC
    {
	isFileNameOK(aDistanceDataFname);
	this->mDistanceDataFileName = aDistanceDataFname;
    }
    void setIntensityImmidiateOut(void) 
    { 
	this->mIntensityImmediateOut	= YES; 
    }
    void setCompressCommand(const myString &aCompressCommand)
    {
	this->mCompressCommand = aCompressCommand;
    }
    void setGenvolOutFilename(myString &aGenvolFNameFormat) //for genvol4mpi2
    {
	this->mGenvolOutFileNameFormat = aGenvolFNameFormat;
    }
    void setTraceFileOut()
    {
	this->mIsTraceFileOut = YES;
    }
    void setProgramMarkerOn()
    {
	this->mIsProgramMarkerOn = YES;
    }
    void setTraceOutWithUnshotRadiosity()
    {
	this->mIsTraceOutUnshotRadiosity = YES;
    }
    void setTraceFileBaseName(const myString &aTraceFileBaseName)
    {
	this->mTraceFileBaseName = aTraceFileBaseName;
    }

    // get functions
    myString getConfigFileName(void) const 
    {
	return(this->mConfigFileName);	
    }
    myString getSpcFileName(void) const 
    {
	return(this->mSpcFileName);	
    }
    myString getMatFileName(void) const 
    {
	return(this->mMatFileName);	
    }
    myString getGeoFileName(void) const 
    {
	return(this->mGeoFileName);  
    }
    myString getSaveResultFileName(void) const 
    {
	return(this->mSaveResultFileName); 
    }
    int getSaveFileFormat(void) const 
    {
	return(this->mSaveFileFormat); 
    }
    myString getSysInfoFileName(void) const 
    { 
	return(this->mSysInfoFileName); 
    }
    myString getViewDataFileName(void) const 
    {
	return(this->mViewDataFileName);
    }
    myString getRadioStageOutFileName(void) const 
    {
	return(this->mRadioStageOutFileName);    	  
    }
    myString getRadioIntermediateBaseName(void) const
    {
	return(this->mRadioIntermFileBaseName);    	  
    }
    int getRadioIntermFileType(void) const 
    { 
	return(this->mRadioIntermFileType);
    }
    myString getVolumeInFileListName(void) const 
    {
	return(this->mVolumeInFileListName);    	  
    }
    myString getDistanceDataFileName(void) const // for PRC
    {
	return(this->mDistanceDataFileName);    	  
    }
    myString getCompressCommand(void) const
    {
	return(this->mCompressCommand);
    }
    myString getGenvolOutFileNameFormat(void) const // for genvol4mpi2
    {
	return(this->mGenvolOutFileNameFormat);
    }

    YorN isGeometryFile(void) const 
    {
	return(((this->mMatFileName != INIT_FILENAME) && 
		(this->mGeoFileName != INIT_FILENAME)) ? YES : NO);
    }
    YorN isVolumeFile(void) const 
    {
	return((this->mVolumeInFileListName != INIT_FILENAME) ? YES : NO);
    }
    YorN isRadioStageResultOut(void) const
    {
	return(this->mIsRadioStageResOut);
    }
    YorN isIntensityImmidiateOut(void) const 
    {
	return(this->mIntensityImmediateOut);
    }

    // profile monitor
    YorN isTraceFileOut() const
    {
	return(this->mIsTraceFileOut);
    }
    YorN isProgramMarkerOn() const
    {
	return(this->mIsProgramMarkerOn);
    }
    YorN isTraceOutWithUnshotRadiosity() const
    {
	return(this->mIsTraceOutUnshotRadiosity);
    }
    myString getTraceFileBaseName() const 
    {
	return(this->mTraceFileBaseName);
    }

    // loop
    YorN isRadioOutAtStep(void) const 
    {
	return(this->mIsRadioOutAt);	
    }
    void initLoopVar(void)
    {
	this->mRadioOutLoopVar = this->mRadioOutStartHC;
    }
    int isInLoop(void) const 
    {
	return(this->mRadioOutLoopVar <= this->mRadioOutEndHC);
    }
    void nextLoopVar(void)
    {
	this->mRadioOutLoopVar += this->mRadioOutIncHCNum;
    }
    int  getLoopVarValue(void) const { return(this->mRadioOutLoopVar);	}
    
    //------------------------------------------------------------
    // print out 
    //------------------------------------------------------------
    void print(const char *pHead) const;

    //------------------------------------------------------------
    // ここに保持されているファイル間の一貫性を見る (レンダリング時用)
    //------------------------------------------------------------
    YorN isOKforMpi2(void) const;

    //------------------------------------------------------------
    // config file を読む
    //------------------------------------------------------------
    YorN readConfigFile(void);

    //------------------------------------------------------------
    // ある file info でこの file info を上書きする
    //------------------------------------------------------------
    void overrideFileInfoWithOption(const FileInfo *pCommandLineFileInfo);
};


// singleton pattern
#ifdef THIS_IS_GLOBAL_DEFINE_FILE
FileInfo *FileInfo::PFileInfo = NULL;	
#endif				// #ifdef THIS_IS_GLOBAL_DEFINE_FILE

#endif				// #ifndef _FileInfo_h
