;***************************************************************************** 
;+
;*NAME:
;
;	marker_search
;
;*PURPOSE:
;
;	Find the first marker in the data file and 
;	return the byte number of the beginning of that marker.
;
;*CALLING SEQUENCE:
;
;	marker_search,lun,sync_pattern,after_byte,found_byte,/debug
;
;*PARAMETERS:
;
;	lun  (required) (input) (integer) (scalar)
;	   Open file unit
;
;       sync_pattern  (required) (input) (scalar) (string - hex)
;	   The pattern to find.  Hex - include leading zeros.
;
;	after_byte (required) (input) (integer) (scalar)
;	   The byte to start the search after.  If not needed, use 0.
;
;	found_byte (required) (output) (scalar) (long word integer)
;	   The byte number in the file where 
;	      - if no after_byte, the occurance of the pattern starts
;	      - if after_byte set, the next occurance of the pattern starts
;	   If marker not found, equals -1
;
;	debug (keyword) (input) (integer) (scalar)
;	   Set to print out debug information
;
;*EXAMPLES:
;
;	marker_search,lun,'fe6b2840',0,found_byte,/debug
;	marker_search,lun,'fe6b2840',found_byte+1L,found_byte
;
;*SYSTEM VARIABLES USED:
;
;	none
;
;*INTERACTIVE INPUT:
;
;	none
;
;*SUBROUTINES CALLED:
;
;	none
;
;*FILES USED:
;
;	open input file from parameter list
;
;*SIDE EFFECTS:
;
;	Sets input file read pointer to start of file
;
;*RESTRICTIONS:
;
;*NOTES:
;
;	found_byte equals -1 if marker not found
;
;*PROCEDURE:
;
;       - determine size of file
;       - determine length of sync pattern and separate first byte value
;	- If after_byte not equals 0, skip number of bytes.
;	- Until end-of-file or marker is found,
;	  - read a buffer of bytes
;	  - convert the bytes to hex
;	  - check for the start of the marker
;	  - if start of marker is found,
;	    - obtain additional bytes if needed
;           - add leading zeros if necessary
;	    - combine the hex of the neceaary number of bytes
;	    - if equals the marker, return found byte of the marker
;
;*MODIFICATION HISTORY:
;
;	 7 May 2012  PJL  wrote - based on juno_cip_marker_search and
;                         juno_fgm_pkts_search - generalize
;       13 Mar 2013  PJL  before each readu, make sure there are enough bytes
;                         remaining
;        8 Jul 2013  PJL  subtract bytes read from track number
;
;-
;******************************************************************************
 pro marker_search,lun,sync_pattern,after_byte,found_byte,debug=debug

;  check inputs

 if (n_params(0) ne 4) then begin
    print,'marker_search,lun,sync_pattern,after_byte,found_byte,/debug'
    return
 endif  ; n_params(0) ne 4

;  debug flag

  if (keyword_set(debug)) then debug = 1 else debug = 0

;  set pointer to start of file

 point_lun,lun,0

;  determine size of file

 file_info = fstat(lun)
 if (debug) then print,'file_info: ',file_info
 track_number_bytes = file_info.size
 file_number_bytes = file_info.size

;  sync pattern

 sync_length = strlen(sync_pattern)
 sync_bytes = sync_length/2
 if ( sync_bytes ne (sync_length/2.0) ) then begin
    print,'ERROR:  sync pattern is not an even number of bytes'
    print,'ACTION: stop'
    stop
 endif  ; sync_bytes ne (sync_length/2.0)

 if (sync_length gt 2) then   $
    start_sync_pattern = strupcase(strmid(sync_pattern,0,2))   $
 else start_sync_pattern = strupcase(sync_pattern)
 
;  initialize counters

 found_byte = -1L
 reading_buff_length = 36L
;; reading_buff_length = 700L
 reading_buff = bytarr(reading_buff_length)
 byte_count = 0L

