;+
; Read RBSP eclipse flag, where 1 is for during eclipse (Umbra and Penumbra).
;
; time. A time or a time range in ut time. Set time to find files
;   automatically, or set files to read data in them directly.
; id=. A string sets the data type to read. Check supported ids by setting
;   print_datatype.
; print_datatype=. A boolean. Set to print all supported ids.
; probe=. A string set the probe to read data for.
; local_root=. A string to set the local root directory.
; remote_root=. A string to set the remote root directory.
; local_files=. A string or an array of N full file names. Set to fine
;   tuning the files to read data from.
; file_times=. An array of N times. Set to fine tuning the times of the files.
; version=. A string to set specific version of files. By default, the
;   program finds the files of the highest version.
;-

pro rbsp_read_eclipse_flag_gen_file, time, probe=probe, filename=data_file, errmsg=errmsg, local_root=local_root
;---Internal, do not check inputs.
    local_root = join_path([default_local_root(),'data','rbsp'])
    remote_root = 'http://rbsp.space.umn.edu/data/rbsp'
    rbspx = 'rbsp'+probe
    paths = ['MOC_data_products',strupcase(rbspx),'eclipse_predict']

    ; Download the index file.
    remote_index_file = join_path([remote_root,paths])+'/'
    local_index_file = join_path([local_root,paths,default_index_file()])
    download_file, local_index_file, remote_index_file

    ; Find all related pecl files.
    lines = read_all_lines(local_index_file)
    file_pattern = '"'+rbspx+'_'+time_string(time[0],tformat='YYYY')+'_[0-9]{3}_[0-9]{2}.pecl"'
    pos = stregex(lines, file_pattern)
    index = where(pos ne -1)
    ; To include the previous file.
    if index[0] ge 1 then begin
        previous_index = index[0]-1
        previous_line = lines[previous_index]
        if stregex(previous_line, file_pattern) ne -1 then index = [previous_index,index]
    endif
    files = lines[index]
    nfile = n_elements(files)
    file_pattern = '"'+rbspx+'_[0-9]{4}_[0-9]{3}_[0-9]{2}.pecl"'
    length = 22
    for ii=0,nfile-1 do files[ii] = strmid(files[ii],stregex(files[ii],file_pattern)+1, length)

    ; Sync the pecl files with server.
    foreach file, files do begin
        local_file = join_path([local_root,paths,file])
        remote_file = join_path([remote_root,paths,file])
        download_flag = 0
        finfo = file_info(local_file)
        rinfo = get_remote_info(remote_file)
        if finfo.size ne rinfo.size then download_flag = 1
        if download_flag then download_file, local_file, remote_file, errmsg=errmsg
        if finfo.mtime ne rinfo.mtime then ftouch, local_file, mtime=mtime
    endforeach

    ; Read eclipse times.
    min_line = 6     ; files contains eclipse time are at least 7 lines.
    header_line = 6
    time_ranges = list()
    foreach file, files do begin
        local_file = join_path([local_root,paths,file])
        nline = file_lines(local_file)
        if nline le min_line then continue  ; no eclipse.
        lines = read_all_lines(local_file)
        lines = lines[header_line:*]
        nline = n_elements(lines)
        foreach tline, lines do begin
            tmp = strsplit(tline, ' ', /extract)
            t1 = strjoin(tmp[1:4], ' ') & if strlen(tmp[1]) eq 1 then t1 = ' '+t1
            t2 = strjoin(tmp[5:8], ' ') & if strlen(tmp[5]) eq 1 then t2 = ' '+t2
            time_range = time_double([t1,t2],tformat='DD MTH YYYY hh:mm:ss.fff')
            time_ranges.add, time_range
        endforeach
    endforeach
    time_ranges = transpose(time_ranges.toarray())  ; in [2,n].
    ntime_range = n_elements(time_ranges[0,*])

    ; Combine to the overall times.
    data_rate = 60. ; sec.
    year = fix(time_string(time[0],tformat='YYYY'))
    full_time_range = time_double([string(year,format='(I4)'),string(year+1,format='(I4)')])
    common_times = smkarthm(full_time_range[0], full_time_range[1]-data_rate*0.5, data_rate, 'dx')
    ncommon_time = n_elements(common_times)
    eclipse_flags = intarr(ncommon_time)
    for ii=0, ntime_range-1 do begin
        the_time_range = time_ranges[*,ii]
        the_time_range = the_time_range-(the_time_range mod data_rate)
        if (time_ranges[1,ii] mod data_rate) eq 0 then the_time_range[1] += data_rate
        index = lazy_where(common_times, '[]', the_time_range, count=count)
        if count eq 0 then continue
        eclipse_flags[index] = 1
    endfor

