function fout = showfit(varargin)
%SHOWFIT   Show the fit for the active curve.
%   SHOWFIT displays the fit specified in a dialog box for the active
%   curve. Use UNDOFIT or RMFIT to remove the fit. The display settings are
%   defined in the file FITPARAM.
%
%   By default, the first curve in the active figure is used (see FITPARAM
%   to change this default behavior). To fit another curve, select it
%   before calling SHOWFIT. If some data are selected by the "Data
%   Brushing" tool (only for Matlab >= 7.6), only those data are fitted.
%   If you use Matlab <=7.5, use SELECTFIT to fit only a part of the data
%   from the selected curve. 
%
%   SHOWFIT(FUN) specifies the fitting string FUN. FUN may be either a
%   default fit (eg, 'exp', 'power'), a user-defined fit (see EDITFIT),
%   or directly a fit equation (eg, 'c+a*exp(-x/x0)'). See EZFIT for the
%   syntax of FUN. FUN may also be any valid interpolation method string
%   (eg 'spline', 'cubic'... excepted 'linear'). See INTERP1 for the valid
%   interpolation methods.
%
%   SHOWFIT(F) displays the fit F defined from the fit structure returned
%   by EZFIT. See EZFIT for the definition of F.
%
%   SHOWFIT(..., 'PropertyName','PropertyValue',...) specifies the 
%   properties of the fit (e.g., fit colors, line width etc.). See the
%   default values in the file FITPARAM.
%
%   F = SHOWFIT(...) also returns the fit structure F. F has the same
%   content as the fit structure returned by EZFIT (see EZFIT for details),
%   and also contains a handle to the equation box and to the curve.
%
%   Note that if the option 'lin' or 'log' is not specified in the string
%   FUN, SHOWFIT checks the Y-scale to know if Y or LOG(Y) has to be
%   fitted.
%
%   Examples:
%      type 'plotsample' and follow the instructions.
%
%      plotsample power
%      showfit('c*x^n; log');
%
%      plotsample hist
%      f = ezfit('gauss');
%      showfit(f,'fitcolor','red','fitlinewidth',2);
%
%      plotsample poly2
%      f = showfit('z(v) = poly3','dispfitlegend','on');
%      editcoeff(f);
%
%   See also EZFIT, UNDOFIT, RMFIT, PLOTSAMPLE, PICKDATA, INTERP1.

%   F. Moisy, moisy_at_fast.u-psud.fr
%   Revision: 2.11,  Date: 2012/07/08
%   This function is part of the EzyFit Toolbox

% History:
% 2005/05/21: v1.00, first version.
% 2005/07/27: v1.01, cosmetics.
% 2005/10/07: v1.02, also displays the parameters in the plot.
% 2005/10/17: v1.10, uses the first curve of the active figure if no curve
%                    is active.
% 2005/10/18: v1.11, no display if no output arg.
% 2005/10/31: v1.20, also displays R. text is displayed in an annotation
%                    box. now uses pickdata. also accepts interpolation.
% 2005/11/03: v1.30, use the file 'fitparam.m' for the fit default values.
% 2005/11/05: v1.31, also displays the lin/log mode
% 2005/12/06: v1.40, opens a dialog box if the fitting function string is
%                    not specified.
% 2006/01/28: v1.41, first check if a curve is present.
% 2006/01/31: v1.42, bug fixed for R^2
% 2006/02/08: v2.00, new syntax. now works with the fit structure F.
% 2006/02/10: v2.01, displays the legend.
% 2006/02/16: v2.02, use evalfit.
% 2006/03/08: v2.03, idem v1.40; bug fixed when using showfit(f) where f
%                    is obtained from fit(x,y,...) without plot.
% 2006/09/04: v2.04, '$' and '!' accepted instead of ';' in FUN
% 2006/09/06: v2.05, bug fixed when F is a structure of a FIT originating
%                    from a deleted curve (f.hdata is an invalid handle)
% 2006/10/18: v2.10, accepts additional input parameters to chnage the
%                    default settings.
% 2012/07/08: v2.11, hold on/off now correctly (thanks Alec de Zegher)





%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% fit parameters:  (new v2.10)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% loads the default fit parameters:
try
    fp=fitparam;
catch
    error('No fitparam file found.');
end


% change the default values of the fit parameters according to the
% additional input arguments:
for nopt=1:(nargin-1)
    if any(strcmp(varargin{nopt},fieldnames(fp))) % if the option string is one of the fit parameter
        fp.(varargin{nopt}) = varargin{nopt+1};
    end
