classdef class_REVS_fuel
	%REVS_fuel
	%   class for storing fuel properties
	% use class_REVS_fuel.show_table to preview REVS_fuel_table.csv in Matlab
	% use class_REVS_fuel.edit_table to allow fuel table editing
    
	properties
		id = ''						% Descriptor
		description = '';			% Generic Description
		density_kgpL_15C;			% Fuel density at 15 degrees Celsius
		energy_density_MJpkg;		% Fuel energy density
		carbon_weight_fraction;		% Carbon proportion of fuel mass
		anti_knock_index;			% AKI Octane - (RON + MON) / 2
		research_octane_number;		% Research octane number (RON)
		motor_octane_number;		% Motor octane number (MON)
		cetane_number;				% Cetane number ( diesel only )
		alcohol_pct_vol;			% Percentage Ethanol or other alcohols by volume
		gCO2pgal;					% Grams of CO2 (or Co2 equivalent) per gallon of fuel - computed from other parameters if not specified
	end
	
	properties (Dependent = true, Transient = true)
		energy_density_BTUplbm;		% Fuel energy density in imperial units
		specific_gravity;
	end
	
	methods
		
		function obj = class_REVS_fuel( id )
			
			if nargin >= 1
				
				
				fid = fopen('REVS_fuel_table.csv');
				fuel_table_header = fgetl(fid);
				fuel_table = textscan(fid, '%s%s%f%f%f%f%f%f%f%f%f%s%*[^\n]',Inf, 'Delimiter',',','CollectOutput',true,'Whitespace','\b\t"');
				
				fuel_name = fuel_table{1}(:,1);
				fuel_description = fuel_table{1}(:,2);
				fuel_prop = fuel_table{2};
				
				fclose(fid);
				
				
				f = 1;
				while f <= size(fuel_prop,1) && ~strcmpi( id, fuel_name{f} )
					f = f + 1;
				end
				
				if f > size(fuel_prop,1)
					error('Fuel ''%s'' not found in REVS fuel table.', id);
				else
					obj.id = fuel_table{1}{f,1};
					obj.description = fuel_table{1}{f,2};
					obj.density_kgpL_15C(~isnan( fuel_prop(f,1) ))		= fuel_prop(f,1);
					obj.energy_density_MJpkg(~isnan( fuel_prop(f,2)))	= fuel_prop(f,2);
					obj.carbon_weight_fraction(~isnan( fuel_prop(f,3)))	= fuel_prop(f,3);
					obj.anti_knock_index(~isnan( fuel_prop(f,4)))		= fuel_prop(f,4);
					obj.research_octane_number(~isnan( fuel_prop(f,5)))	= fuel_prop(f,5);
					obj.motor_octane_number(~isnan( fuel_prop(f,6)))	= fuel_prop(f,6);
					obj.cetane_number(~isnan( fuel_prop(f,7)))			= fuel_prop(f,7);
					obj.alcohol_pct_vol(~isnan( fuel_prop(f,8)))		= fuel_prop(f,8);
					obj.gCO2pgal(~isnan( fuel_prop(f,9 )))				= fuel_prop(f,9);
				end
				
			end
			
		end
		
		
		function val = get.energy_density_BTUplbm( obj)
			val = obj.energy_density_MJpkg * convert.MJpkg2BTUplbm;
		end
		
		function obj = set.energy_density_BTUplbm(obj,val)
			obj.energy_density_MJpkg = val * convert.BTUplbm2MJpkg;
		end
		
		function val = get.specific_gravity( obj)
			val = obj.density_kgpL_15C * convert.density_kgpL2specific_gravity_60F;
		end
		
		function obj = set.specific_gravity( obj,val)
			obj.density_kgpL_15C = val * convert.specific_gravity2density_kgpL_60F;
		end
		
		function val = get.gCO2pgal(obj)
			
			if isempty( obj.gCO2pgal )
				val = obj.density_kgpL_15C * obj.carbon_weight_fraction * (44.0095/12.0107) * 1000 / convert.lit2gal;
			else
				val =  obj.gCO2pgal;
			end
			
		end
		
	end
	
	
	methods (Static = true)
		
		function show_table
			
			fid = fopen('REVS_fuel_table.csv');
			fuel_table_header = fgetl(fid);
			fuel_table = textscan(fid, '%s%s%f%f%f%f%f%f%f%f%f%s%*[^\n]',Inf, 'Delimiter',',','CollectOutput',true,'Whitespace','\b\t"');
			fclose(fid);
			
			
			fuel_name = fuel_table{1}(:,1);
			fuel_description = fuel_table{1}(:,2);
			fuel_notes = fuel_table{3}(:,1);
			
			fuel_prop = fuel_table{2};
			fuel_prop_str = cellfun(@num2str,num2cell(fuel_prop),'UniformOUtput',false);
			fuel_prop_str = strrep(fuel_prop_str,'NaN','   ');
			
			num_cols = size(fuel_prop,2)+3;
			
			fuel_print = [fuel_name, fuel_description,fuel_prop_str, fuel_notes ];
			fuel_print = [{'Name','Description','Density','Energy Density','CWF','AKI','RON','MON','CN','Alcohol','CO2','Notes'};...
				{'','','kg/L','MJ/kg','0-1','#','#','#','#','%','g/gal',''};...
				fuel_print];
			
			format_str = '| ';
			for c = 1:num_cols
				format_str = sprintf('%s%%%ds | ',format_str, max(cellfun(@length,fuel_print(:,c))));
			end
			format_str = [format_str,'\n'];
			
			
			fuel_print = fuel_print';
			fprintf(format_str, fuel_print{:});			
			
		end
		
		
		function edit_table
		
