/*
 * $Id: Mpi21PE.java,v 1.11.4.2 2000/06/18 18:54:36 yamauchi Exp $
 *     (M\pi)^2 : Mpi2 for 1PE 
 *	Copyright (C) 1999 By YAMAUCHI Hitoshi 山内 斉 
 *	@author YAMAUCHI Hitoshi 山内 斉
 *	
 * original source main.cc
 *
 * 1999年8月 9日(月)
 */

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

import java.io.*;

import  jp.ac.tohoku.is.archi.mpi2.util.*;
import  jp.ac.tohoku.is.archi.mpi2.sysparam.*;
import  jp.ac.tohoku.is.archi.mpi2.net.*;
import  jp.ac.tohoku.is.archi.mpi2.common.*;


/**
 * for 1PE main
 */
public final class Mpi21PE 
implements Mpi2Constants, Mpi2Enum 
{
    /**
     * main
     * 	host computer 
     */
    private static void do_host(int hostrank)
    {
	(Host.getInstance()).init(hostrank);
	(Host.getInstance()).readAndDeliverAllData();
    }    

    /**
     * main
     *  PE : Processing Element
     */
    private static void do_PE()
    {
	PE pe = PE.getInstance();

	// GpPE.initBeforeRendeirng();
	if(Mpi2Option.getInstance().getShowDataMode() == true)
	{
	    pe.printSysInfo(NORMALHEAD);
	    pe.printMaterials(NORMALHEAD);
	    pe.printObjects(NORMALHEAD);
	}
	
	if(Mpi2Option.getInstance().getShowNumobjInSpace() == true)
	{
	    pe.printObjInSpcMap(NORMALHEAD);
	}

	// 本来は、host の送信(material, object)が終了したら command を待
	// つ．したがってここにはコマンドの dispatch routine が入る

	/*
	 * radiosity stage 
	 */
	if(Mpi2Option.getInstance().getVerboseMode())
	{
	    ElapsedTimer.outPERawTime("start radiosity stage.");
	}
	ElapsedTimer etimer = new ElapsedTimer();
	etimer.start();
	pe.doRadiosity();
	etimer.stop();		
	ElapsedTimer.outPEEtime("done radiosity stage.", etimer);
	if(Mpi2Option.getInstance().getVerboseMode())
	{
	    ElapsedTimer.outPERawTime("done radiosity stage.");
	}
	if(pe.peekSysInfo().isRadiosityCalc())
	{
	    pe.printStatInfo("Radiosity"); // 統計情報の出力
	}

	/*
	 * prepare shading stage 
	 */
	if(Mpi2Option.getInstance().getVerboseMode())
	{
	    ElapsedTimer.outPERawTime("start prepare shading.");
	}
	etimer.reset();
	etimer.start();
	pe.doPrepareShading();
	etimer.stop();		
	ElapsedTimer.outPEEtime("done prepare shading.", etimer);
	if(Mpi2Option.getInstance().getVerboseMode())
	{
	    ElapsedTimer.outPERawTime("done prepare shading.");
	}
	
	/*
	 * ray-tracing stage 
	 */
	if(Mpi2Option.getInstance().getVerboseMode())
	{
	    ElapsedTimer.outPERawTime("start ray-tracing stage.");
	}
	etimer.reset();
	etimer.start();
	pe.doRayTracing();
	etimer.stop();		
	ElapsedTimer.outPEEtime("done ray-tracing stage.", etimer);
	if(Mpi2Option.getInstance().getVerboseMode())
	{
	    ElapsedTimer.outPERawTime("done ray-tracing stage.");
	}
	if(pe.peekSysInfo().isRayTracingCalc())
	{
	    pe.printStatInfo("Ray-Tracing"); // 統計情報の出力
	}
	//System.out.println(NORMALHEAD + " PE skip/traverse spaces of rays " +
	//	   pe.getSkipSpcOfRays() + "/"+ pe.getTravSpcOfRays());
    }

    /**
     * initialize communicator of stand alone mode 
     */ 
    public static void initCommunicator(String [] args)
    {
	Mpi2CommFactory.initCommunicator(Mpi2Enum.MPI2COMM_OnePE);
	
	Mpi2CommFactory.getInstance().init(args);
    }
	
    /**
     * analize command line option
     */ 
    public static void analyzeCommandLine(String [] args)
    {
	// file info by command line option 
	FileInfo optionFIF = null;
	try {
	    optionFIF = Mpi2Option.getopt_newfileinfo(args);
	}catch(IllegalArgumentException e)
	{
	    System.out.println(e);
	    Mpi2Option.usage();
	    Mpi2CommFactory.getInstance().exit(1);
	}
	
	// real file information
	FileInfo fif = FileInfo.getInstance();
	if(!((optionFIF.getConfigFileName()).equals(FileInfo.INIT_FILENAME)))
	{
	    // Option で conf file が指定されていたなら読む
	    fif.setConfigFileName(optionFIF.getConfigFileName());
	    try {
		fif.readConfigFile();
	    }catch(IOException e)
	    {
		System.out.println(e);
	    }
	}

	// コマンドラインオプションをファイルで読み込んだものに上書きする．
	fif.overrideFileInfoWithOption(optionFIF);
	(SysStat.getInstance()).setHostRank(1); // stand alone
    }


    /**
     * stand alone (M\pi)^2 main
     */ 
    public static void main(String [] args) 
    {
	initCommunicator(args);

	analyzeCommandLine(args);

	// PrifileMonitor init
	ProfileMon.
	    getInstance().init(SysStat.getInstance().getMyRank(), 
			       FileInfo.getInstance().getTraceFileBaseName());

	if((Mpi2Option.getInstance()).getDebugMode())
	{
	    System.out.println((Mpi2Option.getInstance()).
			       toStringWithHead("//"));
	    System.out.println(FileInfo.getInstance().toStringWithHead("//"));
	}

	String s = 
	    "//-----------------------------------------------------\n" +
	    "// Stand Alone mode can not skip the radiosity stage.  \n" +
	    "// if you want to skip the radiosity stage. Please set \n" +
	    "// a minRadiationEnergy Huge val(like 1e20) in a view  \n" +
	    "// file data. and never off Rendering  = Radiosity     \n" +
	    "// in a sysinfo file.    Hitoshi Yamauchi              \n" +
// 	    "// Stand Alone mode ではラジオシティステージをスキップ \n" +
// 	    "// できません。しかし、minRadiationEnergy を大きな値に \n" +
// 	    "// することで同じ効果を得られます。ただし、sysinfo ファ\n" +
// 	    "// イルでは Rendering  = Radiosity を必ず指定して下さい\n" +
// 	    "//                       			山内斉      \n" +
	    "//-----------------------------------------------------";
	System.out.println(s);

	Mpi21PE.do_host(1);
	Mpi21PE.do_PE();
	
	Mpi2CommFactory.getInstance().finalizecommun();

	(Host.getInstance()).outResult();
	// 全員終了したら結果出力(あるいは 
	// ray-tracing では常に出力)
    }
}
