/*
 * Delivered to the U.S. Government in Accordance with Contract FA8650-10-C-7080.
 *
 * EXPORT CONTROLLED
 * ECCN#   EAR99  
 * Warning:  This document contains technical data which is controlled under the
 * Bureau of Industry & Security's Export Administration Regulations and may not be
 * exported or re-exported without authorization by the Bureau of Industry & Security.
 * Diversion contrary to US law is prohibited.
 *
 * (c) 2011 United Technologies Corp.
 * Developed with the sponsorship of the Defense Advanced Research Projects Agency (DARPA).
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this data,
 * including any software or models in source or binary form, as well as any drawings, 
 * specifications, and documentation (collectively "the Data"), to deal in the Data without 
 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Data, and to permit persons to whom the Data
 * is furnished to do so, subject to the following conditions:
 *  
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Data.
 *  
 * THE DATA IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS, SPONSORS, DEVELOPERS, CONTRIBUTORS, OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE DATA OR THE
 * USE OR OTHER DEALINGS IN THE DATA.
 */
package meta.matlab.runner;
import matlabcontrol.MatlabConnectionException;
import matlabcontrol.MatlabInvocationException;
import matlabcontrol.MatlabProxy;
import matlabcontrol.MatlabProxyFactory;
import matlabcontrol.MatlabProxyFactoryOptions;
import meta.util.Log;
import java.util.Properties;
/**
 * Encapsulate MATLAB 
 *
 */
public class MATLABprocessImpl implements MATLABprocess {
	private static String MATLAB_LOCATION;
	private MatlabProxy proxy;
	public MATLABprocessImpl(Properties properties) throws MATLABException
	{
		MATLAB_LOCATION = properties.getProperty("matlab.location");
		String msg = String.format("MATLAB location %s", MATLAB_LOCATION);
		Log.info(msg);
		MatlabProxyFactoryOptions options = new MatlabProxyFactoryOptions.Builder()
        .setHidden(false)
        .setProxyTimeout(360000L)
        .setMatlabLocation(MATLAB_LOCATION)
        .build();
		   //Create a factory 
		
	    MatlabProxyFactory factory = new MatlabProxyFactory(options);
	      //Get a proxy, launching MATLAB in the process
	      try {
			proxy = factory.getProxy();
		} catch (MatlabConnectionException e) {
			Log.err(e.toString());
			throw new MATLABException(e.toString());
		}  
	
	}
	/* (non-Javadoc)
	 * @see meta.matlab.runner.MATLABprocess#execute(java.lang.String)
	 */
	public void execute(String mfile) throws MATLABException {
		try {
			proxy.eval(mfile);
		} catch (MatlabInvocationException e) {
			handleException(e);
		}

	}

	/* (non-Javadoc)
	 * @see meta.matlab.runner.MATLABprocess#getDouble(java.lang.String)
	 */
	public double getDouble(String name) throws MATLABException {
		double result = Double.NaN;
		try {
			result = ((double[]) proxy.getVariable(name))[0];
		} catch (MatlabInvocationException e) {
			handleException(e);
		}
		return result;
	}

	/* (non-Javadoc)
	 * @see meta.matlab.runner.MATLABprocess#getDoubleArray(java.lang.String)
	 */
	public double[] getDoubleArray(String name) throws MATLABException {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see meta.matlab.runner.MATLABprocess#reset()
	 */
	public void reset() throws MATLABException {
		 try {
			proxy.eval("clear all");
		} catch (MatlabInvocationException e) {
			handleException(e);
		}

	}

	/* (non-Javadoc)
	 * @see meta.matlab.runner.MATLABprocess#setDouble(java.lang.String, double)
	 */
	public void setDouble(String name, double value) throws MATLABException {
		try {
			proxy.setVariable(name, value);
		} catch (MatlabInvocationException e) {
			 handleException(e);
		} 

	}

	/* (non-Javadoc)
	 * @see meta.matlab.runner.MATLABprocess#setDouble(java.lang.String, double[])
	 */
	public void setDouble(String name, double[] values) throws MATLABException {
		try {
			proxy.setVariable(name, values);
		} catch (MatlabInvocationException e) {
			// TODO Auto-generated catch block
			handleException(e);
		}

	}

	/* (non-Javadoc)
	 * @see meta.matlab.runner.MATLABprocess#setWorkingDirectory(java.lang.String)
	 */
	public void setWorkingDirectory(String workingDirectory) throws MATLABException {
		String cmd = String.format("cd %s", workingDirectory);
		try {
			proxy.eval(cmd);
		} catch (MatlabInvocationException e) {
	      handleException(e);		
		}

	}

	/* (non-Javadoc)
	 * @see meta.matlab.runner.MATLABprocess#shutdown()
	 */
	public void shutdown() throws MATLABException {
		try {
			proxy.exit();
		} catch (MatlabInvocationException e) {
			 handleException(e);
		}
	    proxy.disconnect();

	}
    private void handleException(Exception e) throws MATLABException
    {
    	String msg = e.getMessage(); 
		Log.err(msg);
		throw new MATLABException(msg);
    }
}
