//------------------------------------------------------------
// $Id: host.h,v 1.2 2000/05/19 20:35:51 yamauchi Exp $
//------------------------------------------------------------
//	mpi2 host computer
//	1996/7/5
//	Copyright (C) 1996--1998 YAMAUCHI Hitoshi 山内 斉
//	host は rank = (size - 1) の者が担当する。
//------------------------------------------------------------
#ifndef _host_h
#define _host_h 1

#include "materialArray.h"
#include "spc2PE.h"
#include "frameBuffer.h"
#include "PEStat.h"
#include "HostComm.h"
#include "sysinfo.h"
#include "viewdata.h"
#include "SpaceParam.h"
#include "array3d.h"
#include "objectInfoInASpace.h"
#include "FileInfo.h"
#include "mySLQueue.h"
#include "Intensity.h"
#include "RecvBuffer.h"
#include "SendBuffer.h"

class hostComputerClass {
private:
    hostComputerClass(const hostComputerClass& rhs);
    const hostComputerClass& operator=(const hostComputerClass& rhs);

protected:
    int		       mRank;		    // 自分の rank

    SysInfoClass       mSysInfo; 	    // system info.
    ViewDataClass      mViewData;	    // view info.
    SpaceParam	       mSpcParam;	    // space division info.
    materialArrayClass mMatArray;	    // material

    spc2PEBaseClass    *mpSpace2PE;	    // space -> PE mapping

    // 各空間の物体の数の情報
    array3dClass< objectNumInASpaceClass > mObjInSpcInfoArray;

    frameBufferClass   mGlobalFrameBuffer;
    PEStatClass	      *mPEStats; 	    // PE の稼働状況
    int 	       mReqNumOfPEStopRays; // ray 発生停止を要求しているPE数


    // network interface unit for host
    mySLQueue  < IntensityClass * > mIntPtrQueue; // 輝度用ポインタ保持キュー
    RecvBuffer < IntensityClass >   mIntRecvBuff; // FIXME 複数持たせる

    // PE からの状態 (PEStat) を受信する．PE へ命令(HostComm)を送信する． 
    mySLQueue  < PEStatClass * > mPEStatRecvPtrQueue; // PEStat ptr 保持キュー
    RecvBuffer < PEStatClass   > mRecvPEStatBuf;
    SendBuffer < HostCommClass > mSendHostCommBuf;

protected:			// Host の統計情報
    HostStatistics mHStat;	

protected:			// for PRC method
    const char *mpDistanceDataFileName;	

protected:
    void checkSpcData(void);
    void mapSpacePE(void);
    int  getRank(void) const	{ return(this->mRank);	}

    void readSpcData(const char  *pSpcFname);
    void readSysinfo(const char  *pSysinfoFname);    
    void readViewdata(const char *pViewdataFname);    

    void readMatData(const char *pMatFname);
    void deliverMaterial(void);
    void broadNullMaterial(void);
    void readAndDeliverMaterialData(void);

    YorN readAndDeliverGeoData(const char *pGeoFname);
    void readAndDeliverObjectData(void); // object は Geo & Vol data から成る
    void deliverObjInSpaceInfoSoboku(void); // 物体の素朴な存在データ表配布
    void broadNullObject(void);

    void saveResult(const char *outFile);

    void initPEStatAllMoving(void);
    void initRadiosityStage()
    {
	this->mReqNumOfPEStopRays = 0;
	this->initPEStatAllMoving();

	// 輝度情報の受信部初期化
	// 	this->mIntRecvBuff.init(this->mSysInfo.getSendInt2FBAtOnce(), 
	// 				&(this->mIntPtrQueue));

	this->mHStat.init();	// 統計情報の初期化
    }
    void initRayTraceStage()
    {
	this->mReqNumOfPEStopRays = 0;
	this->initPEStatAllMoving();
	// 輝度情報の受信部初期化
	this->mIntRecvBuff.init(this->mSysInfo.getSendInt2FBAtOnce(), 
				&(this->mIntPtrQueue));
	this->mHStat.init();	// 統計情報の初期化
    }

    void updatePEstat(const PEStatClass& PEstat);
    void analyzePEInfo(const PEStatClass& PEstat);
    YorN movingPE(void);
    void broadHostCommand(const HostCommClass& hostComm);
    void printObjInSpcMap(void) const;

    // consistent check
    void consistencyCheck(void);
    
protected:
    // volume rendering related functions (ref. in volumeReadHoost.cc)
    int  readAndDeliverVolDataAll(void);
    YorN readAndDeliverVolOneData(const char *pFile, int volumeID);
    void broadNullVolume(int maxNumOfDeliverdVolume);

protected:
    // for PRC method : データ表配布 deliverSkipInfoPRC.cc で実装
    //tokunaga changed	
    void PRC_deliverSkipInfoMap(const char  *pDistanceFname);    

protected:
    //------------------------------------------------------------
    // Host と PE 間の通信
    //------------------------------
    void initNetworkInterfaceUnit(void);

public:
    hostComputerClass(void);
    void init(int rank);
    void readAndDeliverAllData(void);
    void doRadiosity(void);
    void getAndOutRadioResult(void);
    void doPrepareShading(void);
    void doRayTracing(void);
    void outResult(void);
    void barrierSync(void);	// PE含むバリア同期 time outあり失敗するとexit
	
    void setIntensity(const IntensityClass& intensity)
    {
	this->mGlobalFrameBuffer.setIntensity(intensity);
    }
    IntVec3 getPEIDfromSpcPos(const IntVec3 &spcpos)
    {
	return(this->mpSpace2PE->getPEIDfromSpcPos(spcpos));
    }

    //------------------------------
    // get Rank (PEClass:: にもある) PE の id から serial ID を得る
    // serial id = (IDz * PEx * PEy) + (IDy * PEx) + IDx
    //	         = PEx * (IDz * PEy + IDy) + IDx
    //------------------------------
    int getRank(const IntVec3& PEid) const
    {
	int rank = 
	    this->mSysInfo.getPEDim().get(IntVec3::X) * 
		(PEid.get(IntVec3::Z) * 
		 this->mSysInfo.getPEDim().get(IntVec3::Y)
		 + PEid.get(IntVec3::Y)) + PEid.get(IntVec3::X);
	return(rank);
    }
};

#endif				// #ifndef _host_h
