//------------------------------------------------------------
// $Id: readSpcParam.cc,v 1.3 2000/05/19 20:35:51 yamauchi Exp $
//------------------------------------------------------------
//	read space parameter with lineParser for (M\pi)^2
//	1998/6/29
//	Copyright (C) 1998 YAMAUCHI Hitoshi 山内 斉
//------------------------------------------------------------
#include <stdio.h>
#include <iostream.h>
#include <assert.h>
#include "Vector3.h"
#include "lineParser.h"
#include "SpaceParam.h"
#include "mpi2_funcs.h"

// 読み込みに利用するバッファのサイズ
static const int MAX_LINE 	= 1024;

// Space Param が扱うベクトルの要素数は 3次元 x 2 = 6
static const int ELEM_OF_VECTOR = 6; 

//------------------------------
// read space parameter file 
//------------------------------
YorN readSpcparamFile(const char *pSpcFileName, SpaceParam *pSpcParam)
{
    FILE *pfp = getOpenedFp(pSpcFileName);
    if(pfp == NULL)
    {
	return(NO);
    }

    // 読み取るもの
    Vector3 defspcMin,  defspcMax;
    Vector3 partVolMin, partVolMax;
    int     spcDivNum = -1;

    // space parameter は 3 つの項目を扱う
    const int entrynum = 3;
    LineParser lp(entrynum);
    LineParserNumberElem lpElem[entrynum];

    // lineParserClass の管理するエントリ番号のテーブル 
    enum entry_e { 
	SPCPARAM_DEFSPC,	// definespace	: 定義空間
	SPCPARAM_PARTVOL,	// partvol	: 物体存在空間
	SPCPARAM_PARTNUM	// partnum	: 定義空間の分割数/1軸
    };

    lpElem[SPCPARAM_DEFSPC ].set("definespace", ELEM_OF_VECTOR);
    lpElem[SPCPARAM_PARTVOL].set("partvol", 	ELEM_OF_VECTOR);	
    lpElem[SPCPARAM_PARTNUM].set("partnum", 1);	   // 分割数は 1 つの整数

    // set entries 
    for(int i = 0; i < entrynum; i++)
    {
	lp.addEntry(&(lpElem[i]));	
    }
    
    // read file and analize
    YorN isParseOK = YES;
    char buf[MAX_LINE];
    int  line = 0;
    while(fgets(buf, MAX_LINE, pfp) != NULL)
    {
	line++;
	if((buf[0] == '\n') || (buf[0] == '#'))	// skip void line and comment 
	{
	    continue;
	}

	LineParserElemIF *pMatchElemIF = NULL;
	if(lp.evalOneLine(buf, &pMatchElemIF) == YES) 
	{
	    // ここではベクトルのみ
	    assert(pMatchElemIF->getType() == LP_NUMBER_e); 
	    LineParserNumberElem *pMatchNumElem = 
	    	(LineParserNumberElem *)pMatchElemIF;

	    double dval[6];
	    for(int i = 0; i < pMatchNumElem->getVectorLen(); i++)
	    {
		dval[i] = pMatchNumElem->getVecValue(i);
	    }

	    if(pMatchNumElem->getIdentifier() == "definespace")
	    {
		// definespace	: 定義空間
		assert(pMatchNumElem->getVectorLen() == 6);
		defspcMin.setByArray(&(dval[0]));
		defspcMax.setByArray(&(dval[3]));
	    }
	    else if(pMatchNumElem->getIdentifier() == "partvol")
	    {
	    	// partvol	: 物体存在空間
		assert(pMatchNumElem->getVectorLen() == 6);
		partVolMin.setByArray(&(dval[0]));
		partVolMax.setByArray(&(dval[3]));
	    }
	    else if(pMatchNumElem->getIdentifier() == "partnum")
	    {
	     	// partnum	: 定義空間の分割数/1軸
		assert(pMatchNumElem->getVectorLen() == 1);
		spcDivNum = int(dval[0]);
	    }
	    else
	    {
		cout << "Error! : illegal entry : line " << line << 
		    " in [" << pSpcFileName << "]\n" << buf << endl;
		isParseOK = NO;
	    }
	}else
	{
	    cout << "Error! : can not analize : line " << line << 
		" in [" << pSpcFileName << "]\n" << buf << endl;
	    isParseOK = NO;
	}
    }
    if(lp.getNumberofUnparsedEntries() > 0)
    {
	cout << "Error! : There is unpursed entry."<< endl;
	lp.printUnparsedEntries();
	isParseOK = NO;
    }

    pSpcParam->setDefSpace(defspcMin, defspcMax);
    pSpcParam->setPartVolume(partVolMin, partVolMax);
    pSpcParam->setSubDivNumNinitCellLen(spcDivNum);

    fclose(pfp);
    return(isParseOK);
}


#ifdef ReadSpcParamTEST
int main(int argc, char *argv[])
{
    if(argc != 2)
    {
	cout << "Usage: " << argv[0] << " volume infile" << endl;
	exit(1);
    }
    Vector3 defmin, defmax, partmin, partmax;
    int spcSubDivNum = 0;
    if(readSpcParam(argv[1], &defmin, &defmax, 
		    &partmin, &partmax, &spcSubDivNum) == NO)
    {
	cout << "Error! : illegal volume infile" << endl;
	exit(1);
    }else
    {
	cout << "Define    Space  (" << defmin << ")-(" << defmax << ")"
	    << endl;
	cout << "Partition Volume (" << partmin << ")-(" << partmax << ")" 
	    << endl;	
	cout << "SubDivision Number = " << spcSubDivNum << endl;
    }
    return(0);
}
#endif

// g++ -I../mpi2dataReader -I../1PE -DReadSpcParamTEST readSpcParam.cc Vector3.o lineParser.o myString.o getvals.o
