//------------------------------------------------------------
// $Id: ddaInfo.h,v 1.2 2000/06/14 13:29:37 yamauchi Exp $
//------------------------------------------------------------
//	DDA information (from ray)
//	1998年1月29日(木)
//	(C) Copyright Hitoshi YAMAUCHI
//	3DDDA のための情報
//------------------------------------------------------------
#ifndef _ddaInfo_h
#define _ddaInfo_h 1

#include "mpi2.h"
#include "Vector3.h"

//------------------------------------------------------------
// DDA のための情報を保持するクラス
//------------------------------------------------------------
class DDAInfoClass {
protected:
    //----- 3DDDA のための情報を分離しました 
    // DDAの計算がなされたか mDDAsetVolID >= 0 の時には計算されている 
    // volume の場合には volume ID が入っている。 
    YorN     	  mIsInit;	// NO の時には初期化されていない
    Vector3 	  mRelativePos;	// セル中心からの相対座標
    Vector3 	  mDDAVec;	// DDAの進行ベクトル
    int     	  mTraverseAxis;// 進行軸 (Vector3::Direction)
    DIR_3D  	  mGoingdir;	// 実際に進む方向を 6 方向で示す

public:
    DDAInfoClass(void) : 
    mIsInit(NO), mTraverseAxis(-1), mGoingdir(DIR_ILLEGAL){}
    // ~DDAInfoClass(void);
    DDAInfoClass(const DDAInfoClass& rhs)
    {
	this->mIsInit		= rhs.mIsInit;
	this->mRelativePos	= rhs.mRelativePos;
	this->mDDAVec		= rhs.mDDAVec;
	this->mTraverseAxis	= rhs.mTraverseAxis; 
	this->mGoingdir		= rhs.mGoingdir;
    }
    const DDAInfoClass& operator=(const DDAInfoClass& rhs)
    {
	if(this != &rhs)
	{
	    this->mIsInit	= rhs.mIsInit;
	    this->mRelativePos	= rhs.mRelativePos;
	    this->mDDAVec	= rhs.mDDAVec;
	    this->mTraverseAxis	= rhs.mTraverseAxis; 
	    this->mGoingdir	= rhs.mGoingdir;
	}
	return(*this);
    }
    friend int operator==(const DDAInfoClass& rhs, const DDAInfoClass& lhs)
    {
	return((lhs.mIsInit		== rhs.mIsInit)	&&
	       (lhs.mRelativePos	== rhs.mRelativePos)	&&
	       (lhs.mDDAVec		== rhs.mDDAVec)		&&
	       (lhs.mTraverseAxis	== rhs.mTraverseAxis)	&&
	       (lhs.mGoingdir		== rhs.mGoingdir));
    }
    friend int operator!=(const DDAInfoClass& rhs, const DDAInfoClass& lhs)
    {
	return((lhs.mIsInit		!= rhs.mIsInit)	||
	       (lhs.mRelativePos	!= rhs.mRelativePos)	||
	       (lhs.mDDAVec		!= rhs.mDDAVec)		||
	       (lhs.mTraverseAxis	!= rhs.mTraverseAxis)	||
	       (lhs.mGoingdir		!= rhs.mGoingdir));
    }
    void invalidateInit(void)	
    {
	this->mIsInit	= NO;
#ifndef NDEBUG
	this->mRelativePos.set(-1.0, -2.0, -3.0);	
	this->mDDAVec.set(-1.0, -2.0, -3.0);	
	this->mTraverseAxis	= -2;
	this->mGoingdir		= DIR_ILLEGAL;
#endif
    }
    //----- get functions
    YorN    isDDAinited(void) const	
    {
	return(this->mIsInit);	
    }
    Vector3 getRelativePos(void) const	
    {
	return(this->mRelativePos);	
    }
    Vector3 getDDAVec(void) const 	
    {
	return(this->mDDAVec);	
    }
    int     getTravAxis(void) const 	
    {
	return(this->mTraverseAxis);	
    }
    DIR_3D  getGoingDir(void) const 	
    {
	return(this->mGoingdir);	
    }

    //----- set functions
    void   setDDAset(void);
    // void   setDDAsetWithVolID(int volID);
    void   setRelativePos(const Vector3& rpos)
    {
	this->mRelativePos = rpos;
    }
    void   changeRelativePos(const double d1, const int dir1,
			     const double d2, const int dir2);     	  
    void   setDDAVec(const Vector3& aDDA)  
    {
	this->mDDAVec = aDDA;
    }
    void   setTravAxis(const int aV)	   
    {
	this->mTraverseAxis = aV; 
    }
    void   setGoingDir(DIR_3D goingdir);

    // print out
    void print(const char *pHead) const;
};

#endif				// #ifndef _ddaInfo_h 
