//------------------------------------------------------------
// $Id: Option.h,v 1.2 2000/06/14 13:29:37 yamauchi Exp $
//------------------------------------------------------------
//	(M\pi)^2 option analysis and keeping class
//	1996/7/5
//	Copyright (C) 1996--1998 YAMAUCHI Hitoshi 山内 斉
// Option と FileInfo を分離 1998年12月15日(火)
//------------------------------------------------------------
#ifndef _option_h
#define _option_h 1

#include <assert.h>
#include <stdio.h>
#include <iostream.h>
#include "mpi2.h"
#include "constants.h"

//------------------------------------------------------------
// command line option management (switch)
//------------------------------------------------------------
class Option {
private:
    Option(const Option& rhs);
    const Option& operator=(const Option& rhs);

protected:
    YorN mIsVerbose;		// Verbose mode
    YorN mIsDebug;		// 雑多なもの (for debug)
    YorN mIsShowData;		// 読んだデータを出力する
    YorN mIsShowNumobjInSpaces;	// 各部分空間中の物体数を出力するか
    YorN mIsOutPEmove;		// PE が動作しているかどうかを出力する
    YorN mIsOutInterpSlices;	// 補間したスライスの出力を行うか
    YorN mIsCompressOut;	// 出力ファイルを圧縮するか(今はall or nothing)
    // YorN mIsViewNoCheck;	// view param が不正に近くても実行するか

protected:
    // singleton method
    static Option *POption;
public:
    static Option *getInstance(void) 
    {
	if(POption == NULL)
	{
	    POption = new Option();
	}
	return(POption);
    }

public:
    Option(void)
    {
	this->mIsVerbose		= NO;
	this->mIsDebug			= NO;	
	this->mIsShowData		= NO;
	this->mIsShowNumobjInSpaces	= NO;
	this->mIsOutPEmove		= NO;
	this->mIsOutInterpSlices	= NO;
	this->mIsCompressOut		= NO;
    }

    void setVerboseMode(void)		
    {
	this->mIsVerbose         = YES;
    }
    void setDebugMode(void)		
    {
	this->mIsDebug           = YES;
    }
    void setShowData(void)		
    {
	this->mIsShowData        = YES;
    }
    void setShowNumobjInSpace(void)	
    {
	this->mIsShowNumobjInSpaces = YES;
    }
    void setOutPEmove(void)		
    {
	this->mIsOutPEmove       = YES;
    }
    void setSliceOut(void) 		
    {
	this->mIsOutInterpSlices = YES;
    }
    void setCompressOut(void)		
    {
	this->mIsCompressOut	   = YES;
    }
    void setNotCompress(void)		
    {
	this->mIsCompressOut	   = NO;
    }

    YorN getVerboseMode(void) const	
    {
	return(this->mIsVerbose); // ##
    }

    YorN getDebugMode(void) const	
    {
	return(this->mIsDebug);	// <<
    }
    YorN getShowDataMode(void) const	
    {
	return(this->mIsShowData);	
    }
    YorN getShowNumobjInSpace(void)const
    {
	return(this->mIsShowNumobjInSpaces);
    }
    YorN getOutPEmove(void) const	
    {
	return(this->mIsOutPEmove);	
    }
    YorN isSliceOut(void) const		
    {
	return(this->mIsOutInterpSlices);
    }
    YorN isCompressOut(void)		
    {
	return(this->mIsCompressOut);
    }
    
    void print(const char *pHead) const 
    {
	cout << pHead << "----- Option print -----" << endl;
	cout << pHead << "mode :";
	cout << ((this->mIsVerbose  == YES) ? "Verbose "   : "");
	cout << ((this->mIsDebug    == YES) ? "Debug "     : "");
	cout << ((this->mIsShowData == YES) ? "ShowData "  : "");
	cout << ((this->mIsShowNumobjInSpaces == YES) ? "ShowNumObjs " : ""); 
	cout << ((this->mIsShowNumobjInSpaces == YES) ? "CompressOut " : ""); 
	cout << endl;
    }
};

//------------------------------------------------------------
// system stat
//------------------------------------------------------------
class SysStat {
protected:
    int mCommSize;		// このタスクの大きさ
    int mMyRank;		// 自分のランク
    int mHostRank;		// host のランク
    
protected:
    // singleton
    static SysStat *PSysStat;
public:
    static SysStat *getInstance(void) 
    {
	if(PSysStat == NULL)
	{
	    PSysStat = new SysStat();
	}
	return(PSysStat);
    }

public:
    SysStat(void) : mCommSize(-1), mMyRank(-1), mHostRank(-1){}
    void setCommSize(int commSize)
    {
	assert(commSize > 1);
	this->mCommSize = commSize;
    }
    int  getCommSize(void) const 	
    {
	return(this->mCommSize);	
    }
    void setMyRank(int aMyRank)
    {
	assert(aMyRank >= 0);	
	this->mMyRank = aMyRank;
    }
    int  getMyRank(void) const	
    {
	return(this->mMyRank);	
    }
    void setHostRank(int aHostRank)
    {
	assert(aHostRank > 0);	// host rank は最後の rankで PE数 > 0から 0 
	this->mHostRank = aHostRank; // の hostrank はなくそれ以上になる
    }
    int  getHostRank(void) const	
    {
	return(this->mHostRank);	
    }
};
    

//------------------------------------------------------------
// singleton pattern init
//------------------------------------------------------------
#ifdef THIS_IS_GLOBAL_DEFINE_FILE
Option  *Option::POption   = NULL;
SysStat *SysStat::PSysStat = NULL;
#endif				// #ifdef THIS_IS_GLOBAL_DEFINE_FILE

#endif				// #ifndef _option_h