;  if need to skip to later in the file (not first packet)

 if (after_byte gt 0L) then begin
    if (track_number_bytes lt after_byte) then begin
       print,'marker_search: not enough bytes remaining'
       print,'ACTION: finish'
       goto, finish
    endif  ; track_number_bytes lt after_byte

    ignore_buff = bytarr(after_byte)
    readu,lun,ignore_buff
    byte_count = byte_count + long(after_byte)
    track_number_bytes = track_number_bytes - after_byte
 endif  ; after_byte gt 0L

;  until eof or find the marker - step through input file

 while ( not(eof(lun)) and (found_byte lt 0) ) do begin

;  read a buffer

    if (track_number_bytes lt reading_buff_length) then begin
       print,'marker_search: not enough bytes remaining'
       print,'ACTION: finish'
       goto, finish
    endif  ; track_number_bytes lt reading_buff_length

    readu,lun,reading_buff
    additional_bytes = 0L
    track_number_bytes = track_number_bytes - reading_buff_length

;  convert to hex

    hex = byte(string(reading_buff,'(z)'))
    hex = strupcase(strtrim(hex(5:6,*),2))

;  search for start of marker

    sync_index = where(strupcase(hex) eq start_sync_pattern,sync_index_ct)

;  if start of marker is found

    if (sync_index_ct ge 1) then begin
       j = 0

;  for each start byte found ...

       while ( (j lt sync_index_ct) and (found_byte lt 0) ) do begin

;  determine if additional bytes are needed

          additional_bytes =   $
             -1 * (reading_buff_length - sync_index[j] - sync_bytes)

;  if there were additional bytes needed, piece together the bytes

          if (additional_bytes gt 0) then begin
             if (track_number_bytes lt additional_bytes) then begin
                print,'marker_search: not enough bytes remaining'
                print,'ACTION: finish'
                goto, finish
             endif  ; track_number_bytes lt additional_bytes

             temp_buff = bytarr(additional_bytes)
             readu,lun,temp_buff
             track_number_bytes = track_number_bytes - additional_bytes
             temp_hex = byte(string(temp_buff,'(z)'))
             temp_hex = strupcase(strtrim(temp_hex(5:6,*),2))
             new_hex = strarr(reading_buff_length + additional_bytes)
             new_hex[0L:reading_buff_length-1L] = hex[0L:reading_buff_length-1L]
             new_hex[reading_buff_length:reading_buff_length+additional_bytes-1L] = temp_hex
             hex = new_hex
;             byte_count = byte_count + additional_bytes
             if (debug) then begin 
                print,'additional_bytes = ',additional_bytes
                print,j, sync_index[j],hex[sync_index[j]:*]
             endif  ; debug
          endif else additional_bytes = 0L

;  create the hex - based on length of marker string

          working_hex = ''
          for k=0L,sync_bytes-1L do begin
	     temphex = hex[sync_index[j]+k]
             while(strlen(temphex) lt 2) do temphex = '0' + temphex
             working_hex = working_hex + temphex
          endfor  ; k
          if (debug) then begin
             print,'working_hex = ', working_hex
             print,'sync_index[' + strtrim(j,2) + '] = ',sync_index[j]
          endif  ; debug

;  compare hex value with marker

          if (working_hex eq strupcase(sync_pattern)) then   $
             found_byte = byte_count + long(sync_index[j])
          if (debug) then begin
             print,'byte_count = ',byte_count
             print,'found_byte = ', found_byte
          endif  ; debug

          j = j + 1

       endwhile  ; (j le sync_index_ct) and (found_byte lt 0)
    endif  ; sync_index_ct ge 1

;  update location in file

    byte_count = byte_count + reading_buff_length + long(additional_bytes)
    if (debug) then print,'bytes count, buff, additional = ',   $
       byte_count,reading_buff_length,additional_bytes

 endwhile  ; not(eof(lun)) and (found_byte lt 0)

 finish:

;  set pointer to start of file

 point_lun,lun,0

 return
 end  ; marker_search