classdef class_REVS_VM_result
	
	
	properties
		% Required Parameters
		drive_cycle_name;
		drive_cycle_phase_names;
				
		% Base Properties - set by model
		phase_time_secs;						% Phase durations [seconds]
		total_time_secs;						% Total test duration [seconds]
				
		phase_stopped_time_secs;				% Time stopped during phase [seconds]
		total_stopped_time_secs;				% Time stopped during test [seconds]
		
		phase_driver_error_time_secs;			% Phase 2 mph driver error durations [seconds]
		total_driver_error_time_secs;			% Total 2 mph driver error duration [seconds]
		
		phase_drive_cycle_distance_m;
		total_drive_cycle_distance_m;
		
		phase_distance_m;
		total_distance_m;
		
		phase_num_upshifts;
		total_num_upshifts;
		
		phase_num_downshifts;
		total_num_downshifts;
		
		phase_gear_time_secs;
		total_gear_time_secs;
		
        drive_quality;                          % structure of SAEJ2951 drive quality metrics, from run_cycle_postproc
	end
	
	properties ( Dependent= true , Transient = true)
		
		phase_distance_mi;
		total_distance_mi;
		
		phase_avg_speed_mps;
		total_avg_speed_mps;
		
		phase_avg_speed_mph;
		total_avg_speed_mph;
				
		phase_num_shifts;
		total_num_shifts;
				
		phase_shifts_per_mi;
		total_shifts_per_mi;
		
	end
	
	
	methods
		
		
		
		
		%% Constructor
		function obj = class_REVS_CVM_result( drive_cycle)
			
			
			if isfield( drive_cycle,'name')
				obj.drive_cycle_name = drive_cycle.name;
			end
			
			if isfield( drive_cycle,'phase_name')
				obj.drive_cycle_phase_names = drive_cycle.phase_name;
			end
						
		end
		
		%% Print Result - to screen or file
% 		function print(obj, fid )
% 			
% 			if nargin < 2 || isempty(fid)
% 				fid = 1;
% 			end
% 			
% 			% ... display percent time trace missed by 2mph (%)
% 			fprintf(fid,'\n-- Summary data for %s drive cycle --\n\n',    obj.drive_cycle_name);
% 			fprintf(fid,'   Percent Time Missed by 2mph   = %6.2f %%\n',  obj.total_driver_error_time_secs ./ obj.total_time_secs);
% 			
% 			
% 			if length(obj.phase_time_secs) ~= 1 ||  obj.phase_time_secs ~= obj.total_time_secs
% 				for p = 1:length(obj.phase_time_secs)
% 					
% 					if ~isempty( obj.drive_cycle_phase_names ) && p <= length(obj.drive_cycle_phase_names )
% 						phase_name = obj.drive_cycle_phase_names{p};
% 					else
% 						phase_name = '';
% 					end
% 					
% 					fprintf(fid,'   Phase %2d: %s %s\n',p, phase_name, repmat('-', 1,25-length(phase_name)));
% 					fprintf(fid,'   Distance                    = %6.3f mi\n',			obj.phase_distance_mi(p));
% 					fprintf(fid,'   Fuel Consumption            = %6.4f grams\n',		obj.phase_fuel_consumed_g(p));
% 					fprintf(fid,'   Fuel Consumption            = %6.4f gallons\n',		obj.phase_fuel_consumed_gallons(p));
% 					fprintf(fid,'   Fuel Economy (Volumetric)   = %6.3f mpg\n',			obj.phase_FE_vol_mpg(p));
% 					fprintf(fid,'   Fuel Economy (CFR)          = %6.3f mpg\n',			obj.phase_FE_CFR_mpg(p));
% 					fprintf(fid,'   Fuel Consumption            = %6.3f g/mile\n',		obj.phase_fuel_consumed_g(p) / obj.phase_distance_mi(p));
% 					fprintf(fid,'   CO2 Emission                = %6.2f g/mile\n',		obj.phase_gCO2pmi(p));
% 					fprintf(fid,'\n');
% 					
% 				end
% 			end
% 			
% 			% Print Total Results
% 			fprintf(fid,'   Total ---------------------------------------\n');
% 			fprintf(fid,'   >> %s\n', obj.drive_cycle_name);
% 			fprintf(fid,'   Distance                    = %6.3f mi\n',		obj.total_distance_mi);
% 			fprintf(fid,'   Fuel Consumption            = %6.4f grams\n',	obj.total_fuel_consumed_g);
% 			fprintf(fid,'   Fuel Consumption            = %6.4f gallons\n', obj.total_fuel_consumed_gallons);
% 			fprintf(fid,'   Fuel Economy (Volumetric)   = %6.3f mpg\n',		obj.total_FE_vol_mpg);
% 			fprintf(fid,'   Fuel Economy (CFR)          = %6.3f mpg\n',		obj.total_FE_CFR_mpg);
% 			fprintf(fid,'   Fuel Consumption            = %6.3f g/mile\n', obj.total_fuel_consumed_g / obj.total_distance_mi);
% 			fprintf(fid,'   CO2 Emission                = %6.2f g/mile\n', obj.total_gCO2pmi);
% 			
% 			
% 		end
		
		
		
		%% Distance
		function val = get.phase_distance_mi(obj)
			val = obj.phase_distance_m .* convert.mtr2mi;
		end
		
		function val = get.total_distance_mi(obj)
			val = obj.total_distance_m .* convert.mtr2mi;
		end
		

		
		%% Average Speed - when moving
		function val = get.phase_avg_speed_mps(obj)
			val = obj.phase_distance_m ./max(0, obj.phase_time_secs - obj.phase_stopped_time_secs);
		end
		
		function val = get.total_avg_speed_mps(obj)
			val = obj.total_distance_m ./max(0, obj.total_time_secs - obj.total_stopped_time_secs);
			
		end
		
		function val = get.phase_avg_speed_mph(obj)
			val = obj.phase_avg_speed_mps * convert.mps2mph;
		end
		
		function val = get.total_avg_speed_mph(obj)
			val = obj.total_avg_speed_mps * convert.mps2mph;
		end
			
		
		%% Shifts
		function val = get.phase_num_shifts(obj)
			val = obj.phase_num_upshifts + obj.phase_num_downshifts;
		end
		
		function val = get.total_num_shifts(obj)
			val = obj.total_num_upshifts + obj.total_num_downshifts;
		end
		
		function val = get.phase_shifts_per_mi(obj)
			val = obj.phase_num_shifts ./ obj.phase_distance_mi;
		end
		
		function val = get.total_shifts_per_mi(obj)
			val = obj.total_num_shifts ./ obj.total_distance_mi;
		end
		
		
		function val = cycle_results(obj)
			
			cycles = unique(regexprep(obj.drive_cycle_phase_names,'_\d+$',''));
            class_meta = metaclass(obj);
            prop_meta = class_meta.PropertyList;
            
			for c = 1:length(cycles)
				
                cyc_phases = strncmpi( cycles{c}, obj.drive_cycle_phase_names, length(obj.drive_cycle_phase_names));
				
                cyc_result = obj;
                cyc_result.drive_cycle_name = cycles{c};

                for p = 1:length(prop_meta)
                   prop_name = prop_meta(p).Name;
                    
                    if ~prop_meta(p).Dependent && ~prop_meta(p).Transient && ~isscalar(obj.(prop_name)) && size( obj.(prop_name),2) == size(cyc_phases,2)
                        cyc_result.(prop_name) = obj.(prop_name)(:,cyc_phases);
                    end
                    
                end	
				
				val.(cycles{c}) = cyc_result;
				
				
			end
			
			
		end	
		
	end
	
end

