;+
; FILE_TOUCH
; Purpose:  Wrapper routine for the "touch" program that sets file modification and access times
; USAGE:
;    file_touch,'foo',systime(1)-300,/mtime   ; sets mod time to 5 minutes ago
; keywords:
;    MTIME    set only modification time
;    ATIME    set only access time
;    VERBOSE  sets VERBOSITY of messages (0: error messages only,  6: lots)
;    TOFFSET set an hour offset for time zones or DST (e.g. +0700, -0300)
; Restrictions:
;   Shell executable "touch" must be in path on local operating system.  This is common on unix systems.
;   Windows executable available from: http://sourceforge.net/projects/unxutils/
;   If the touch executable is not found then no action is taken.
;   Test for executable occurs only once.
;   
;   Time is set in system local time.  Use toffset with get_timezone_offset() if time is a unix time.
;   Example:  file_touch,'foo',systime(1)-300,/mtime ,toffset=time_zone_offset()
;   
;   Warning: This routine will not work with home directories(~/file_name will not work) on linux variants.  The /noshell option to spawn means that it won't expand home directories into full paths
;   
;$LastChangedBy: pcruce $
;$LastChangedDate: 2014-01-23 18:27:14 -0800 (Thu, 23 Jan 2014) $
;$LastChangedRevision: 13998 $
;$URL: svn+ssh://thmsvn@ambrosia.ssl.berkeley.edu/repos/ssl_general/trunk/misc/file_touch.pro $
;-


pro file_touch,file,time,mtime=mtime,atime=atime,no_create=no_create,toffset=toffset,exit_status=status,verbose=verbose,exists=exists

common file_touch_com, touch_init,touch_version

if ~keyword_set(touch_init)  then begin
    spawn,'touch --version',touch_version,touch_error
    if (strpos(strjoin(touch_error),'usage') ne -1 ) then touch_version=1
    touch_init = 1
endif

if arg_present(exists) then begin
  exists = keyword_set(touch_version)
  return
endif

if ~keyword_set(touch_version) then begin
    dprint,verbose=verbose,dlevel=touch_init-1 ,'Executable "touch" not found. Ignoring.'
    touch_init =4
    return
endif else dprint,verbose=verbose,dlevel=4,touch_version

if size(/type,file) ne 7 then begin
    dprint,verbose=verbose,'filename required.'
    return
endif

commands = 'touch'
if keyword_set(mtime) then commands = [commands,'-m']
if keyword_set(atime) then commands = [commands,'-a']
if keyword_set(no_create) then commands = [commands,'-c']

if undefined(toffset) then toffset= '+0'
   
   
if !version.os_family eq 'unix' then begin
   ;;; if keyword_set(tstring) then commands = [commands,'-d',tstring +toffset]       ;;; previous version

   
   if ~undefined(time) then begin    

      ;orphaned code
      ;;;; tstring = time_string(time[0], tformat= 'YYYY-MM-DD hh:mm:ss')   ;+ toffset   ;;; previous version (for -d option)
      tstring = time_string(double(time[0])+double(toffset)*60.*60., tformat='YYYYMMDDhhmm.ss') ;I believe that this version is in error.  It interprets toffset as seconds, when it should be hours(pcruce)
      commands = [commands,"-t",tstring]
      
   endif
 
   commands = [commands,file]
   dprint,verbose=verbose,dlevel=4,commands
   spawn,commands ,/noshell,/stderr,output,exit_status=status
   
endif else if !version.os_family eq 'Windows' then begin
    ;kludge to fix time daylightsaving time error in old version of touch
   ;;;if touch_version[0] eq 'touch (GNU fileutils) 3.16' then begin                  ;;;previous version
      ;;;if isdaylightsavingtime(time[0]) then toffset = ' -60'                      ;;; previous version
   if (strpos(strjoin(touch_version),'fileutils') ne -1 ) && isdaylightsavingtime(time[0]) then begin
     dst_offset = '-1' ;;; going back 1 hour
     dprint,dlevel=3,verbose=verbose,'Correcting for DST error in TOUCH program. offset:"'+dst_offset+'"'
   endif else begin
     dst_offset='+0'
   endelse
   
   ;;;if keyword_set(tstring) then tstring = '-t "' + tstring+toffset + '"' else tstring=''   ;;; previous version
   if ~undefined(time) then begin
     tstring = '-t "' + time_string(double(time[0])+double(toffset)*60.*60.+double(dst_offset)*60.*60., tformat='YYYYMMDDhhmm.ss') + '"' 
     dprint,dlevel=6,verbose=verbose,'tstring=' ,tstring
   endif else begin
     tstring=''
   endelse
   
   filestring = '"' + file + '"'
   command = strjoin([commands,tstring,filestring],' ')
   dprint,verbose=verbose,dlevel=4,command
   spawn,command ,/noshell,/stderr, /hide,output ,exit_status=status
endif

if keyword_set(output) then dprint,dlevel=1,verbose=verbose,output

end

