;------------------------------------------------------------------------------;
;+
; NAME:
;		DIVA_IMAGE__DEFINE
; PURPOSE:
;		This procedure defines the "diva_image" (named) structure (see
;		IDL help: "Automatic Stucture Definition").
; INPUTS:
;		None
; AUTHOR:
;		John A. Rainnie - RAL (j.a.rainnie@rl.ac.uk)
;-
;------------------------------------------------------------------------------;
PRO diva_image__define
;------------------------------------------------------------------------------;
    junk = {	    diva_image,     	    	    	                    $
    	    	    file_info	    :   {diva_file},	                    $
		    		pimage  	    :   Ptr_New(),	    	                $
		    		o_pimage  	    :   Ptr_New(),	    	                $
		    		p_pimage  	    :   Ptr_New(),	    	                $
					s_pimage  	    :   Ptr_New(),	    	                $
		    		xsize   	    :   0UL,		    	                $
		    		ysize   	    :   0UL,		    	                $
					prev_xsize		:	0UL,								$
					prev_ysize		:	0UL,								$
		    		n_dim   	    :	0UL,	    	                    $
    	    	    n_byt			:	0UL,								$
					i_mean	    	:   [0.D,0.,0.], 	                    $
		    		i_variance      :	[0.D,0.,0.],	                    $
		    		i_stddev	    :   [0.D,0.,0.],	                    $
		    		i_max	    	:   [0L,0,0],   	                    $
		    		i_min	    	:   [0L,0,0],   	                    $
		    		ops_name	    :	'', 	    	                    $
		    		ops_bshift      :	[0,0],  	    	                $
    	    	    mfile_name	    :   '',		    		                $
		    		mfile_name_str  :	'', 	    	                    $
		    		mfile_date	    :   '',		    		                $
		    		mfile_time	    :   '',		    		                $
		    		mfile_pos_from  :   0L,		    		                $
		    		mfile_pos_to    :   0L,		    		                $
		    		mfile_size	    :	0L,  	    	                    $
		    		diva_n_images   :	0L 	    	    	                $
	    }
		
END ; of "diva_image__define" procedure----------------------------------------;
;------------------------------------------------------------------------------;
;+
; NAME:
;		DIVA_IMAGE_INIT
; PURPOSE:
;		This function assigns real values to "diva_image" (named) structure
;		tags.
; INPUTS:
;		diva_image	-
;		image		-
; OUTPUTS:
;		diva_image	-
; PROCEDURES USED:
;		FUNCTIONS:	REVERSE, ROTATE
; AUTHOR:
;		John A. Rainnie - RAL (j.a.rainnie@rl.ac.uk)
;-
;------------------------------------------------------------------------------;
FUNCTION diva_image_init,diva_image,image
;------------------------------------------------------------------------------;

image					= REVERSE(image)
n_dim					= diva_image.n_dim
CASE n_dim OF
   1:	   image	    = ROTATE(image,2)
   3:	   BEGIN
			   b0	    = ROTATE(image[*,*,0],2)
			   b1	    = ROTATE(image[*,*,1],2)
			   b2	    = ROTATE(image[*,*,2],2)
			   image	= [[[b0]],[[b1]],[[b2]]]
		   END
   ELSE:   stop
ENDCASE

xsize					= diva_image.xsize
ysize					= diva_image.ysize
n_byt					= diva_image.n_byt
diva_n_images			= diva_image.diva_n_images

;update ops_name to include x and ysizes
file_info			   = diva_image.file_info
file_str	    	   = file_info.file_str
file_ext	    	   = file_info.file_ext
pathname	    	   = file_info.pathname
mfile_name_str  	   = diva_image.mfile_name_str

CASE diva_n_images OF
   1:	   ops_name    = file_info.f
   ELSE:   ops_name    = pathname 	+   file_str		+ '__'    			$
								 	+   mfile_name_str	+ '.'	  			$
								 	+   file_ext
ENDCASE

ending = 	'(' + STRCOMPRESS(xsize,/remove) +  							$
			',' + STRCOMPRESS(ysize,/remove) +  							$
			',' + STRCOMPRESS(n_dim,/remove) + ')(1,0)'

diva_image.ops_name 	  = STRCOMPRESS(ops_name + ending,/rem)
diva_image.ops_bshift	  = [1,0]
diva_image.mfile_size	  = ( xsize * ysize * n_dim * n_byt )

