/*
 * $Id: PEStat.java,v 1.4 1999/10/05 14:25:24 yamauchi Exp $
 *     (M\pi)^2 : PEStat : PE Status object
 *	Copyright 1999 By YAMAUCHI Hitoshi 山内 斉 
 *	@author YAMAUCHI Hitoshi 山内 斉
 *	
 * original source PEStat.h
 *
 *	PE の情報を通信する際に利用するもの
 * 
 * 1999年8月18日(水)
 */

package jp.ac.tohoku.is.archi.mpi2.obj;

import	java.io.Serializable;
import	jp.ac.tohoku.is.archi.mpi2.sysparam.*;
import	jp.ac.tohoku.is.archi.mpi2.util.*;

public final class PEStat 
implements Encodable // , Serializable
{
    /*
     * PE の状態を伝える
     */
    public final static int PESt_Idle	= 0;
    public final static int PESt_BUSY	= 1;
    public final static int PESt_Ack	= 2; // for acknowledge
    public final static int PESt_ELSE	= 3;

    /*
     * PE からの host への要求
     */
    // システムに ray の発生停止を要求
    public final static int PEReq_StopGenRays 	= 0;
    // システムに ray の発生再開を要求
    public final static int PEReq_ResumeGenRays	= 1; 
    public final static int PEReq_ELSE		= 2;

    /* 
     * 送信する情報
     */
    private int mPEStat;	// status
    private int mPEReq;		// request
    private int mSrcRank;	// source rank

    /**
     * constructor 
     *	初期状態は busy で request はない
     */
    public PEStat()
    {
	this.mPEStat 	= PESt_BUSY;
	this.mPEReq  	= PEReq_ELSE;
	this.mSrcRank 	= -1;
    }
    public PEStat(int stat, int req, int srcRank)
    {
  	this.mPEStat  = stat;
  	this.mPEReq   = req;
  	this.mSrcRank = srcRank;
    }
    public PEStat(PEStat rhs)
    {
	this.mPEStat 	= rhs.mPEStat;
	this.mPEReq	= rhs.mPEReq;
	this.mSrcRank	= rhs.mSrcRank;
    }

    
    /**
     * set status 
     */
    public void set(PEStat rhs)
    {
	this.mPEStat 	= rhs.mPEStat;
	this.mPEReq	= rhs.mPEReq;
	this.mSrcRank	= rhs.mSrcRank;
    }

    /**
     * set status busy
     */
    public void setBusy(int srcRank)
    { 
	this.mPEStat 	= PESt_BUSY;	
	this.mPEReq 	= PEReq_ELSE;	
	this.mSrcRank 	= srcRank;
    }

    /**
     * set status idle
     */
    public void setIdle(int srcRank) 	
    { 
	this.mPEStat 	= PESt_Idle;	
    	this.mPEReq	= PEReq_ELSE;	
	this.mSrcRank 	= srcRank;
    }    

    /**
     * set acknowledge
     */
    public void setAck(int srcRank) 	
    { 
	this.mPEStat 	= PESt_Ack;	
    	this.mPEReq	= PEReq_ELSE;	
	this.mSrcRank 	= srcRank;
    }    

    /**
     * get PE status
     */
    public int getStat()
    {
	return(this.mPEStat);	
    }

    /**
     * request to host : Stop Generate rays
     */
    public void setReqStopGenRay(int srcRank)
    { 
	this.mPEStat 	= PESt_ELSE;	
    	this.mPEReq 	= PEReq_StopGenRays;	
	this.mSrcRank 	= srcRank;
    }    

    /**
     * request to host : resume generate rays
     */
    public void setReqResumeGenRay(int srcRank) 	
    { 
	this.mPEStat 	= PESt_ELSE;	
    	this.mPEReq 	= PEReq_ResumeGenRays;	
	this.mSrcRank 	= srcRank;
    }    

    /**
     * get PE Request
     */
    public int getRequest() 
    {
	return(this.mPEReq);	
    }

    /**
     * get src rank : 発信元
     */
    public int getSrcRank()
    {
	return(this.mSrcRank);	
    }

    /**
     * charactor representation of this class
     */
    private static String [] mStat = {  "I", "B", "A", "-", };
    private static String [] mReq  = {  "s", "r", "-", };
    public String toString() 
    {
	return(mStat[this.mPEStat] + ":" + mReq[this.mPEReq]);
    }

    /**
     * 通信用のタグを返す
     */
    public static int getTAG() 
    {
	return(Mpi2Enum.TAG_PE_STATUS);	
    }

    /*
     * Implements Encodable
     */
    public int sizeInDouble() 
    {
	// int mPEStat, mPEReq, mSrcRank;
	return(3);
    }
    public void encodeInDouble(double[] array, int offset) 
    {
	array[offset] 		= (double)(this.mPEStat);
	array[offset + 1] 	= (double)(this.mPEReq);
	array[offset + 2] 	= (double)(this.mSrcRank);
    }

    /*
     * Implements ObjectDecoder
     */
    private static class PEStatObjectDecoder implements ObjectDecoder 
    {
    	public int sizeInDouble() 
	{
	    return(3);
	}
    	public Object decodeFromDouble(double[] array, int offset)
	{
	    return(new PEStat((int)(array[offset]), 
			      (int)(array[offset + 1]), 
			      (int)(array[offset + 2])));
	}
    }
    private final static ObjectDecoder mODInstance 
    	= new PEStatObjectDecoder();
    public static ObjectDecoder getObjectDecoder() 
    {
	return(mODInstance);
    }
}
