function SAM_Test_MATLAB

	function [result] = ssccall(action, arg0, arg1, arg2 )
    [pathstr, fn, fext] = fileparts(mfilename('fullpath'));
        ssclibpath = './' ; 
        ssclib = 'ssc'   ;
        
    if ~libisloaded(ssclib)
        oldFolder = cd(pathstr);
        
 
      loadlibrary(strcat(ssclibpath,ssclib),strcat(ssclibpath,'sscapi.h'));     
        cd(oldFolder);
    end
    if strcmp(action,'load')
        if ~libisloaded(ssclib)
            oldFolder = cd(pathstr);
            loadlibrary(strcat(ssclibpath,ssclib),strcat(ssclibpath,'../sscapi.h'));
            cd(oldFolder);
        end
    elseif strcmp(action,'unload')
        if libisloaded(ssclib)
            unloadlibrary(ssclib)    
        end
    elseif strcmp(action,'version')
        result = calllib(ssclib,'ssc_version');
    elseif strcmp(action,'build_info')
        result = calllib(ssclib, 'ssc_build_info');
    elseif strcmp(action,'data_create')
        result = calllib(ssclib, 'ssc_data_create');
        if ( isnullpointer(result) )
            result = 0;
        end
    elseif strcmp(action,'data_free')
        result = calllib(ssclib, 'ssc_data_free', arg0);
    elseif strcmp(action,'data_unassign')
        result = calllib(ssclib, 'ssc_data_unassign', arg0, arg1);
    elseif strcmp(action,'data_query')
        result = calllib(ssclib, 'ssc_data_query', arg0, arg1 );
    elseif strcmp(action,'data_first')
        result = calllib(ssclib, 'ssc_data_first', arg0 );
    elseif strcmp(action,'data_next')
        result = calllib(ssclib, 'ssc_data_next', arg0 );
    elseif strcmp(action,'data_set_string')
        result = calllib(ssclib, 'ssc_data_set_string', arg0, arg1, arg2 );
    elseif strcmp(action,'data_set_number')
        result = calllib(ssclib, 'ssc_data_set_number', arg0, arg1, arg2 );
    elseif strcmp(action,'data_set_array')
        len = length(arg2);
        arr = libpointer( 'doublePtr', arg2 );
        result = calllib(ssclib,'ssc_data_set_array',arg0,arg1,arr,len);
    elseif strcmp(action,'data_set_matrix')
        [nr nc] = size(arg2);
        mat = zeros(nr*nc, 1);
        ii = 1;
        for r=1:nr,
            for c=1:nc,
                mat(ii) = arg2(r,c);
                ii=ii+1;
            end
        end
        arr = libpointer( 'doublePtr', mat );
        result = calllib(ssclib,'ssc_data_set_matrix',arg0,arg1,arr,nr,nc);
    elseif strcmp(action,'data_set_table')
        result = calllib(ssclib,'ssc_data_set_table',arg0,arg1,arg2);
    elseif strcmp(action,'data_get_string')
        result = calllib(ssclib,'ssc_data_get_string',arg0,arg1);
    elseif strcmp(action,'data_get_number')
         p = libpointer('doublePtr',0);
         calllib(ssclib,'ssc_data_get_number', arg0,arg1,p);
         result = get(p,'Value');
    elseif strcmp(action,'data_get_array')
        p_count = libpointer('int32Ptr',0);   
        [xobj] = calllib(ssclib,'ssc_data_get_array',arg0,arg1,p_count);
        setdatatype(xobj,'int64Ptr',p_count.Value,1);
        len = p_count.Value;
        result = zeros( len, 1 );
        for i=1:len,
            pidx = xobj+(i-1);
            setdatatype(pidx,'doublePtr',1,1);
            result(i) = pidx.Value;
        end
    elseif strcmp(action,'data_get_matrix')
        p_rows = libpointer('int32Ptr',0);
        p_cols = libpointer('int32Ptr',0);
        [xobj] = calllib(ssclib,'ssc_data_get_matrix',arg0,arg1,p_rows,p_cols);
        setdatatype(xobj,'int64Ptr',p_rows.Value*p_cols.Value,1);
        nrows = p_rows.Value;
        ncols = p_cols.Value;
        if ( nrows*ncols > 0 )
            result = zeros( nrows, ncols );
            ii=1;
            for r=1:nrows,
                for c=1:ncols,
                    pidx = xobj+(ii-1);
                    setdatatype(pidx,'doublePtr',1,1);
                    result(r,c) = pidx.Value;
                    ii=ii+1;
                end
            end
        end
    elseif strcmp(action,'data_get_table')
        result = calllib(ssclib,'ssc_data_get_table',arg0,arg1);
    elseif strcmp(action,'module_entry')
        result = calllib(ssclib,'ssc_module_entry',arg0);
        if isnullpointer( result ),
            result = 0;
        end
    elseif strcmp(action,'entry_name')
        result = calllib(ssclib,'ssc_entry_name',arg0);
    elseif strcmp(action,'entry_description')
        result = calllib(ssclib,'ssc_entry_description',arg0);
    elseif strcmp(action,'entry_version')
        result = calllib(ssclib,'ssc_entry_version',arg0);
    elseif strcmp(action,'module_var_info')
        result = calllib(ssclib,'ssc_module_var_info',arg0,arg1);
        if isnullpointer( result ),
            result = 0;
        end
    elseif strcmp(action,'info_var_type')
        ty = calllib(ssclib,'ssc_info_var_type',arg0);
        if (ty == 1)
            result = 'input';
        elseif ( ty==2 )
            result = 'output';
        else
            result = 'inout';
        end
    elseif strcmp(action,'info_data_type')
        dt = calllib(ssclib,'ssc_info_data_type',arg0);
        if (dt == 1)
            result = 'string';
        elseif (dt == 2)
            result = 'number';
        elseif (dt == 3)
            result = 'array';
        elseif (dt == 4)
            result = 'matrix';
        elseif (dt == 5)
            result = 'table';
        else
            result = 'invalid';
        end
    elseif strcmp(action,'info_name')
        result = calllib(ssclib,'ssc_info_name',arg0);
    elseif strcmp(action,'info_label')
        result = calllib(ssclib,'ssc_info_label',arg0);
    elseif strcmp(action,'info_units')
        result = calllib(ssclib,'ssc_info_units',arg0);
    elseif strcmp(action,'info_meta')
        result = calllib(ssclib,'ssc_info_meta',arg0);
    elseif strcmp(action,'info_group')
        result = calllib(ssclib,'ssc_info_group',arg0);
    elseif strcmp(action,'info_required')
        result = calllib(ssclib,'ssc_info_required',arg0);
    elseif strcmp(action,'info_constraints')
        result = calllib(ssclib,'ssc_info_constraints',arg0);
    elseif strcmp(action,'info_uihint')
        result = calllib(ssclib,'ssc_info_uihint',arg0);
    elseif strcmp(action,'exec_simple')
        result = calllib(ssclib,'ssc_module_exec_simple',arg0,arg1);
    elseif strcmp(action,'exec_simple_nothread')
        result = calllib(ssclib,'ssc_module_exec_simple_nothread',arg0,arg1);
    elseif strcmp(action,'module_create')
        result = calllib(ssclib,'ssc_module_create',arg0);
        if ( isnullpointer(result) )
            result = 0;
        end
    elseif strcmp(action,'module_free')
        result = calllib(ssclib,'ssc_module_free',arg0);
    elseif strcmp(action,'module_exec_set_print')
        calllib(ssclib,'ssc_module_exec_set_print',arg0);
        result = 0;
    elseif strcmp(action,'module_exec')
        result = calllib(ssclib,'ssc_module_exec',arg0,arg1);
    elseif strcmp(action,'module_log')
        p_type = libpointer('int32Ptr',1);
        p_time = libpointer('singlePtr',1);
        result = calllib(ssclib,'ssc_module_log', arg0, arg1, p_type, p_time);
    elseif strcmp(action,'module_log_detailed')
        p_type = libpointer('int32Ptr',1);
        p_time = libpointer('singlePtr',1);
        text = calllib(ssclib,'ssc_module_log', arg0, arg1, p_type, p_time);
        typetext = 'notice';
        if (p_type.Value == 2)
            typetext = 'warning';
        elseif (p_type.Value == 3)
            typetext = 'error';
        end
        if ( strcmp(text,'') )
            result = 0;
        else
            result = {text , typetext , p_time.Value};
        end
    else
        disp( sprintf('ssccall: invalid action %s', action) );        
        result = 0;
    end
	end
	function bb = isnullpointer(p)
    bb = false;
    try
        setdatatype(p, 'voidPtr', 1, 1);
        deref = get(p);
    catch
        e = lasterror();
        if strcmp(e.identifier, 'MATLAB:libpointer:ValueNotDefined')
            bb = true;
        end
    end
	end
	clear
	ssccall('load');
	disp('Current folder = /Users/markkovacs/Desktop/SAM_TEST_MATLAB');
	disp(sprintf('SSC Version = %d', ssccall('version')));
	disp(sprintf('SSC Build Information = %s', ssccall('build_info')));
	ssccall('module_exec_set_print',0);
	data = ssccall('data_create');
	ssccall('data_set_string', data, 'solar_resource_file', '/Applications/SAM.app/Contents/solar_resource/phoenix_az_33.450495_-111.983688_psmv3_60_tmy.csv');
	ssccall('data_set_number', data, 'system_capacity', 4);
	ssccall('data_set_number', data, 'module_type', 0);
	ssccall('data_set_number', data, 'dc_ac_ratio', 1.2);
	ssccall('data_set_number', data, 'array_type', 0);
	ssccall('data_set_number', data, 'tilt', 20);
	ssccall('data_set_number', data, 'azimuth', 180);
	ssccall('data_set_number', data, 'gcr', 0.40000000000000002);
	ssccall('data_set_number', data, 'losses', 14.075660705566406);
	ssccall('data_set_number', data, 'en_snowloss', 0);
	ssccall('data_set_number', data, 'inv_eff', 96);
	ssccall('data_set_number', data, 'batt_simple_enable', 0);
	ssccall('data_set_number', data, 'adjust:constant', 0);
	module = ssccall('module_create', 'pvwattsv7'); 
	ok = ssccall('module_exec', module, data);
	if ~ok,
		disp('pvwattsv7 errors:'); 
		ii=0;
		while 1,
			err = ssccall('module_log', module, ii);
			if strcmp(err,''),
			      break;
			end
			disp( err );
			ii=ii+1;
		end
		return 
	end
	ssccall('module_free', module);
	ssccall('data_set_number', data, 'enable_interconnection_limit', 0);
	ssccall('data_set_number', data, 'grid_interconnection_limit_kwac', 100000);
	grid_curtailment = csvread( '/Users/markkovacs/Desktop/SAM_TEST_MATLAB/grid_curtailment.csv');
	ssccall( 'data_set_array', data, 'grid_curtailment', grid_curtailment );
	module = ssccall('module_create', 'grid'); 
	ok = ssccall('module_exec', module, data);
	if ~ok,
		disp('grid errors:'); 
		ii=0;
		while 1,
			err = ssccall('module_log', module, ii);
			if strcmp(err,''),
			      break;
			end
			disp( err );
			ii=ii+1;
		end
		return 
	end
	ssccall('module_free', module);
	annual_energy = ssccall('data_get_number', data, 'annual_energy' );
	disp(sprintf('%s = %g', 'Annual energy (year 1)', annual_energy));
	capacity_factor = ssccall('data_get_number', data, 'capacity_factor' );
	disp(sprintf('%s = %g', 'Capacity factor (year 1)', capacity_factor));
	kwh_per_kw = ssccall('data_get_number', data, 'kwh_per_kw' );
	disp(sprintf('%s = %g', 'Energy yield (year 1)', kwh_per_kw));
	ssccall('data_free', data);
	ssccall('unload');
end