function [R,L] = match_query(D,SR,IX)
% [R,L] = match_query(D,SR,IX)
%     Match landmarks from an audio query against the database.
%     Rows of R are potential maxes, in format
%      songID  modalDTcount modalDT
%     i.e. there were <modalDTcount> occurrences of hashes 
%     that occurred in the query and reference with a difference of 
%     <modalDT> frames.
%     Input D is either audio waveform at sample rate SR, or a
%     3-column array of hashes (e.g., from landmark2hash, or get_hashes_for_track).
%     L returns the actual landmarks that this implies for IX'th return.
% 2008-12-29 Dan Ellis [email protected]

if nargin < 3
  IX = 1;
end


if size(D, 2) == 3
  % We were passed hashes, not audio
  Lq = [];
  Hq = D;

else

  % Target query landmark density
  % (reference is 7 lm/s, query can be maybe 4x denser?)
  dens = 20;

  % collapse stereo
  if size(D,2) == 2
    D = mean(D,2);
  end

  %Rt = get_hash_hits(landmark2hash(find_landmarks(D,SR)));
  Lq = find_landmarks(D,SR, dens);
  %%Lq = fuzzify_landmarks(Lq);
  % Augment with landmarks calculated half-a-window advanced too
  landmarks_hopt = 0.032;
  Lq = [Lq;find_landmarks(D(round(landmarks_hopt/4*SR):end),SR, dens)];
  Lq = [Lq;find_landmarks(D(round(landmarks_hopt/2*SR):end),SR, dens)];
  Lq = [Lq;find_landmarks(D(round(3*landmarks_hopt/4*SR):end),SR, dens)];
  % add in quarter-hop offsets too for even better recall

  Hq = unique(landmark2hash(Lq), 'rows');
end

disp(['landmarks ',num2str(size(Lq,1)),' -> ', num2str(size(Hq,1)),' hashes']);
Rt = get_hash_hits(Hq);
nr = size(Rt,1);

if nr > 0

  % Find all the unique tracks referenced
  [utrks,xx] = unique(sort(Rt(:,1)),'first');
  utrkcounts = diff([xx',nr]);

  [utcvv,utcxx] = sort(utrkcounts, 'descend');
  % Keep at most 20 per hit
  utcxx = utcxx(1:min(20,length(utcxx)));
  utrkcounts = utrkcounts(utcxx);
  utrks = utrks(utcxx);
  
  nutrks = length(utrks);
  R = zeros(nutrks,4);

  for i = 1:nutrks
    tkR = Rt(Rt(:,1)==utrks(i),:);
    % Find the most popular time offset
    [dts,xx] = unique(sort(tkR(:,2)),'first');
    dtcounts = 1+diff([xx',size(tkR,1)]);
    [vv,xx] = max(dtcounts);
    R(i,:) = [utrks(i),vv,dts(xx),size(tkR,1)];
    R(i,:) = [utrks(i),sum(abs(tkR(:,2)-dts(xx))<=1),dts(xx),size(tkR,1)];
  end

  % Sort by descending match count
  [vv,xx] = sort(R(:,2),'descend');
  R = R(xx,:);

  % Extract the actual landmarks
  H = Rt((Rt(:,1)==R(IX,1)) & (Rt(:,2)==R(IX,3)),:);
  % Restore the original times
  for i = 1:size(H,1)
    hix = find(Hq(:,3)==H(i,3));
    hix = hix(1);  % if more than one...
    H(i,2) = H(i,2)+Hq(hix,2);
    L(i,:) = hash2landmark(H(i,:));
  end


  % Return no more than 100 hits, and only down to 10% the #hits in
  % most popular
  maxrtns = 100;
  if size(R,1) > maxrtns
    R = R(1:maxrtns,:);
  end
  maxhits = R(1,2);
  nuffhits = R(:,2)>(0.1*maxhits);
  %R = R(nuffhits,:);

else
  R = [];
  disp('*** NO HITS FOUND ***');
end