;free up previous image pointers
PTR_FREE,diva_image.pimage
PTR_FREE,diva_image.o_pimage
PTR_FREE,diva_image.p_pimage
PTR_FREE,diva_image.s_pimage

diva_image.pimage		  = PTR_NEW(image)
diva_image.o_pimage 	  = diva_image.pimage
;-------------------------------------------------------------------;
;create preview image-----------------------------------------------;
;-------------------------------------------------------------------;
diva_prev_image_congrid,diva_image.pimage,p_pimage,	    			$
					   xsize,ysize,n_dim[0],prev_xsize,prev_ysize
diva_image.p_pimage[0]	= p_pimage
diva_image.prev_xsize	= prev_xsize
diva_image.prev_ysize	= prev_ysize
;-------------------------------------------------------------------;

RETURN,diva_image

END ; of "diva_image_init" function--------------------------------------------;
;------------------------------------------------------------------------------;
;+
; NAME:
;		DIVA_IMAGE_COPY
; PURPOSE:
;		This procedure
; INPUTS:
;		diva_image_in	-
; OUTPUTS:
;		diva_image_out	-
; AUTHOR:
;		John A. Rainnie - RAL (j.a.rainnie@rl.ac.uk)
;		Also thanks to Phil Kershaw - RAL
;-
;------------------------------------------------------------------------------;
Pro diva_image_copy, diva_image_in, diva_image_out
;------------------------------------------------------------------------------;
; Output will be over-written so make sure that pointers are freed first 
;before they are copied over - this avoids dangling pointer references
if N_Elements(diva_image_out) then begin
    Ptr_Free, diva_image_out.pimage
    Ptr_Free, diva_image_out.p_pimage
    Ptr_Free, diva_image_out.o_pimage
EndIf

; Copy all tags
diva_image_out = diva_image_in

; For pointer varibles make sure to copy data and not just the pointers
diva_image_out.pimage 	= Ptr_New(*diva_image_in.pimage)
diva_image_out.p_pimage = Ptr_New(*diva_image_in.p_pimage)
diva_image_out.o_pimage = Ptr_New(*diva_image_in.o_pimage)    
End ; of "diva_image_copy" procedure-------------------------------------------;
;------------------------------------------------------------------------------;
;+
; NAME:
;		DIVA_IMAGE_STORE
; PURPOSE:
;		This procedure appends a "diva_image" structure to the list
;		of already stored images. It is this list that is displayed in
;		DIVA_MATH and DIVA_CONC. Hence, if these widgets are registered,
;		their lists will be updated.
; INPUTS:
;		pdiva_draw	-
;		func		- a string indicating whether
; AUTHOR:
;		John A. Rainnie - RAL (j.a.rainnie@rl.ac.uk)
;-
;------------------------------------------------------------------------------;
PRO diva_image_store,pdiva_draw,func
;------------------------------------------------------------------------------;

CASE func OF
	'current'	:	curr = (*pdiva_draw).diva_current_image
	'prev'		:	curr = (*pdiva_draw).diva_current_prev_image
ENDCASE

diva_image_copy, curr, new_curr

;make "s_image" --> small image (maximum dimension = 150)
diva_small_image_congrid,new_curr.pimage,s_pimage,new_curr.xsize,			$
								new_curr.ysize,new_curr.n_dim,				$
								prev_xsize,	prev_ysize
new_curr.s_pimage = s_pimage

IF (Ptr_Valid((*pdiva_draw).diva_image_stored) eq 0) THEN BEGIN
	(*pdiva_draw).diva_image_stored = Ptr_New(new_Curr)
