/*
 * ServiceWrapper.java
 * Created on 5th July 11:40
 */
import javax.xml.rpc.Stub;
import java.rmi.RemoteException;
import surface.*;
import seqgen.*;
import xprodgen.*;
import randgen.*;
import visualiser.*;
import converter.*;
import java.io.*;
/**
 * Class for wrapping the calls to the services 
 * RandGen, SeqGen, XProdGen, Surface, Visualiser and Converter
 * @author sara
 */
public class ServiceWrapper{

    /** Generates a random set of 2D data (x,y) pairs which is
     * stored in FileStore
     * @param boundary the bounding box defining the ranges for the
     * random pairs.
     * @param count the number of pairs to be generated
     * @param name the name of the file in which to store the data
     * @param dataDir the sub-directory in FileStore where the
     * file will be put.
     */
    public static void randgen(Box boundary, int count, String name, 
			     String dataDir, String store){
	try{
	    //file and directory for random 2D data
	    randgen.FileName2D fileName = 
		new randgen.FileName2D(dataDir,name);
	    randgen.URLFileName2D fileURL = 
		new randgen.URLFileName2D(fileName,store);

	    //generate the random 2D data which is automatically
	    //stored using FileStore
	    RandGen_Impl randGenService = new RandGen_Impl();
	    RandomGen randGenPort = randGenService.getRandomGenPort();
	    randGenPort.generate(boundary,count,fileURL);
	}
	catch(randgen.GeneratorException ge){
	    System.err.println(ge.getMessage());
	    System.exit(1);
	}
	catch(RemoteException re){
	    System.err.println("Remote error: "+re.getMessage());
	    System.exit(1);
	}
    }

    /** Generates a sequence of real numbers which is
     * stored in FileStore
     * @param start the start value for the sequence
     * @param step the spacing between values
     * @param limit the maximum value in the sequence
     * @param seqName the name of the file in which to store the data
     * @param seqDir the sub-directory in FileStore where the
     * file will be put.
     */
    public static void seqgen(double start, double step,
			    double limit, String seqName,
			    String seqDir, String store){
	try{
	    //file and directory for 1D data
	    seqgen.FileName1D fileSeq = new seqgen.FileName1D(seqDir,seqName);

	    //Wrap service address and filename info into 
	    //a URLFileName1D object.
	    seqgen.URLFileName1D seqURL = 
		new seqgen.URLFileName1D(fileSeq,store);

	    //generate the sequences and cross-product which are automatically
	    //stored using FileStore
	    SeqGen_Impl seqService = new SeqGen_Impl();
	    Sequence seqPort = seqService.getSequencePort();
	    seqPort.generate(start,step,limit,seqURL);

	}
	catch(seqgen.GeneratorException ge){
	    System.err.println(ge.getMessage());
	    System.exit(1);
	}
	catch(RemoteException re){
	    System.err.println("Remote error: "+re.getMessage());
	    System.exit(1);
	}
    }
    
    /** Generates the cross-product of two 1D sequences of
     * real numbers. 
     * @param seq1Name the filename of the first sequence
     * @param seq1Dir the subdirectory in FileStore where the
     * first sequence is stored
     * @param seq2Name the filename of the second sequence
     * @param seq2Dir the subdirectory in FileStore where the
     * second sequence is stored
     * @param xprodName the filename for the cross-product data
     * @param xprodDir the subdirectory in FileStore in which to store
     * the data
     */
    public static void xprodgen(String seq1Name, String seq1Dir,
				String seq2Name, String seq2Dir,
				String xprodName, String xprodDir,
				String store){
	try{
	    //filenames and directory for sequence data
	    xprodgen.FileName1D fileSeq1 = 
		new xprodgen.FileName1D(seq1Dir,seq1Name);
	    xprodgen.FileName1D fileSeq2 = 
		new xprodgen.FileName1D(seq2Dir,seq2Name);
	    xprodgen.URLFileName1D seq1URL = 
		new xprodgen.URLFileName1D(fileSeq1,store);
	    xprodgen.URLFileName1D seq2URL = 
		new xprodgen.URLFileName1D(fileSeq2,store);


	    //filenames and directory for cross-product 2D data 
	    xprodgen.FileName2D fileXprod = 
		new xprodgen.FileName2D(xprodDir,xprodName);
	    xprodgen.URLFileName2D xprodURL = 
		new xprodgen.URLFileName2D(fileXprod,store);

	    XProdGen_Impl xprodService = new XProdGen_Impl();
	    XProduct xprodPort = xprodService.getXProductPort();
	    xprodPort.generate(seq1URL,seq2URL,xprodURL);
	}
	catch(xprodgen.GeneratorException ge){
	    System.err.println(ge.getMessage());
	    System.exit(1);
	}
	catch(RemoteException re){
	    System.err.println("Remote error: "+re.getMessage());
	    System.exit(1);
	}
    }