% 			edit REVS_fuel_table.csv
			fid = fopen('REVS_fuel_table.csv');
			fuel_table_header = fgetl(fid);
			fuel_table = textscan(fid, '%s%s%s%s%s%s%s%s%s%s%s%s%*[^\n]',Inf, 'Delimiter',',','CollectOutput',false,'Whitespace','\b\t"');
			fclose(fid);

 			d = dialog('Units','Normalized','WindowStyle','Normal');
			t = uitable('Parent', d,'Data',[fuel_table{:}],'Units','Normalized','Position',[0.0, 0.0, 1.0, 0.95],...
			'ColumnName',{'Name','Description','Density','Energy Density','CWF','AKI','RON','MON','CN','Alcohol','CO2','Notes'},...
			'ColumnWidth',{150,180, 70,70,70,70,70,70,70,70,70,70,250},'ColumnEditable',true);
            uicontrol('Parent',d,'String','Save','Units','Normalized','Position',[0,0.95,0.1,0.05],'Callback',@save_table);
            uicontrol('Parent',d,'String','Add Row','Units','Normalized','Position',[0.1,0.95,0.1,0.05],'Callback',@add_row);
            
            function save_table(~,~)
                fuel_table_new = get(t,'Data');
                writetable(cell2table(fuel_table_new,'VariableNames',strsplit(fuel_table_header,',')),'REVS_fuel_table.csv');
            end
            
            function add_row(~,~)
                fuel_table_new = get(t,'Data');
                newRow = cell(1, size(fuel_table_new,2));
                newRow(:)={''}; %Quotes ensure these are chars, not doubles
                fuel_table_new = [fuel_table_new;newRow]; 
                set(t,'Data',fuel_table_new);
            end
			
			
		end
		
		function tf = check_id( id)
			

				fid = fopen('REVS_fuel_table.csv');
				fuel_table_header = fgetl(fid);
				fuel_table = textscan(fid, '%s%s%f%f%f%f%f%f%f%f%f%s%*[^\n]',Inf, 'Delimiter',',','CollectOutput',true,'Whitespace','\b\t"');
				
				fuel_name = fuel_table{1}(:,1);
							
				fclose(fid);
				
				
				f = 1;
				while f <= length(fuel_name) && ~strcmpi( id, fuel_name{f} )
					f = f + 1;
				end
				
				tf = f <= length(fuel_name);
				
	
			
		end
		
	end
	
end