ENDIF ELSE BEGIN
	(*(*pdiva_draw).diva_image_stored) =   	    	    					$
    	    	    			[(*(*pdiva_draw).diva_image_stored),new_curr]

	;DIVA_MATH!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	IF (XREGISTERED("diva_math") eq 1) THEN BEGIN
		diva_math_list  	= (*(*pdiva_draw).diva_image_stored)[*].ops_name
		diva_math_list_mini = strarr(n_elements(diva_math_list))
		

		FOR i = 0, n_elements(diva_math_list) - 1 DO BEGIN
 			diva_math_list[i] 		= '[' + strcompress(i+1,/rem) + 		$
										'] ' + diva_math_list[i]

 			diva_math_list_mini[i]	= '[' + strcompress(i+1,/rem) + 		$
											'] ' +							$
											strmid(diva_math_list[i],		$
 	    									strpos(diva_math_list[i],		$
											'/',/reverse_search)+1)

			diva_math_list[i] 		=	strmid(diva_math_list[i],0, 		$
										strpos(diva_math_list[i],'('))
		ENDFOR

		wid_1 = (*(*pdiva_draw).diva_math_info).diva_op1_list_id
		wid_2 = (*(*pdiva_draw).diva_math_info).diva_op2_list_id
		widget_control,wid_1,set_value = diva_math_list
		widget_control,wid_2,set_value = diva_math_list_mini
	
	ENDIF ;of condition 'diva_math' is XRegistered
	
	;DIVA_CONC!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	IF (XREGISTERED("diva_conc") eq 1) THEN BEGIN
		diva_conc_list = (*(*pdiva_draw).diva_image_stored)[*].ops_name
		
		FOR i = 0, n_elements(diva_conc_list) - 1 DO diva_conc_list[i] = 	$
									'['  + strcompress(i+1,/rem) + 			$
									'] ' + diva_conc_list[i]
		
		wid_1 = (*(*pdiva_draw).diva_conc_info).diva_conc_list_id
		widget_control,wid_1,set_value =  diva_conc_list
	ENDIF;of condition 'diva_conc' is XRegistered


ENDELSE	;of condition "diva_image_stored" is Valid Pointer (ie; IS populated)
		
END ; of "DIVA_IMAGE_STORE" procedure------------------------------------------;
;------------------------------------------------------------------------------;
;+
; NAME:
;		DIVA_IMAGE_ROTATE
; PURPOSE:
;		This procedure rotates an image
; INPUTS:
;		diva_image	-	the 
;		rot_value	- 	1 = anti-clockwise (90 degrees left)
;						2 = flip (180 degrees)
;						3 = clockwise (90 degrees right)
; OUTPUTS:
;		diva_image	-	with rotated image and updated x and y sizes
; AUTHOR:
;		John A. Rainnie - RAL (j.a.rainnie@rl.ac.uk)
;		Also thanks to Phil Kershaw - RAL
;-
;------------------------------------------------------------------------------;
pro diva_image_rotate,diva_image,rot_val
;------------------------------------------------------------------------------;
CASE diva_image.n_dim OF
    1:	    BEGIN
    	    	new_pimage = ROTATE(*diva_image.pimage,rot_val)
    	    	PTR_FREE, diva_image.pimage
	    		diva_image.pimage = Ptr_New(new_pimage)
	    	END
    3:	    BEGIN
    	    	b0	= ROTATE((*diva_image.pimage)[*,*,0],rot_val)
				b1	= ROTATE((*diva_image.pimage)[*,*,1],rot_val)
				b2	= ROTATE((*diva_image.pimage)[*,*,2],rot_val)
		
				PTR_FREE, diva_image.pimage
				diva_image.pimage =	PTR_NEW([[[b0]],[[b1]],[[b2]]])
    	    END
    ELSE:   BEGIN
				stop
	    	END
ENDCASE
    
    new_size 	     = SIZE(*diva_image.pimage)
    diva_image.xsize = new_size[1]
    diva_image.ysize = new_size[2]
    
END ; of 'diva_image_rotate' procedure-----------------------------------------;
;------------------------------------------------------------------------------;
;+
; NAME:
;		DIVA_IMAGE_CONGRID
; PURPOSE:
;		This procedure resizes an image
; INPUTS:
;		diva_image	- the  
;		new_xsize	- the required image width 
;		new_ysize	- the required image height
; OUTPUTS:
;		diva_image	- with resized image and updated x and y sizes
; AUTHOR:
;		John A. Rainnie - RAL (j.a.rainnie@rl.ac.uk)
;-
;------------------------------------------------------------------------------;
pro diva_image_congrid,diva_image,new_xsize,new_ysize
;------------------------------------------------------------------------------;
new_pimage = CONGRID(*diva_image.pimage,new_xsize,new_ysize,diva_image.n_dim)
PTR_FREE, diva_image.pimage
diva_image.pimage = PTR_NEW(new_pimage)

new_size    	 = SIZE(*diva_image.pimage)
diva_image.xsize = new_size[1]
diva_image.ysize = new_size[2]

