function [xtt, Qtt, goodfeat] = track(Ii, Ipi, SampleSize, xt, Qt, goodfeat, nbri, prv_feat_num)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Global Variables
global resolution winx winy saturation ...
    wintx winty spacing boundary boundary_t ...
    Nmax thresh ThreshQ ...
    N_max_feat method motion hist_eq_flag;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
xtt = zeros(2, N_max_feat);
                % creates a matrix to store updated feature loctions
scores = zeros(1, round((wintx.*winty)/2)-1);
                 % creates a matrix to store the SSD value of the candidate
                 % feature point
points = zeros(2, round((wintx.*winty)/2)-1);
                 % creates a matrix to store the location of the candidate
                 % feature point
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for i = 1:N_max_feat
    if goodfeat(i)
        
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        if ((nbri == 2) || (mod(nbri-1, 5) == 0))  && i > prv_feat_num
            searchspace = [15 15];
        else
            searchspace = [5 5];
        end
                % makes the search window larger each time feature points
                % are detected until a motion vector can be calculated
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        
        xtt_temp = xt(:,i) + motion(:,i);
        
        if (xt(1,i)-floor(wintx./2)) < 1 || (xt(1,i)+floor(wintx./2)) > size(Ii,1) ...
            || (xt(2,i)-floor(winty./2)) < 1 || (xt(2,i)+floor(winty./2)) > size(Ii,2)
            goodfeat(i)=0;
            xtt(:,i) = xt(:,i);
            continue;
                % If the original window around a feature point goes over
                % the edge of the image, it is no longer listed as a
                % feature point.
        end
        
        orig_win = Ii(xt(1,i)-floor(wintx./2):xt(1,i) + floor(wintx./2), xt(2,i) - floor(winty./2):xt(2,i) + floor(winty./2), 1);
                % extracts the original window
                
        count = 1;
                % a variable used for iteration
                
        minx = xtt_temp(1,1) - searchspace(1,1) - floor(wintx./2);
        maxx = xtt_temp(1,1) + searchspace(1,1) + floor(wintx./2);
        miny = xtt_temp(2,1) - searchspace(1,2) - floor(winty./2);
        maxy = xtt_temp(2,1) + searchspace(1,2) + floor(winty./2);
        
        if  minx < 1 || maxx > size(Ipi, 1) || miny < 1 || maxy > size(Ipi, 2)
            goodfeat(i)=0;
            xtt(:,i) = xt(:,i);
            continue;
                % If the tracking window of a candidate feature point goes
                % over the edge of the image, it is no longer listed as a
                % feature point.
        end
        
        searchwindow = Ipi(minx:maxx, miny:maxy, 1);
                % gives the location of the search window within the image
                
        if hist_eq_flag
            orig_win = hist_eq(orig_win);
                % histogram equalization of the original image
        end
        
        for a = -1*searchspace(1,1):searchspace(1,1)
            for b = -1*searchspace(1,2):searchspace(1,2)
                temp_win = searchwindow((ceil(size(searchwindow,1)./2) + a - floor(wintx./2)):((ceil(size(searchwindow, 1)./2) + a + floor(wintx./2)))...
                ,((ceil(size(searchwindow,2)./2) + b - floor(winty./2)):((ceil(size(searchwindow, 2)./2) + b + floor(winty./2)))));
                % extracts a window that is the size and location of the
                % search window from the new image
                
                if sum(sum(temp_win - temp_win)) ~= 0
                    break;
                end
                % checks for NaN values within the search window
                
                if hist_eq_flag
                    temp_win = hist_eq(temp_win);
                end
                % histogram equalization of the new image
                
                scores(count) = sum(sum((orig_win - temp_win).^2));
                points(1, count) = xtt_temp(1,1) + a;
                points(2, count) = xtt_temp(2,1) + b;
                % computes and stores SSD value and location of the center
                % of the tracking window
                
                count = count + 1;
            end
        end
        
        [minumum, index] = min(scores);
                % finds the minimum SSD, determining the best new feature
                % point
        xtt(:,i) = points(:, index);
                % stores the center point of the tracking window with
                % minimum SSD value
        
    else
        xtt(:,i) = xt(:,i);
                % copies the location of feature points that are no longer
                % good just to keep ComputeQuality() from crashing
    end
    
    motion(:,i) = xtt(:,i) - xt(:,i);
                % determines a motion vector used to predict the location
                % of the feature point in the next frame
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
maxQ = 0;
                % sets Q_max = 0 if Qttc is empty
Qtt = ComputeQuality(Ipi, xtt, goodfeat, wintx, winty);
                % computes the quality vector Qtt at location xtt on image
                % Ipi
                
TF = (Qtt > ThreshQ * Qt);

Qttc = Qtt(find(TF));


                % gets rid of feature points whose quality decreased by
                % more than threshQ throughout the track
Q_max = [Qttc;maxQ];
if ~method,
    maxQ = max(Q_max);
else
    maxQ = max(Q_max(find(Q_max<saturation*min(wintx,winty))));
end;
TF = TF & (Qtt > thresh*maxQ);
                % gets rid of feature points whose quality dropped below
                % thresh percentage of the quality of the strongest feature
                % point
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
goodfeat = TF;
                % updates existence of feature points
xtt = [TF, TF]'.*xtt;
                % updates location of feature points
Qtt = TF.*Qtt;
                % updates quality of feature points
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