;---Write to file.
    pre0 = 'rbsp'+probe+'_'
    odir = fgetpath(data_file)
    if file_test(odir,/directory) eq 0 then file_mkdir, odir
    offn = data_file
    if file_test(offn) eq 1 then file_delete, offn  ; overwrite old files.

    ginfo = {$
        title: 'RBSP flag to tell if spacecraft is in eclipse or not',$
        text: 'Generated by Sheng Tian at the University of Minnesota'}
    scdfwrite, offn, gattribute=ginfo

    ; utsec.
    utname = 'ut_flag'
    ainfo = {$
        fieldnam: 'UT time', $
        units: 'sec', $
        var_type: 'support_data'}
    scdfwrite, offn, utname, value=common_times, attribute=ainfo, cdftype='CDF_DOUBLE'

    ; eclipse_flag.
    varname = 'eclipse_flag'
    tdat = eclipse_flags
    ainfo = {$
        fieldnam: 'Eclipse flag: 1 for in eclipse', $
        units: '#', $
        var_type: 'data', $
        depend_0: utname}
    scdfwrite, offn, varname, value=tdat, attribute=ainfo

end

pro rbsp_read_eclipse_flag, time, id=datatype, probe=probe, $
    print_datatype=print_datatype, errmsg=errmsg, $
    local_files=files, file_times=file_times, version=version, $
    local_root=local_root, remote_root=remote_root

    compile_opt idl2
    on_error, 0
    errmsg = ''

;---Check inputs.
    sync_threshold = 0
    if n_elements(probe) eq 0 then begin
        errmsg = handle_error('no probe ...')
        return
    endif
    index = where(probe eq ['a','b'])
    if index[0] eq -1 then begin
        errmsg = handle_error('invalid probe ...')
        return
    endif
    if n_elements(local_root) eq 0 then local_root = join_path([default_local_root(),'sdata','rbsp'])
    if n_elements(version) eq 0 then version = 'v01'

;---Init settings.
    type_dispatch = hash()
    valid_range = ['2012','2020']
    rbspx = 'rbsp'+probe
    base_name = rbspx+'_eclipse_flag_%Y_'+version+'.cdf'
    local_path = [local_root,rbspx,'flags','eclipse']

    type_dispatch['all'] = dictionary($
        'pattern', dictionary($
            'local_file', join_path([local_path,base_name]), $
            'local_index_file', join_path([local_path,default_index_file()])), $
        'valid_range', time_double(valid_range), $
        'cadence', 'year', $
        'extension', fgetext(base_name), $
        'var_list', list($
            dictionary($
                'in_vars', ['eclipse_flag'], $
                'out_vars', rbspx+'_'+['eclipse_flag'], $
                'time_var_name', 'ut_flag', $
                'time_var_type', 'unix')))

    if keyword_set(print_datatype) then begin
        print, 'Suported data type: '
        ids = type_dispatch.keys()
        foreach id, ids do print, '  * '+id
        return
    endif

;---Dispatch patterns.
    datatype = 'all'
    request = type_dispatch[datatype]

;---Find files, read variables, and store them in memory.
    files = prepare_files(request=request, errmsg=errmsg, local_files=files, $
        file_times=file_times, time=time, nonexist_files=nonexist_files)
    if n_elements(nonexist_files) ne 0 then begin
        foreach file, request.nonexist_files do begin
            file_time = file.file_time
            local_file = file.local_file
            rbsp_read_eclipse_flag_gen_file, file_time, probe=probe, filename=local_file, local_root=local_root
        endforeach
        files = prepare_files(request=request, errmsg=errmsg, local_files=files, $
            file_times=file_times, time=time, nonexist_files=nonexist_files)
    endif

;---Read data from files and save to memory.
    read_files, time, files=files, request=request

end

rbsp_read_eclipse_flag_gen_file, time_double('2013-01-01'), probe='a'
end
