%
%   plot_modes_onethird_octave_bar.m  ver 2.1  by Tom Irvine
%
%   One-Third Octave Plot
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%   Input variables
%
%     fig_num = figure number
%
%     f = frequency (Hz)
%     b = amplitude
%      
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%   Output variables
%
%     fig_num = figure number plus 1
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%   External functions
%     xtick_label.m
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
function [fig_num] = plot_modes_onethird_octave_bar(fig_num, f, b, t_string, ylab)
% PLOT_MODES_ONETHIRD_OCTAVE_BAR
% Bar chart on 1/3-octave centers with equal visual bar widths.
% Bars are plotted at log10(center freq). Data tips show the *preferred*
% one-third-octave band centers (from array a) rather than log10(Hz).
% Requires R2019b+ for DataTipTemplate.

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    
    % coerce sizes
    pf   = fix_size(f);
    bspl = fix_size(b);

    % Preferred 1/3-octave nominal centers (you can edit this palette)
    a = [1, 1.25, 1.6, 2, 2.5, 3.15, 4, 5, 6.3, 8, 10, ...
         12.5, 16, 20, 25, 31.5, 40, 50, 63, 80, ...
         100, 125, 160, 200, 250, 315, 400, 500, ...
         630, 800, 1000, 1250, 1600, 2000, 2500, ...
         3150, 4000, 5000, 6300, 8000, 10000, ...
         12500, 16000];

    clear f;

    %--- Snap each pf(i) to the nearest a(j) if within 5% ---
    tol = 0.05;
    a_match = zeros(size(pf));       % the preferred centers used for data tip (and optionally X)
    label_str = strings(numel(pf),1);% tick labels
    
    for i = 1:numel(pf)
        % find closest preferred band by relative error
        [relerr, jbest] = min( abs(pf(i) - a) ./ a );
        if relerr < tol
            a_match(i) = a(jbest);
        else
            a_match(i) = pf(i); % keep original if no close match
        end

        % pretty tick labels using the *matched* (preferred) center
        v = a_match(i);
        if abs(v - 1000)   /1000   < 1e-6, label_str(i) = "1K";   % cosmetic
        elseif abs(v - 2000)/2000  < 1e-6, label_str(i) = "2K";
        elseif abs(v - 4000)/4000  < 1e-6, label_str(i) = "4K";
        elseif abs(v - 8000)/8000  < 1e-6, label_str(i) = "8K";
        elseif abs(v - 16000)/16000< 1e-6, label_str(i) = "16K";
        else
            % If it wasn't snapped, this may be a non-preferred value;
            % still label numerically.
            label_str(i) = string(sprintf('%g', v));
        end
    end

    % Choose what x-centers to use for plotting:
    % Option A (recommended): plot AT the preferred centers when matched.
    % Option B: keep your geometric cpf; only the tip shows preferred a_match.
    % We'll do Option A for maximum consistency.
    cpf = a_match;

    % Plot
    h=figure(fig_num);
    fig_num = fig_num + 1;
    hold on;

    xx    = log10(cpf);
    width = 0.7;
    bh = bar(xx, bspl, width, 'FaceColor', [0 0.4470 0.7410]);  % keep handle

    %=== Modern data tips: show preferred band centers from 'a' ===
    % If a point did not match within tolerance, we still show its actual pf(i)
    % in a separate row for transparency.
    rowPref = dataTipTextRow('fc (Hz)', cpf);   % uses a_match
    rowLvl  = dataTipTextRow(ylab, bspl);
    bh.DataTipTemplate.DataTipRows = [rowPref; rowLvl];

    % Optional: also show original pf(i) if it differed from the preferred
    showOriginal = any(abs((pf - cpf)./max(cpf,eps)) > 1e-12);
    if showOriginal
        rowOrig = dataTipTextRow('Original Center (Hz)', pf);
        bh.DataTipTemplate.DataTipRows = [rowPref; rowOrig; rowLvl];
        % Format both frequency rows nicel
        bh.DataTipTemplate.DataTipRows(1).Format = '%.5g';
        bh.DataTipTemplate.DataTipRows(2).Format = '%.5g';
        bh.DataTipTemplate.DataTipRows(3).Format = '%.5g';
    else
        bh.DataTipTemplate.DataTipRows(1).Format = '%.5g';
        bh.DataTipTemplate.DataTipRows(2).Format = '%.5g';
    end
    %=============================================================

    ylabel(ylab);
    xlabel('Center Frequency (Hz)');
    title(t_string);

    grid on;
    set(gca, 'MinorGridLineStyle','none', 'GridLineStyle',':', ...
             'XScale','lin', 'YScale','log');

    set(gca, 'XTick', xx);
    set(gca, 'XTickLabel', cellstr(label_str));

    % x-limits in log10-space using +/- 1/6 octave guard (~1.2599 factor)
    minf_raw = min(cpf);
    if (minf_raw > 80), minf_raw = 80; end
    fmin = log10(minf_raw/1.2599);
    fmax = log10(max(cpf)*1.2599);
    xlim([fmin, fmax]);

    % reference dashed line at y=3 (as in your code)
    xline_pair = [fmin; fmax];
    yline_pair = [3; 3];
    line(xline_pair, yline_pair, 'Color','red', 'LineStyle','--');

    % y-limits (log scale)
    ymax = 10^ceil(log10(1.2*abs(max(bspl))));
    if (ymax <= 0.1), ymax = 1; end
    ylim([0.1, ymax]);

    % annotation text (uses x in log10-space)
    if (ymax > 1000)
        text(fmin*1.02, 5, 'num=3');
    else
        text(fmin*1.02, 4, 'num=3');
    end


    set(h, 'Position', [0 0 1000 450]);

    hold off;
end
