//------------------------------------------------------------
// $Id: hostForParallel.cc,v 1.2 2000/05/21 20:04:10 yamauchi Exp $
//------------------------------------------------------------
//	(M\pi)^2 host computer implementation for parallel version
//	1998/11/29
//	Copyright (C) 1996--1998 YAMAUCHI Hitoshi  山内 斉
//------------------------------------------------------------
#include <stdio.h>
#include "mpi2.h"
#include "object.h"
#include "Option.h"
#include "mpi2_funcs.h"
#include "mpi2communication.h"
#include "host.h"


void outputObjectsFromOnePE(const int PErank, const int hostRank, 
			    materialArrayClass* pMatArray, FILE *pfp)
{
    objBaseClass *pObj 		   = NULL;
    int  	  recvNumOfObjects = 0;	 // 1 つの PE から受信した obj 数
    int 	  beforeMaterialID = -1; // invalid value で初期化
    const int 	  LINEBUFSIZE 	   = 256;
    char 	  buf[LINEBUFSIZE];
    YorN 	  isOnePEdone 	   = NO;

    while(isOnePEdone == NO)
    {
	commMpi2_recvObject(PErank, hostRank, &pObj);
	if(pObj->who() == NULL_OBJ_E)
	{
	    // 1 つの PE からの送信終了
	    if(Option::getInstance()->getVerboseMode() == YES)
	    {
		cout << VERBOSEHEAD << " host:: " << " get null object." 
			" from " << PErank << ", number of recv objects = " << 
			recvNumOfObjects << endl;
		isOnePEdone = YES;
	    }
	}
	else
	{
	    // object 情報出力
	    assert(pObj->getMaterialID() >= 0);
	    if(beforeMaterialID != pObj->getMaterialID())
	    {
		// 一つ前の material ID と異なる ID -> 名前を出力
		materialClass *pMat = pMatArray->get(pObj->getMaterialID());
		fprintf(pfp, "m %s\n", pMat->getName());
	    }

	    // output object data : 放射済み radiosity を出力する
	    pObj->getMpi2Form(WITH_SHOT_RADOUT_e, buf);
	    fprintf(pfp, "%s\n", buf);
	    
	    // 出力した material を記録
	    beforeMaterialID = pObj->getMaterialID();
	}
    }
}    
    
//------------------------------------------------------------
// 全 PE から object の情報を get してファイルに書く
//------------------------------------------------------------
void hostComputerClass::
getAndOutRadioResult(void)
{
    assert(FileInfo::getInstance()->isRadioStageResultOut() == YES);
    const int FNAMEBUFSIZE = 128;
    char fnamebuf[FNAMEBUFSIZE];

    // write 可能なまだ存在していない FILE * を求める (ref. fileUtil.cc)
    FileInfo *pFi = FileInfo::getInstance();
    assert(pFi->isRadioStageResultOut() == YES);
    FILE *pfp = 
    	getUniqueWriteFP((const char*)(pFi->getRadioStageOutFileName()),
			 fnamebuf, FNAMEBUFSIZE);
    
    // 各 PE からデータを受け取る
    const int PEnum = (SysStat::getInstance()->getCommSize() - 1);

    for(int i = 0; i < PEnum; i++)
    {
	HostCommClass *pHcom = 
		new HostCommClass(HOSTCOM_Send_Patch_Descriptions_e);
	this->mSendHostCommBuf.enqNewedObjwithMaySend(pHcom, i);
	outputObjectsFromOnePE(i, this->getRank(), &(this->mMatArray), pfp);
    }
    fclose(pfp);

    cout << NORMALHEAD << " host:: output radiosity intermediate result. [" 
    	 << fnamebuf << "]" << endl;

    // gzip output file
    char combuf[FNAMEBUFSIZE];
    sprintf(combuf, "gzip %s", fnamebuf);
    system(combuf);

    cout << NORMALHEAD << " host :: compressed [" << fnamebuf << "] done. " 
         << getNowTime() << endl;
}

