%SOLVER class definition
%
%   Usage:
%      obj=solver();

classdef solver
    properties (SetAccess=public) 
		 options=cell(0,0);
	 end
	 methods
		 function obj = solver(varargin) % {{{
			 switch nargin
				 case 0
					 obj=setdefaultparameters(obj);
				 case 1
					 in=varargin{1};
					 if (isa(in,'numeric') & in==0),
						 % requesting templates do nothing
					 else
						 error('constructor not supported');
					 end 
				 otherwise
					 error('constructor not supported');
				 end
			 end % }}}
		 function obj = setdefaultparameters(obj) % {{{

			 %MUMPS is the default solver
			 if ismumps,
				 obj.options={'NoneAnalysis',mumpsoptions};
			 else
				 obj.options={'NoneAnalysis',iluasmoptions};
			 end

		 end % }}}
		 function obj = addoptions(obj,analysis,solveroptions) % {{{1

			 %Convert analysis from enum to string
			 analysis=EnumToString(analysis);

			 %first, find out if analysis has already been supplied
			 found=false;
			 for i=1:size(obj.options,1),
				 inanalysis=obj.options{i,1};
				 if strcmp(inanalysis,analysis),
					 found=true;
					 obj.options{i,1} = analysis;
					 obj.options{i,2} = solveroptions;
					 break;
				 end
			 end

			 if ~found,
				 obj.options{end+1,1}= analysis;
				 obj.options{end,2}  = solveroptions;
			 end
		 end
		 %}}}
		 function checkconsistency(obj,md,solution,analyses) % {{{
			 for i=1:size(obj.options,1),
				 if ~ischar(obj.options{i,1}),
					 checkmessage('solver is not well formatted: Analyses are not strings');
				 end
			 end
		 end % }}}
		 function PetscFile(solver,filename) % {{{
			 %PETSCFILE - build petsc file
			 %
			 %   Build a Petsc compatible options file, from the solver model field  + return options string
			 %
			 %   Usage:     PetscFile(solver,filename);

			 %open file for writing
			 fid=fopen(filename,'w');
			 if fid==-1,
				 error(['PetscFile error: could not open ' filename ' for writing']);
			 end

			 %write header
			 fprintf(fid,'%s%s%s\n','%Petsc options file: ',filename,' written from Matlab solver array');

			 %start writing options
			 for i=1:size(solver.options,1),
				 analysis=solver.options{i,1};
				 options=solver.options{i,2};

				 %first write analysis:
				 fprintf(fid,'\n+%s\n',analysis); %append a + to recognize it's an analysis enum

				 %now, write options
				 for j=1:size(options,2),
					 option=options{j};
					 if isempty(option),
						 %do nothing
					 elseif length(option)==1,
						 %this option has only one argument
						 fprintf(fid,'-%s\n',option{1});
					 elseif length(option)==2,
						 %option with value. value can be string or scalar
						 if isscalar(option{2}),
							 fprintf(fid,'-%s %g\n',option{1},option{2});
						 elseif ischar(option{2}),
							 fprintf(fid,'-%s %s\n',option{1},option{2});
						 else
							 error(['PetscFile error: option #' num2str(j) ' is not well formatted']);
						 end
					 else 
						 error(['PetscFile error: option #' num2str(j) ' is not well formatted']);
					 end
				 end
			 end

			 fclose(fid);
		 end %}}}
		 function disp(obj) % {{{1
			disp(sprintf('   solver parameters:'));

			for i=1:size(obj.options,1),
				analysis=obj.options{i,1};
				ioptions=obj.options{i,2};

				string='';
				for i=1:length(ioptions),
					option=ioptions{i};
					if isempty(option),
						%do nothing
					elseif length(option)==1,
						%this option has only one argument
						string=[string ' -' option{1}];
					elseif length(option)==2,
						%option with value. value can be string or scalar
						if isscalar(option{2}),
							string=[string ' -' option{1} ' ' num2str(option{2})];
						elseif ischar(option{2}),
							string=[string ' -' option{1} ' ' option{2}];
						else
							error(['PetscString error: option #' num2str(i) ' is not well formatted']);
						end
					else 
						error(['PetscString error: option #' num2str(i) ' is not well formatted']);
					end
				end

				disp(sprintf('   %s -> ''%s''',analysis,string));
			end
		 end
		 %}}}
	 end
 end
