function palmrender(object, event)
%
% palmrender: the palm image rendering function
% this functions take the .scf matrix field and generate a final PALM
% image using the desired rendering resolution
%
% by default, this function is called by system call back
% when object == 0 it is called internally by other functions
%   and when event = 1, it is to generate a fine (1 nm/pixel) PALM image for current view in a new window


	global h_palmpanel handles params;

	pixsize = str2num(get(handles.pixelsize, 'string'));

	if object == 0	% called by renders to generate high or low resolution images of current view
		% get the current viewport
		[ind x0 y0 x1 y1] = getpointsinview();
		scf = params.scf(ind, :);
		%figure; plot(scf(:, 1), scf(:, 2), 'g.'); axis image;
		scf(:, 1) = scf(:, 1) - (x0 - 2 * params.feature_size) / params.palm_mag;
		scf(:, 2) = scf(:, 2) - (y0 - 2 * params.feature_size) / params.palm_mag;

		palm_pixelsize = 1;
		width  = (x1 - x0 + 1) / params.palm_mag;
		height = (y1 - y0 + 1) / params.palm_mag;

		if(width >=60 || height >=60)	% image will be too large
			ans = questdlg('Area of interest is over 60 pixels. It will take a long time to generate the final image. Continue?', 'Warning!');
			if strcmp(ans, 'No')
				return;
			end
		end
	else
		scf = params.scf;
		width = params.width;
		height = params.height;
		palm_pixelsize = str2num(get(handles.renderpix, 'string'));	
	end

	particle_num = length(scf);
	if particle_num == 0
		dispmessage('Particles have not been sorted. Click SORT first');
		return;
	end		
	
	% create the final image matrix
	render_res = str2num(get(handles.renderres, 'string'));
	feature_size = ceil(render_res / palm_pixelsize);
    renderimg = gauss2d(0, 100, 2*feature_size, 2*feature_size, 0.5*feature_size, 4*feature_size+1, 4*feature_size+1);
	
	palm_mag  = pixsize / palm_pixelsize;
	palm_xdim = ceil(palm_mag * width) + 4*feature_size + 1;
	palm_ydim = ceil(palm_mag * height) + 4*feature_size + 1;
	palm_img  = zeros(palm_ydim, palm_xdim);

	msg = sprintf('Rendering particles. Please wait ...');
	dispmessage(msg);
	pause(0.001);	

	for i = 1 : particle_num
		%if mod(i, 100) == 0	|| i == particle_num || i == 1	
				
		%end

		x   = round(palm_mag * scf(i, 1)) + 2*feature_size;
		y   = round(palm_mag * scf(i, 2)) + 2*feature_size;

		ys = y-2*feature_size;		ye = y+2*feature_size;
		xs = x-2*feature_size; 		xe = x+2*feature_size;

		if(xs > 0 & ys > 0 & ye < palm_ydim & xe < palm_xdim)
			palm_img(ys : ye, xs : xe) = palm_img(ys : ye, xs : xe) + renderimg;
		end		
		% pause();
	end

	rendersize = 500;

	if object ~= 0 % render whole PALM image only
		fig_mag = min(rendersize/palm_ydim, rendersize/palm_xdim) * 100.0;
		params.palm_img = palm_img;
		params.palm_pixelsize = palm_pixelsize;
		params.palm_mag = palm_mag;
		params.feature_size = feature_size;
		psf_size = ceil(300/palm_pixelsize);		
		params.psf = gauss2d(0, 10, psf_size, psf_size, 150/palm_pixelsize, 2*psf_size+1, 2*psf_size+1);

		% show the image
	
		set(handles.autoscale, 'enable', 'on');
		autoscale = get(handles.autoscale, 'value');
		if autoscale == 1
			[disp_low disp_high] = autoscale2d(palm_img);
			%disp_high = 0.2* max(max(palm_img))
			set(handles.displow, 'string', num2str(disp_low, '%.1f'));
			set(handles.disphigh, 'string', num2str(disp_high, '%.1f'));
		else
			disp_low = str2num(get(handles.displow, 'string'));
			disp_high = str2num(get(handles.disphigh, 'string'));
		end	
		
		% see if there's a window open
		if(handles.palmfig == -1)
			handles.palmfig = figure; 
			set(handles.palmfig, 'Position', [200 100 500 500], 'CloseRequestFcn', @onfigpalmclosed);
		end

		figure(handles.palmfig);	hold off;
		imshow(palm_img, [disp_low disp_high], 'InitialMagnification', fig_mag); 
		axis on; axis image; colormap(hot);
		titlemsg = sprintf('Rendered at %d nm/pixel', params.palm_pixelsize);
		title(titlemsg);
		filen = params.filename(1:length(params.filename)-4);
		wintitle = sprintf('PALM Image of %s', filen);
		set(gcf, 'name', wintitle, 'NumberTitle', 'off');

		params.fig_mag = fig_mag;
		params.palm_xdim = palm_xdim;
		params.palm_ydim = palm_ydim;

		% enable the 'low res' button
		set(handles.lowres, 'enable', 'on');
		set(handles.highres, 'enable', 'on');
		set(handles.cluster, 'enable', 'on', 'callback', @clusteranalysis);
		%set(handles.palmexport, 'enable', 'on');
		
	else
		fig_mag = min(rendersize/(palm_ydim - 4*feature_size), rendersize/(palm_xdim - 4*feature_size)) * 100.0;
		%[disp_low disp_high] = autoscale2d(palm_img);
		autoscale = get(handles.autoscale, 'value');
		if autoscale == 1
			[disp_low disp_high] = autoscale2d(palm_img);
			%disp_high = 0.2* max(max(palm_img))
			% display high and low values to 0.1 precision
			set(handles.displow, 'string', num2str(disp_low, '%.1f'));	
			set(handles.disphigh, 'string', num2str(disp_high, '%.1f'));
		else
			disp_low = str2num(get(handles.displow, 'string'));
			disp_high = str2num(get(handles.disphigh, 'string'));
		end	
		
		if handles.figfine == -1
			h = figure; 
			set(h, 'Position', get(handles.palmfig, 'Position'));
			handles.figfine = h;
		else
			h = handles.figfine;	
		end
		
		figure(h); set(h, 'CloseRequestFcn', @onfigfineclosed);
		show_y = 2*feature_size : palm_ydim - 2*feature_size;
		show_x = 2*feature_size : palm_xdim - 2*feature_size;
		hold off; imshow(palm_img(show_y, show_x), [disp_low disp_high], 'InitialMagnification', fig_mag); 
		axis on; axis image; colormap(hot);
		xlabel('X (nm)');	ylabel('Y (nm)');
		titlemsg = sprintf('PALM Image Rendered at 1 nm/pixel. Viewport = (%d, %d) - (%d, %d)', x0, x1, y0, y1);
		title(titlemsg);
		
		filen = params.filename(1:length(params.filename)-4);
		wintitle = sprintf('PALM Image of %s', filen);
		set(gcf, 'name', wintitle, 'NumberTitle', 'off');
		
		% record the current view information in the 'userdata' field of FineFig
		fv_userdata = get(h, 'userdata');
		fv_userdata.ind = ind;
		fv_userdata.x0 = x0;
		fv_userdata.y0 = y0;
		fv_userdata.x1 = x1;
		fv_userdata.y1 = y1;
		
		% initialize the cur_point handle for pointtrack to use
		fv_userdata.h_curpoint = -1;
		
		set(h, 'userdata', fv_userdata);
		
		% activate buttons for viewport analysis
		set(handles.pointtrack, 'enable', 'on', 'callback', @pointtrack);
	end	

	msg = sprintf('Rendering particles. Please wait ... done.');
	dispmessage(msg);
	pause(0.001);

return


