; Copyright (c) 1998-2015 A.P. Hitchcock  All rights reserved
;+
;NAME:
;		STACK_WB
;
;LAST CHANGED: ----------------------------------- 27-Aug-15
; PURPOSE:
;	This procedure writes  a whole stack (3d (E,x,y) array) to a binary file
; with associated *.dat file to track paramaters
; assumes Common volume_data, image_stack exists and contains the data
; Scales data to within 1000 and 10000 of above 3e4 or below 1e3
; scale factor is stored, and reinstalled when using STACK_rb.pro
;
; CATEGORY:
;	stack processing; stand alone operation
;
; CALLING SEQUENCE:
;	WRITE_WB, FILE [, real=real, silent = silent, overwrite=overwrite]
;
; INPUTS:
; 	FILE	name of the output file
;
; KEYWORDS:
; 	REAL  - write as reals
;	SILENT - if set, no feedback
;	OVERWRITE - if set, do not check if file exists
;
; OUTPUTS:
;	*.ncb file
;
; COMMON BLOCKS:
; AXIS_COM	standard set of common blocks
; STACK_PROCESS_COM
; BSIF_COM
; volume_data, image_stack
;
; SIDE EFFECTS:

;
; RESTRICTIONS: none
;
; MODIFICATION HISTORY:
; (22-may-99 aph) first version
; (09-sep-99 aph) (x,y) scale reset to account for dimensions on nsls data
; (26-sep-99 aph) clean up name
; (27-oct-99 aph) leave (x,y) axes in original dimensions
; (28-feb-02 aph) adapt to handle 1-image stacks; AXIS standard header added
; (04-jun-04 aph) add free_lun; get to write more than 8-character filenames in list
; (17-Jun-05 aph) warning & switch re Unix format; print => axis_log
; (17-Sep-08 aph) replace analcom with stack_process_com
; (14-dec-09 aph) desensitize to filenames with '.' in them
; (27-Jan-10 aph) add write protect for *,ncb
; (14-Feb-10 aph) add write protext for *.dat files !; write as reals
; (20-Feb-10 aph) add hourglass for slow writes
; (22-Jul-10 aph) correct flag for case where scale is < 1
;                 fix REAL write out
; (22-Jul-13 aph) ensure filename has *.ncb, *.dat extensions
; (23-Jul-13 aph) add DefPath and remove duplicate checks
; (26-Jul-13 aph) REMOVE defPath - it was putting stacks in crazy places  & added back the second overwrite check !
; (10-Nov-13 aph) change printed information if do not save stack
; (21-Apr-14 aph) add OVERWRITE option to avoid multiple checks for existing file
; (21-Jul-14 aph) corrected header
; (27-Aug-15 aph) freed logical units after each use (otherwise repeated call suses up available LU
;-

PRO stack_wb, file, real=real, silent = silent, overwrite=overwrite
@axis_com		; include COMMON from file
@stack_process_com
COMMON volume_data, image_stack
@bsif_com

on_error,2
if strlen(file) EQ 0 then begin
	file = pickfile2(/WRITE, FILTER='*.ncb')  ;, /LPATH, DEFPATH=defpath),
endif
if strlen(file) EQ 0 then return

; ****************  For Macintosh computers ***********
;	Note that Intel processors and VAX machines are little endian,
;; while PowerPC processors (e.g., Macs, plus SGI/MIPS, Sun/SPARC),
;; are big endian.  For a number 0x01020304, a big endian machine
;; stores it starting from the "big" end as successive bytes 0x01,
;; 0x02, 0x03, and 0x04.  A little endian machine stores it starting
;; from the "little" end as successive bytes 0x04, 0x03, 0x02, and
;; 0x01.  In any case, we will assume that the binary data was written
;; from an Intel machine in little endian order, so we need to swap
;; the bytes around if we are running this program on a big endian
;; machine.

if !version.OS_family NE 'Windows' AND !version.OS_family NE 'UNIX' then $
	byteorder,image_stack,/swap_if_big_endian

; ------------------- this is already in PICKFILE2 ----------------
; -------- if file exists, ask if want to over-write  - but only if overwrite is not requested
if not keyword_set(overwrite) then begin
	test1 = findfile(file)
	t=ax_name(file)
	file2 = t(0)+t(1)+'.dat'
	test2 = findfile(file2)
	if test1(0) EQ file OR test2(0) EQ file2 then begin
		if widget_info(/active) EQ 1 then $
	    	t = file_overwrite(group = axis_ID, val = 1) else $
	    	t = file_overwrite(val = 1)
;;	    	print, 'code from overwrite ', t
	    if t EQ 0 then file = pickfile2(/write, fltr='*.ncb', $
	                      LFILE = file, title = 'Alternate name for this stack file', DefPath=DefPath)
	    if t EQ 2 then overwrite_all = 1
	endif
; ------------------- this is already in PiCKFILE2 ----------------
endif
t = ax_name(file)
fileshort = t(1)
file = t(0) + t(1) + '.ncb'  ; force ncb extension

WIDGET_CONTROL, /Hourglass		; in case it is a large file to write


; --------------- INTEGER format to save space - MUST re-set scale !! ------------
if NOT keyword_set(real) then begin
	tmax = max(image_stack, min = tmin)
	test = max([abs(tmin), abs(tmax)])
	scale = 1.
	if test GT 3e4 OR test LT 1e3 then  scale = 10.^(3-fix(alog10(test)))
	if scale NE 1 then begin
		if not keyword_set(silent) then begin
		  if scale GT 1 then print, 'Stack write: data rescaled by ', strtrim(fix(scale),2) $
		  else print, 'Stack write: data rescaled by  1 / ', strtrim(string(fix(round(1./scale))),2)
	  endif
	endif
	openw, iunit, file, /get_lun
	writeu, iunit, fix(scale*image_stack)
	close, iunit & free_lun, iunit
endif else begin
	scale = -1.
	openw, iunit, file, /get_lun
;	help, image_stack
	writeu, iunit, image_stack
	close, iunit & free_lun, iunit

endelse

dpos = strpos(file,'.ncb')
E_file = strmid(file,0,dpos)+'.dat'

openw, iunit, E_file, /get_lun
im_size = size(image_stack)
printf,iunit, im_size(1), im_size(2), scale
if im_size(0) EQ 2 then n_img = 1 else n_img = im_size(3)
;	axis_log, 'packing ' + strtrim(string(n_img),2) + ' images into ' + fileshort
if x_start NE 0 then begin
	x_stop = x_stop - x_start
	x_start = 0.
	y_stop = y_stop - y_start
	y_start = 0.
	if not keyword_set(silent) then print, 'reset (x,y) scales'
	if not keyword_set(silent) then print, 'X: ', x_start,' to ', x_stop
	if not keyword_set(silent) then print, 'Y: ', y_start,' to ', y_stop
endif
printf, iunit, x_start, x_stop
printf, iunit, y_start, y_stop
printf, iunit, n_img
for i = 0, n_img-1 DO printf, iunit, ev(i)
for i = 0, n_img-1 DO BEGIN
;		print, i+1,' of ',n_img ,'     ',  filename_ev_msec_list(i)
	printf, iunit, filename_ev_msec_list(i)
endfor
close, iunit & free_lun, iunit

if not keyword_set(silent) then axis_log, ' Binary STACK file wrote to  ' + file

END