function gabor_patch_avi

% seed the random number generator and pick some values
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
time_num = deblank(evalc('!date +%N'));
rng(str2double(time_num));

stim_size   = 5 + (rand * 15);
cyc_per_deg = 0.2 + (rand * 3);
drift_speed = 1 + (rand * 5);
orientation = round(rand * 180);

% geometry
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
hrz_sc_size = 34;%cm
vrt_sc_size = 27;%cm
view_dist   = 40.64;%cm
hrz_pix     = 1280;
vrt_pix     = 1024;

radian2deg = 180 / pi;

hrz_deg = 2 * ((atan((hrz_sc_size/2)/view_dist)) * radian2deg);
vrt_deg = 2 * ((atan((vrt_sc_size/2)/view_dist)) * radian2deg);

h_pixperdeg = hrz_pix / hrz_deg;
v_pixperdeg = vrt_pix / vrt_deg;

pixperdeg = mean([h_pixperdeg v_pixperdeg]);

pix_size = pixperdeg * stim_size; % size of the steim in pixels

fps = 30;
mov_secs = 30;
pix_drift = (drift_speed * pixperdeg) / fps; % number of pixels to drift on every frame.

cyc_num = cyc_per_deg * stim_size;

% initiate movie
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
write_vid = VideoWriter([time_num '.avi']);
write_vid.Quality = 100;
write_vid.FrameRate = fps;
open(write_vid)

% calculate and write frames
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
offset = 0;
ct = 1;
while ct <= (fps * mov_secs)

    my_surf = gabor(round(pix_size),cyc_num,orientation,round(offset));
    heatmap = num2colormap(my_surf,'gray',[-1 1]);

    writeVideo(write_vid,heatmap)

    offset = offset + pix_drift;
    ct = ct + 1;

end

close(write_vid)


function [my_surf,scale] = gabor(px_num,cycles,rt_angle,offset,edge_sig,bg_black)
debug = 0;

if nargin < 6
    bg_black = 0;  % 1 to make aperture background black
end
if nargin < 5
    edge_sig = .1; % determines steepness of aperture falloff
end
if nargin < 4
    offset = 0;     % off from center in pixels
end
if nargin < 3
    rt_angle = 0;  % used to rotate the grating angle
end
if nargin < 2
    cycles   = 20; % number of cycles in aperture
end
if nargin < 1
    px_num = 100;
end

% generate gaussian aperture
gauss_mean = .5;
xx         = 0:1/px_num:1;
my_gauss   = exp(-(xx - gauss_mean).^2/(2*edge_sig^2));

aperture   = my_gauss' * my_gauss;
aperture   = aperture - min(min(aperture));
aperture   = aperture ./ max(max(aperture));
aperture(aperture < .001) = 0;

% generate gratings
pi_data = (0:(cycles*pi)/px_num:(cycles*pi));
pi_data = pi_data + ((cycles*pi)/px_num) * offset;
grating = repmat(sin(pi_data),[px_num+1 1]);
if rt_angle
    grating = imrotate(grating,rt_angle,'bilinear','crop');
end
grating = grating - min(min(grating));
grating = grating ./ max(max(grating));
if ~bg_black
    grating = (grating*2) - 1;
end

% make surface
my_surf = grating .* aperture;
if bg_black
    scale = [0 1];
else
    scale = [-1 1];
end


if debug
    %     my_min = min(min(my_surf));
    %     my_max = max(max(my_surf));
    %     fprintf('min = %s, max = %s\n',num2str(my_min),num2str(my_max));

    heatmap = num2colormap(my_surf,'gray',scale);
    image(heatmap)
    axis off
    truesize
    drawnow
end


function y = gaussmf(x,params)
sigma = params(1); c = params(2);
y = exp(-(x - c).^2/(2*sigma^2));


function RGB_values = num2colormap(data,map,limits,gamma)
% RGB_values = num2colormap(data,map,limits)
%
% Given a vector or array "data", num2colormap returns RGB_values on a 256
% color scale similar to those that would be used to construct the figure
% output of "image(data)" given a specific colormap.

if nargin < 4, gamma  = [];    end
if nargin < 3, limits = [];    end
if nargin < 2, map    = 'jet'; end

% get rgb_data from selected map
if ischar(map)
    try
        eval(sprintf('map = %s(256);',map))
    catch
        map = othercolor(map,256);
    end
end
map = uint8(round(map * 255));

% scale data to 0-255 and change to uint8
if isempty(limits)
    data = data - min(min(data));
    data = data ./ max(max(data));
else
    data = data - limits(1);
    limits(2) = limits(2) - limits(1);
    data = data ./ limits(2);
end
data = data * 255;
data = uint8(round(data));

% apply gamma correction if the user asked for it
if ~isempty(gamma)
    data = double(data)/255; % rescale data to fall between 0 and 1
    data = data .^ gamma;
    data = uint8(data*255) ;   % rescale back to 8 bit color range
end

%get red green and blue info from lookup tables
red   = intlut(data,map(:,1));
green = intlut(data,map(:,2));
blue  = intlut(data,map(:,3));

%combine into RGB data
RGB_values(:,:,1) = red;
RGB_values(:,:,2) = green;
RGB_values(:,:,3) = blue;