%FLAIM class definition
%
%   Usage:
%      flaim=flaim();

classdef flaim
	properties (SetAccess=public) 
		targets            = ''
		tracks             = ''
		flightreqs         = struct()
		criterion          = NaN
		gridsatequator     = 200000
		usevalueordering   = true
		split_antimeridian = true
		solution           = ''
		quality            = 0
		path_optimize      = false
		opt_ndir           = 1
		opt_dist           = 25
		opt_niter          = 30000
	end
	methods
  	 	function createxml(obj,fid) % {{{
            fprintf(fid, '<!-- flaim -->\n');            
                    
            % Input
            fprintf(fid,'%s\n%s\n%s\n','<frame key="1" label="Input:">','<section name="flaim" />');                    
            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="targets" type="',class(obj.targets),'" default="',convert2str(obj.targets),'">','     <section name="flaim" />','     <help> name of kml output targets file </help>','  </parameter>');
            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="tracks" type="',class(obj.tracks),'" default="',convert2str(obj.tracks),'">','     <section name="flaim" />','     <help> name of kml input tracks file </help>','  </parameter>');
            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="flightreqs" type="',class(obj.flightreqs),'" default="',convert2str(obj.flightreqs),'">','     <section name="flaim" />','     <help> structure of kml flight requirements (not used yet) </help>','  </parameter>');
            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="criterion" type="',class(obj.criterion),'" default="',convert2str(obj.criterion),'">','     <section name="flaim" />','     <help> element or nodal criterion for flight path evaluation (metric) </help>','  </parameter>');
        	fprintf(fid,'%s\n%s\n','</frame>');    
            
            % Arguments
            fprintf(fid,'%s\n%s\n%s\n','<frame key="2" label="Arguments:">','<section name="flaim" />');                    
            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="gridsatequator" type="',class(obj.gridsatequator),'" default="',convert2str(obj.gridsatequator),'">','     <section name="flaim" />','     <help> number of grids at equator (determines resolution) </help>','  </parameter>');
            fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n','  <parameter key ="usevalueordering" type="',class(obj.usevalueordering),'" optional="false">','     <section name="flaim" />','         <option value="',convert2str(obj.usevalueordering),'" type="string" default="true"></option>','     <help> flag to consider target values for flight path evaluation </help>','  </parameter>');
            fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n','  <parameter key ="split_antimeridian" type="',class(obj.split_antimeridian),'" optional="false">','     <section name="flaim" />','         <option value="',convert2str(obj.split_antimeridian),'" type="string" default="true"></option>','     <help> flag to split polygons on the antimeridian </help>','  </parameter>');
            fprintf(fid,'%s\n%s\n','</frame>');   
            
            % Optimization
            fprintf(fid,'%s\n%s\n%s\n','<frame key="3" label="Optimization:">','<section name="flaim" />');                    
            fprintf(fid,'%s%s%s\n%s\n%s%s%s\n%s\n%s\n','  <parameter key ="path_optimize" type="',class(obj.path_optimize),'" optional="false">','     <section name="flaim" />','         <option value="',convert2str(obj.path_optimize),'" type="string" default="true"></option>','     <help> optimize? (default false) </help>','  </parameter>');
            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="opt_ndir" type="',class(obj.opt_ndir),'" default="',convert2str(obj.opt_ndir),'">','     <section name="flaim" />','     <help> number of directions to test when moving a point.  If this value = 1, a random direction is tested. A value > 1 results in directions equally spaced from [0, 2*PI] being tested. For example, 4 would result in directions [0, PI/2, PI, 3PI/2] </help>','  </parameter>');
            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="opt_dist" type="',class(obj.opt_dist),'" default="',convert2str(obj.opt_dist),'">','     <section name="flaim" />','     <help> specifies the distance in km (default 25) to move a randomly selected path point on each iteration </help>','  </parameter>');
            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="opt_niter" type="',class(obj.opt_niter),'" default="',convert2str(obj.opt_niter),'">','     <section name="flaim" />','     <help> number of iterations (default 30,000) to run for flightplan optimization, i.e. the number of times to randomly select a point and move it. </help>','  </parameter>');
        	fprintf(fid,'%s\n%s\n','</frame>');     
            
            % Output
            fprintf(fid,'%s\n%s\n%s\n','<frame key="4" label="Output:">','<section name="flaim" />');                    
            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="solution" type="',class(obj.solution),'" default="',convert2str(obj.solution),'">','     <section name="flaim" />','     <help> name of kml solution file </help>','  </parameter>');
            fprintf(fid,'%s%s%s%s%s\n%s\n%s\n%s\n','  <parameter key ="quality" type="',class(obj.quality),'" default="',convert2str(obj.quality),'">','     <section name="flaim" />','     <help> quality of kml solution </help>','  </parameter>');
            fprintf(fid,'%s\n%s\n','</frame>');              
        
        end % }}}
		function obj = flaim(varargin) % {{{
			switch nargin
				case 0
					obj=setdefaultparameters(obj);
				otherwise
					error('constructor not supported');
			end
		end % }}}
		function obj = setdefaultparameters(obj) % {{{

		end % }}}
		function md = checkconsistency(obj,md,solution,analyses) % {{{

			%Early return
			if solution~=FlaimSolutionEnum(), return; end

			md = checkfield(md,'fieldname','flaim.tracks','file',1);
			if any(isnan(md.flaim.criterion)) || isempty(md.flaim.criterion)
				md = checkfield(md,'fieldname','flaim.targets','file',1);
			else
				md = checkfield(md,'fieldname','flaim.criterion','numel',[md.mesh.numberofvertices md.mesh.numberofelements]);
			end

		end % }}}
		function disp(obj) % {{{

			disp(sprintf('   FLAIM - Flight Line Adaptation using Ice sheet Modeling:')); 

			disp(sprintf('\n      Input:'));
			fielddisplay(obj,'targets'            ,'name of kml output targets file ');
			fielddisplay(obj,'tracks'             ,'name of kml input tracks file ');
			fielddisplay(obj,'flightreqs'         ,'structure of kml flight requirements (not used yet)');
			fielddisplay(obj,'criterion'          ,'element or nodal criterion for flight path evaluation (metric)');

			disp(sprintf('\n      Arguments:'));
			fielddisplay(obj,'gridsatequator'     ,'number of grids at equator (determines resolution)');
			fielddisplay(obj,'usevalueordering'   ,'flag to consider target values for flight path evaluation');
			fielddisplay(obj,'split_antimeridian' ,'flag to split polygons on the antimeridian');

			disp(sprintf('\n      Optimization:'));
			fielddisplay(obj,'path_optimize'     ,'optimize? (default false)');
			fielddisplay(obj,'opt_ndir'     ,{'number of directions to test when moving a point.  If this value = 1, a random direction is tested.',...
											  'A value > 1 results in directions equally spaced from [0, 2*PI] being tested.',...
											  'For example, 4 would result in directions [0, PI/2, PI, 3PI/2].'});
			fielddisplay(obj,'opt_dist'     ,'specifies the distance in km (default 25) to move a randomly selected path point on each iteration');
			fielddisplay(obj,'opt_niter'     ,{'number of iterations (default 30,000) to run for flightplan optimization',...
											   'i.e. the number of times to randomly select a point and move it.'});

			disp(sprintf('\n      Output:'));
			fielddisplay(obj,'solution'           ,'name of kml solution file');
			fielddisplay(obj,'quality'            ,'quality of kml solution');
		end % }}}
	end
end
