/*
 * $Id: Mpi2Option.java,v 1.11 2000/06/15 13:55:51 yamauchi Exp $
 *     (M\pi)^2 : (M\pi)^2 Option
 *	Copyright 1999 By YAMAUCHI Hitoshi 山内 斉 
 *	@author YAMAUCHI Hitoshi 山内 斉
 *
 * 	Mpi2Option  : コマンドラインのオプション関係
 *
 * original source Option.h
 * 
 * 1999年8月 1日(日)
 */

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

// import java.util.Map;
import jp.ac.tohoku.is.archi.mpi2.jdk12src.Map;

import jp.ac.tohoku.is.archi.mpi2.util.Assert;
import jp.ac.tohoku.is.archi.mpi2.util.Option;
import jp.ac.tohoku.is.archi.mpi2.util.IntVec3;
import jp.ac.tohoku.is.archi.mpi2.sysparam.FileInfo;
import jp.ac.tohoku.is.archi.mpi2.sysparam.Mpi2Constants;

/**
 * Mpi2Option : command line option management (switch)
 */
public final class Mpi2Option implements Mpi2Constants {
    /*
     * singleton pattern
     */
    static Mpi2Option singleMpi2Option;
    public static Mpi2Option getInstance() 
    {
	if(singleMpi2Option == null)
	{
	    singleMpi2Option = new Mpi2Option();
	}
	return(singleMpi2Option);
    }

    private boolean mIsVerbose;		// Verbose mode
    private boolean mIsDebug;		// 雑多なもの (for debug)
    private boolean mIsShowData;	// 読んだデータを出力する
    private boolean mIsShowNumobjInSpaces;// 各部分空間中の物体数を出力するか
    private boolean mIsOutPEmove;	// PE が動作しているかどうかを出力する
    private boolean mIsOutInterpSlices;	// 補間したスライスの出力を行うか
    private boolean mIsCompressOut;	// 出力ファイルを圧縮するか(今はall or nothing)

    private Mpi2Option()
    {
	this.mIsVerbose			= false;
	this.mIsDebug			= false;	
	this.mIsShowData		= false;
	this.mIsShowNumobjInSpaces	= false;
	this.mIsOutPEmove		= false;
	this.mIsOutInterpSlices		= false;
	this.mIsCompressOut		= false;
    }

    public void setVerboseMode()	
    {
	this.mIsVerbose         = true;
    }
    public void setDebugMode()		
    {
	this.mIsDebug           = true;
    }
    public void setShowData()		
    {
	this.mIsShowData        = true;
    }
    public void setShowNumobjInSpace()	
    {
	this.mIsShowNumobjInSpaces = true;
    }
    public void setOutPEmove()		
    {
	this.mIsOutPEmove       = true;
    }
    public void setSliceOut() 		
    {
	this.mIsOutInterpSlices = true;
    }
    public void setCompressOut()	
    {
	this.mIsCompressOut	   = true;
    }
    public void setNotCompress()	
    {
	this.mIsCompressOut	   = false;
    }
    
    public boolean getVerboseMode() 	
    {
	return(this.mIsVerbose); // ##
    }
    public boolean getDebugMode() 	
    {
	return(this.mIsDebug);	// <<
    }
    public boolean getShowDataMode() 	
    {
	return(this.mIsShowData);	
    }
    public boolean getShowNumobjInSpace()
    {
	return(this.mIsShowNumobjInSpaces);
    }
    public boolean getOutPEmove() 	
    {
	return(this.mIsOutPEmove);	
    }
    public boolean isSliceOut() 	
    {
	return(this.mIsOutInterpSlices);
    }
    public boolean isCompressOut()	
    {
	return(this.mIsCompressOut);	
    }
    
    public String toStringWithHead(String head)  
    {
	head += " ";
	String s = head + "----- Mpi2Option print -----\n";
	s += head + "mode : ";
	s += ((this.mIsVerbose  == true) ? "Verbose "   : "");
	s += ((this.mIsDebug    == true) ? "Debug "     : "");
	s += ((this.mIsShowData == true) ? "ShowData "  : "");
	s += ((this.mIsShowNumobjInSpaces == true) ? "ShowNumObjs " : ""); 
	s += ((this.mIsShowNumobjInSpaces == true) ? "CompressOut " : ""); 
	return(s);
    }

    /**
     * usage and exit for Mpi2Java
     */
    public static void usage()
    {
	String s = "This is mpi2, parallel multi-pass rendering program\n" +
	    "Informative output:\n"	+
	    "	-d, --debug	Debug mode\n"	+
	    "	-h, --help	Print this message\n"	+
	    "	-v, --verbose	Verbose mode\n"	+
	    "	-s, --showdata	Show read data\n"	+
	    "	-S, --shownumobjs	Show number of objects in subspaces\n"+
	    "Input filename selection:\n"	+
	    "	--conf   ... configuration (all config) file\n"	+
	    "	--spc    ... space (definespace etc.) file\n"	+
	    "	--sys    ... system configuration file\n"	+
	    "	--view   ... view file (viewpoint etc.)\n"	+
	    "	--mat    ... material information file\n"	+
	    "	--geo    ... geometry information file\n"	+
	    "	--vinl   ... volume data infile list file\n"	+
	    "Output filename selection:\n"	+	    
	    "	--rado    ... radiosity result as mpi2 patch(basename)\n"+
	    "	--saveppm ... rendering result as ppm format\n"	+
	    "	--savegfb ... rendering result as global frame buffer(gfb)"+ 
	    " format\n"	+
	    "	              refer to mpi2.GFBraw.doc\n\n"	+
	    "	contents of conffile is overrided with command line options.\n"
	    + Mpi2Constants.COPYRIGHT + "\n" + Mpi2Constants.VERSION;
	System.out.println(s);

	System.exit(1);
    }