END ;of 'diva_image_congrid' procedure;----------------------------------------;
;------------------------------------------------------------------------------;
;+
; NAME:
;		DIVA_PREV_IMAGE_CONGRID
; PURPOSE:
;		This procedure makes a preview image by resampling the input image
; INPUTS:
;		pimage		- the original image (to be resampled to make the
;						preview image) 
;		xsize,ysize - the width and height of the original image
;		n_dim		- 1 or 3 for grayscale or rgb images, respectively
; OUTPUTS:
;		p_pimage	- the preview image
;		prev_xsize	- width of the preview image
;		prev_ysize  - height of the preview image
; PROCEDURE:
;		to make the preview image. If the image is square, then it will
;		be 250 x 250 pixels. If, however, the image is NOT a square,
;		then it's max dimension (x or y) will be 250 and the min
;		dimension will be calculated to preserve the aspect ratio.
;		However, in the case of images where this is impractical 
;		(eg: x >> y or vice versa) then both dimensions will be set to 
;		250 pixels!
; AUTHOR:
;		John A. Rainnie - RAL (j.a.rainnie@rl.ac.uk)
;-
;------------------------------------------------------------------------------;
PRO diva_prev_image_congrid,pimage,p_pimage,xsize,ysize,n_dim,prev_xsize,	$
																prev_ysize
;------------------------------------------------------------------------------;
if (xsize ne ysize) then begin
	dims = [xsize,ysize]
	the_max = where(dims eq max(dims))
	CASE the_max[0] OF
		0:	BEGIN
				prev_xsize = 250
				prev_ysize = round((float(dims[1])/float(dims[0])) * 250 )
			END
		1:	BEGIN
				prev_xsize = round((float(dims[0])/float(dims[1])) * 250 )
				prev_ysize = 250
			END
	ENDCASE
endif else begin
	prev_xsize = 250
	prev_ysize = 250
endelse

if (prev_xsize lt 50) then prev_xsize = 250
if (prev_ysize lt 50) then prev_ysize = 250

p_pimage = congrid(*pimage,prev_xsize,prev_ysize,n_dim)
p_pimage = Ptr_new(p_pimage)
END ; of "diva_prev_image_congrid" procedure-----------------------------------;
;------------------------------------------------------------------------------;
;------------------------------------------------------------------------------;
;------------------------------------------------------------------------------;
;------------------------------------------------------------------------------;
;+
; NAME:
;		DIVA_SMALL_IMAGE_CONGRID
; PURPOSE:
;		This procedure makes a "small" image by resampling the input image
;		(see above - however, maximum size is 150 in this case). This 
;		"small" image is displayed in DIVA_MATH and DIVA_CONC guis.
; INPUTS:
;		pimage		- the original image
;		xsize,ysize - the width and height of the original image
;		n_dim		- 1 or 3 for grayscale or rgb images, respectively
; OUTPUTS:
;		p_pimage	- the small image
;		prev_xsize	- width of the preview image
;		prev_ysize  - height of the preview image
; PROCEDURE:
;		cf. "diva_prev_image_congrid"
; AUTHOR:
;		John A. Rainnie - RAL (j.a.rainnie@rl.ac.uk)
;-
;------------------------------------------------------------------------------;
PRO diva_small_image_congrid,pimage,s_pimage,xsize,ysize,n_dim,prev_xsize,	$
																prev_ysize
;------------------------------------------------------------------------------;
IF (xsize ne ysize) THEN BEGIN
	dims = [xsize,ysize]
	the_max = WHERE(dims eq MAX(dims))
	CASE the_max[0] OF
		0:	BEGIN
				prev_xsize = 150
				prev_ysize = ROUND((FLOAT(dims[1])/FLOAT(dims[0])) * 150 )
			END
		1:	BEGIN
				prev_xsize = ROUND((FLOAT(dims[0])/FLOAT(dims[1])) * 150 )
				prev_ysize = 150
			END
	ENDCASE
ENDIF ELSE BEGIN
	prev_xsize = 150
	prev_ysize = 150
ENDELSE

IF (prev_xsize lt 30) THEN prev_xsize = 150
IF (prev_ysize lt 30) THEN prev_ysize = 150

s_pimage = CONGRID(*pimage,prev_xsize,prev_ysize,n_dim)
s_pimage = PTR_NEW(s_pimage)
END ; of "diva_small_image_congrid" procedure----------------------------------;
;------------------------------------------------------------------------------;