    /** Samples a predefined surface generating 3D data
     * (x,y,h) from 2D (x,y) input data
     * @param inputName the 2D input file
     * @param inputDir the sub-directory of FileStore where
     * the 2D data is stored
     * @param surfName the filename of the 3D output data
     * @param surfDir the sub-directory of FileStore to store the
     * 3D data in.
    */
    public static void probe(String inputName, String inputDir,
			     String surfName, String surfDir,
			     String store, String surfaceURL){
	try{
	    //filename and directory for the input data

	    //filename and directory for the sampled surface

	    //create Surface service instance

	    //get Probe port

	    //set Surface service endpoint address

	    //sample the surface
	}
	catch(    ){
	}
	catch(    ){
	}
    }

    /** Visualises the 3D sampled surface using gnuplot to generate
     * postscript which is outputted to a file
     * @param surfName the filename for the 3D data
     * @param surfDir the sub-directory in FileStore where it is
     * stored
     * @param epsName the filename for the postscript file which
     * will be produced in the directory the program is run in.
     */
    public static void render(String surfName, String surfDir,
			      String store, String epsName){
	try{
	    //filename and directory for the 3-D data
	    visualiser.FileName3D f = 
		new visualiser.FileName3D(surfDir,surfName);
	    visualiser.URLFileName3D fileIn = 
		new visualiser.URLFileName3D(f,store);

	    //produce the postscript using render and output
	    //to a file
	    Visualiser_Impl service = new Visualiser_Impl();
	    Render port = service.getRenderPort();
	    String out = port.render(fileIn);
	    outputToFile(out,epsName);
	}
	catch(RenderException re){
	    System.err.println(re.getMessage());
	    System.exit(1);
	}
	catch(RemoteException re){
	    System.err.println("Remote error: "+re.getMessage());
	}
    }

    /** Converts the 3D sampled surface into the format required for
     * inputting to gnuplot
     * @param surfName the filename for the 3D data
     * @param surfDir the sub-directory in FileStore where it is
     * stored
     * @param gnuName the filename for the gnu formatted file which
     * will be produced in the directory the program is run in.
     */
    public static void reformat(String surfName, String surfDir,
				String store, String gnuName){
	try{
	    //filename and directory for the 3-D data
	    converter.FileName3D f = 
		new converter.FileName3D(surfDir,surfName);
	    converter.URLFileName3D fileIn = 
		new converter.URLFileName3D(f,store);

	    //convert the data to gnu format and output to file
	    Converter_Impl service = new Converter_Impl();
	    Convert port = service.getConvertPort();
	    String out = port.reformat(fileIn);
	    outputToFile(out,gnuName);
	}
	catch(ReformatException re){
	    System.err.println(re.getMessage());
	    System.exit(1);
	}
	catch(RemoteException re){
	    System.err.println("Remote error: "+re.getMessage());
	}
    }


    /** Writes data into a file in the local directory
     * @param out the data to be written
     * @param name the filename
     */
    private static void outputToFile(String out, String name){
	try{
	    File outFile = new File(name);
	    if(!outFile.createNewFile()){
		System.err.println("Cannot create file "+name+
				   " it might already exist");
		System.exit(1);
	    }
	    PrintWriter pw = new PrintWriter(new FileWriter(outFile));
	    pw.println(out);
	    pw.close();
	}
	catch(IOException ioe){
	    System.err.println("Error writing to file "+name);
	    System.exit(1);
	}

    }
}