    private static Option[] options = 
    {
	new Option("debug",   	"d"),
	new Option("help",    	"h"),
	new Option("verbose",   "v"),
	new Option("showdata", 	"s"),
	new Option("shownumobj","S"),
	new Option("conf", 	null, Option.REQUIRED_ARG, Option.STRING),
	new Option("spc",  	null, Option.REQUIRED_ARG, Option.STRING),
	new Option("mat",  	null, Option.REQUIRED_ARG, Option.STRING),
	new Option("geo",  	null, Option.REQUIRED_ARG, Option.STRING),
	new Option("saveppm", 	null, Option.REQUIRED_ARG, Option.STRING),
	new Option("savegfb", 	null, Option.REQUIRED_ARG, Option.STRING),
	new Option("sys",  	null, Option.REQUIRED_ARG, Option.STRING),
	new Option("view", 	null, Option.REQUIRED_ARG, Option.STRING),
	new Option("rado", 	null, Option.REQUIRED_ARG, Option.STRING),
	new Option("vinl", 	null, Option.REQUIRED_ARG, Option.STRING),
    };

    public static FileInfo getopt_newfileinfo(String [] args)
    {
	FileInfo fif = new FileInfo();

	Option.CommandLine cl = Option.parseCommandLine(options, args);
	Map opts = cl.getOptions();

	if(cl.getNonOptionIndex() < args.length)
	{
	    throw new RuntimeException("Error! : option must start at `-'.");
	}

	if(opts.get("debug") != null) 
	{
	    (Mpi2Option.getInstance()).setDebugMode();
	}	
	if(opts.get("help") != null) 
	{
	    Mpi2Option.usage();
	}	
	if(opts.get("verbose") != null) 
	{
	    (Mpi2Option.getInstance()).setVerboseMode();
	}	
	if(opts.get("showdata") != null) 
	{
	    (Mpi2Option.getInstance()).setShowData();
	}	
	if(opts.get("shownumobj") != null) 
	{
	    (Mpi2Option.getInstance()).setShowNumobjInSpace();
	}	
	if(opts.get("conf") != null) // config filename
	{
	    fif.setConfigFileName((String)opts.get("conf"));
	}
	if(opts.get("spc") != null) // space param filename
	{
	    fif.setSpcFileName((String)opts.get("spc"));	    
	}	
	if(opts.get("mat") != null) // material filename
	{
	    fif.setMatFileName((String)opts.get("mat"));	    
	}	
	if(opts.get("geo") != null) // geometry filename
	{
	    fif.setGeoFileName((String)opts.get("geo"));	    
	}	
	if(opts.get("saveppm") != null) // save result as ppm file
	{
	    fif.setSaveResultFileName((String)opts.get("saveppm"));
	    fif.setSaveFileFormat(FileInfo.FI_SAVE_PPM);
	}	
	if(opts.get("savegfb") != null) // save result as gfb file
	{
	    fif.setSaveResultFileName((String)opts.get("savegfb"));
	    fif.setSaveFileFormat(FileInfo.FI_SAVE_GFB);
	}	
	if(opts.get("sys") != null) // sysinfo file
	{
	    fif.setSysInfoFileName((String)opts.get("sys"));
	}	
	if(opts.get("view") != null) 
	{
	    fif.setViewDataFileName((String)opts.get("view"));
	}	
	if(opts.get("rado") != null) 
	{
	    fif.setRadioStageOutFileName((String)opts.get("rado"));	    
	}	
	if(opts.get("vinl") != null) 
	{
	    fif.setVolumeInFileListName((String)opts.get("vinl"));
	}	
	return(fif);
    }

    /*
     * message out related functions
     */
    /**
     * generate headder 
     */
    public static String toHead(String headder, IntVec3 PEid)
    {
	String s = headder;
	if(PEid.equals(HostID))
	{
	    s += " host::";       
	}
	else if(PEid.equals(IllegalPEID))
	{
	    s += " illegal PE, Error? :: ";
	}
	else
	{
	    s += " PE:: " + PEid + " ";
	}
	return(s);
    }
    public static String toHead(String headder, int rank)
    {
	String s = headder + " rank " + rank + " : ";
	return(s);    	
    }

    /**
     * verbose out : convenient function
     */
    public void verboseOut(String mes)
    {
	if(this.getVerboseMode())
	{
	    System.out.println(VERBOSEHEAD + " " + mes);
	}
    }

    /**
     * debug out : convenient function
     */
    public void debugOut(String mes)
    {
	if(this.getDebugMode())
	{
	    System.out.println(mes);
	}
    }

    /**
     * for test
     */
    public static void main(String [] arg)
    {
	FileInfo fif = getopt_newfileinfo(arg);
	System.out.println(Mpi2Option.getInstance().toStringWithHead(""));
	System.out.println(fif.toStringWithHead(""));
    }
}