end



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% input arguments:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if nargin==0,
    % opens a dialog box with the last fit equation (saved in prevfit.mat):
    efroot=fileparts(mfilename('fullpath'));   % directory where the ezyfit toolbox is installed
    prevfitfile=[efroot filesep 'prevfit.mat'];
    if exist(prevfitfile,'file'),
        load(prevfitfile);
    else
        fun='m1 + m2 * x; m1 = 1; m2 = 1';
    end
    fun=inputdlg('Enter a default fit, a user-defined fit or directly a fit equation',...
        'General Curve Fit Definition',1,{fun});
    if ~isempty(fun)
        fun=fun{1};
        fun=strrep(fun,'$',';');  % new v2.04
        fun=strrep(fun,'!',';');
        save(prevfitfile,'fun');
        % if the option 'lin' or 'log' is not specified, use the Y-scale of
        % the current figure:
        if (isempty(findstr(strrep(fun,' ',''),';lin'))) && (isempty(findstr(strrep(fun,' ',''),';log'))),
            mode=get(gca,'YScale');
            fun=strrep([fun ';' mode(1:3)],';;',';');
        end
        f=ezfit(fun);
    else
        return;
    end
elseif nargin>=1,
    if isstruct(varargin{1}), % if argument is a structure
        f=varargin{1};
    elseif ischar(varargin{1}), % if argument is a string
        fun=varargin{1};
        fun=strrep(fun,'$',';');  % new v2.04
        fun=strrep(fun,'!',';');
        if sum(strcmp(fun,{'nearest','spline','pchip','cubic','v5cubic'})),
            f.name=fun;
            [f.x, f.y, f.hdata]=pickdata(fp);
        else  % if the string is not an interpolation
            if strcmp(fun,'poly'), % new v2.03
                str_ord=inputdlg('Order of the polynomial fit','Polynomial order',1,{'2'});
                if ~isempty(str_ord),
                    fun=['poly' str_ord{1}];
                else
                    return;
                end
            end
            % if the option 'lin' or 'log' is not specified, use the Y-scale of
            % the current figure:
            if (isempty(findstr(strrep(fun,' ',''),';lin'))) && (isempty(findstr(strrep(fun,' ',''),';log'))),
                mode=get(gca,'YScale');
                fun=strrep([fun ';' mode(1:3)],';;',';');
            end
            f=ezfit(fun,varargin{2:end});
        end
    else
        error('Use showfit with a string or a fit structure.');
    end
end



% output fit structure: idem as f, but with additional information.
fout=f;

% determines the X points used to evaluate the fit
switch fp.extrapol
    case {'none','data'},
        xminfit=min(f.x);
        xmaxfit=max(f.x);
    case 'fig',
        icg=get(gca);
        xminfit=icg.XLim(1);
        xmaxfit=icg.XLim(2);
end
if strcmp(get(gca,'XScale'),'log'),
    xfit=logspace(log10(xminfit),log10(xmaxfit),fp.npt);
else
    xfit=linspace(xminfit,xmaxfit,fp.npt);
end


% evaluate the fit / interpolation:
switch f.name
    case {'nearest','spline','pchip','cubic','v5cubic'}
        yfit = interp1(f.x, f.y, xfit, f.name);
    otherwise   % real fit (ie with a fitting function)  
        yfit = evalfit(f, xfit);
end

        
% determines the fit color:
if ischar(fp.fitcolor) || length(fp.fitcolor)==3
    fitcolor=fp.fitcolor; % fixed color
else
    fitcolor=[0 0 0]; % default color if no data in the figure
    if isfield(f,'hdata')
        if ishandle(f.hdata)
            co=get(f.hdata); % object properties of the data
            if isfield(co,'Color'),
                fitcolor=max(0,min(1,co.Color*fp.fitcolor)); % color indexed from that of the data
            end
        end
    end
end

% plots the fitted curve (modified v2.11)
holdState = ishold;
hold on;
fout.hfit = plot(xfit,yfit,'-','Color',fitcolor,'LineStyle',fp.fitlinestyle,'LineWidth',fp.fitlinewidth);
% Return to original hold state
if ~holdState
    hold off
end

% this tag is useful to delete the fit later
set(fout.hfit,'UserData', 'fit'); 

% give a 'DisplayName' to the fit:
if length(fout.name)>10,
    fitname='fit';
else
    fitname=greekize(fout.name);
end
setautodisplayname; % give a name to all the data in the figure (if they don't have one yet)
if isfield(f,'hdata'),
    if ishandle(f.hdata)   % new v2.05, changed v2.10
        try
            dataname = get(f.hdata,'DisplayName');
        catch
            dataname = 'data';
        end
        fitname=[fitname ' (' dataname ')'];
    end
end
set(fout.hfit,'DisplayName',fitname);


% makes the equation box:
if strcmp(fp.dispeqboxmode,'on')
    fout.heqbox = showeqbox(f,fp);
end

% updates the legend:
if strcmp(fp.dispfitlegend,'on')
    legend off;  % refresh the legend
    legend show;
end

% opens the Array Editor with the fit coefficients:
if (strcmp(fp.editcoeffmode,'on') && (isfield(fout,'m'))),
    editcoeff(fout);
end

% displays the fit equation in the command window if no output argument:
if ~nargout
    if isfield(fout,'m'),
        if strcmp(fp.dispeqmode,'on') % new v2.30
            dispeqfit(fout,fp);
        end
    end
    clear fout;
end
