FUNCTION DIcal_xtalk, in, fitsHdr, FN=fn, FLAGS=flags

;;-----------------------------------------------------------------------------
;; PURPOSE:
;;	Used in the DI Calibration Pipeline.
;;	Removes the electrical crosstalk across quadrant boundaries
;;
;; CALLING SEQUENCE:
;;	out = DIcal_xtalk, in, fitsHdr
;;
;; REQUIRED INPUTS:
;;	in - The image to which this pipeline element is going to be applied
;;	fitsHdr - The FITS header for the image
;;
;; OUTPUTS:
;;	RETURN -  the image after going through this  calibration step
;;
;; OPTIONAL INPUT KEYWORDS:
;;	FN - Filename of the gains to use. If this keyword is not set,
;;		the database is queried.
;;	FLAGS - Flags to identify bad sections of data
;;
;; EXAMPLE:
;;      IDL> imgOut = DIcal_xtalk(imgIn, fitsHdr)
;;
;; PROCEDURES USED (i.e. called directly!):
;;	SXPAR - Read FITS header
;;	FXADDPAR - Modifies the FITS header
;;	DI_SQLQuery - queries the database
;;	getLocFN - Retrieves a local file
;;
;; MODIFICATION HISTORY:
;;   2004-11-15  M. Desnoyer    Created
;;
;;-----------------------------------------------------------------------------

;; Do error handling 
;CATCH, error
error=0

IF error NE 0 THEN BEGIN
	CATCH, /CANCEL
	message, 'Remove crosstalk - ' + !ERROR_STATE.MSG, /NONAME
ENDIF

;; Include
@dical_flags

out = double(in)

;; Get the instrument
inst = strtrim(SXPAR(fitsHdr, 'INSTRUME', COUNT=c1),2)

;; Get the date the image was taken
date = SXPAR(fitsHdr, 'OBSDATE', COUNT=c2)

;; Get the image mode
mode = SXPAR(fitsHdr, 'IMGH030', COUNT=c3)

;; Make sure the FITS header contained everything
IF (c1 EQ 0) OR (c2 EQ 0) OR (c3 EQ 0) THEN $
	message, 'Invalid FITS Header', /NONAME

;; Get the filename of the gains
IF NOT keyword_set(fn) THEN BEGIN
	serv = getSQLserver()
	db = 'di_calib'
	tbl = 'XTALK'
	sel = ['Filepath']
	cond = 'Instrument = "'+inst+'" AND Date <= "'+date+$
		'" AND Mode = '+strtrim(mode,2)+' order by Date desc, Version desc limit 1'

	webfn = di_sqlquery(serv, db, tbl, sel, cond, dim=dim)

	IF min(dim) EQ 0 THEN message, 'No valid crosstalk gains'

	fn1 = getLocFn(webFn, subdir='XTALK')
ENDIF ELSE fn1 = fn

;; Get the gains
gains = readFITS(fn1[0], calHdr, /SILENT)

;; Figure out where quadrants are, shifts and rotates
dim = size(out, /dimensions);
IF inst EQ 'HRIIR' THEN BEGIN
	qcnt = 2
	;; Find quadrant locations. The first row is the xy-coordinates
	;; of the minimum corner. The second row is the coordinates of
	;; the maximum corner.
	qloc = intarr(2,2,qcnt)
	qloc[*,*,0] =  [[0         ,0       ],$
			[dim[0]/2-1,dim[1]-1]]
	qloc[*,*,1] =  [[dim[0]/2,0       ],$
			[dim[0]-1,dim[1]-1]]
	rot =  [[0,5],$
		[5,0]]
	shft = intarr(2,2)
ENDIF ELSE BEGIN ;;VIS
	qcnt = 4
	;; Find quadrant locations. The first row is the xy-coordinates
	;; of the minimum corner. The second row is the coordinates of
	;; the maximum corner.
	qloc = intarr(2,2,qcnt)
	qloc[*,*,0] =  [[0         ,dim[1]/2], $
			[dim[0]/2-1,dim[1]-1]]
	qloc[*,*,1] =  [[dim[0]/2  ,dim[1]/2], $
			[dim[0]-1  ,dim[1]-1]]
	qloc[*,*,2] =  [[0         ,0       ], $
			[dim[0]/2-1,dim[1]/2-1]]
	qloc[*,*,3] =  [[dim[0]/2  ,0       ], $
			[dim[0]-1  ,dim[1]/2-1]]
	rot =  [[0,5,7,2],$
		[5,0,2,7],$
		[7,2,0,5],$
		[2,7,5,0]]
	IF inst NE 'HRIIR' THEN $
		shft = [[0 , 1, 1, 1],$
			[-1, 0,-1,-1],$
			[ 1, 1, 0, 1],$
			[-1,-1,-1, 0]] $
	ELSE shft = intarr(4,4)
	
ENDELSE

;; Zero all the missing pixels
IF n_elements(flags) GT 0 THEN BEGIN
	missLoc = where((flags AND FLAG_GAP) NE 0,missCnt)
	IF (missCnt GT 0) THEN out[missLoc] = 0
ENDIF

;; Generate the cross talk image
ximg = dblarr(dim[0],dim[1])
FOR i=0,qcnt-1 DO BEGIN ;; Loop through quadrants to build
	curQuad = dblarr(dim[0]/2,dim[1]*2/qcnt)
	FOR j=0, qcnt-1 DO BEGIN ;; Loop through quadrants to add ghosts of
		;; Extract the quadrant to make image of
		tmp = out[qloc[0,0,j]:qloc[0,1,j],qloc[1,0,j]:qloc[1,1,j]]
		
		;; Scale the quadrant by the appropriate gain
		tmp = poly(tmp,gains[j,i,*])

		;; Rotate and shift the quadrant
		curQuad = curQuad + shift(rotate(tmp, rot[j,i]),shft[j,i])
	ENDFOR
	ximg[qloc[0,0,i]:qloc[0,1,i],qloc[1,0,i]:qloc[1,1,i]] = curQuad
ENDFOR

;; Subtract the crosstalk image
out = out - ximg

;; Put back original data from missing pixels
IF n_elements(flags) GT 0 THEN BEGIN
	IF (missCnt GT 0) THEN out[missLoc] = in[missLoc]
ENDIF

;; Update the FITS header
fxaddpar, fitsHdr, 'XTALK', 'T'
fxaddpar, fitsHdr, 'XTALKFN', $
	strupcase(strmid(fn1[0], strpos(fn1[0], path_sep(), /reverse_search)+1))

RETURN, out			
END