;+
; Project     : SOHO - CDS     
;                   
; Name        : DEF_CDS_UTPLOT
;               
; Purpose     : Setup x-axis for time plot.
;               
; Explanation : Adjusts relevant x-axis parameters to plot data on a labelled
;               time axis.
;               
; Use         : Usually only from within CDS_UTPLOT.
;    
; Inputs      : None
;               
; Opt. Inputs : None
;               
; Outputs     : Adjusts current copies of global plotting variables
;               
; Opt. Outputs: None
;               
; Keywords    : xrange - array of seconds of time, the limits of which are
;                        taken to define the plotting range.
;
;               xstyle - if = 1 then fixes range to exactly that requested.
;
; Calls       :
;
; Common      : None
;               
; Restrictions: None
;               
; Side effects: Sets global variables.
;               
; Category    : Util, plotting
;               
; Prev. Hist. : Based entirely on SET_UTPLOT by Schwartz, Morrison
;
; Written     : CDS version by C D Pike, RAL, 20-Apr-94
;               
; Modified    : Name change. CDP, 2-Oct-96
;
; Version     : Version 2, 2-Oct-96
;-            

pro  def_cds_utplot,$
                  cds_xoffset=cds_xoffset,$
                  xrange=x,xstyle=xstyle 

;
; save xstyle and load that required
;
xstyle_in = !x.style
!x.style=vcheck(xstyle, !x.style)

;
; check limits of input data 
; (if none was passed then take current plot limits)
;
s_x = size(x) 
if s_x(1) ne 0 then begin 
   if (n_elements(x) eq 2) then begin 
      xmin = x(0)
      xmax = x(1)
   endif else begin
      xmin=min(x)
      xmax=max(x)
   endelse
endif else begin   
   xmin=!x.crange(0)
   xmax=!x.crange(1)
endelse

;
; clear old plot parameters
;
!x.crange=0.
!x.range=0.
!x.tickv=0.
!x.ticks=0.
!x.tickname=0.
!x.minor=0.
!x.range=[xmin,xmax]

;
; do a dummy plot to set the ranges, taking note of axis style required
;

yold = !y
!x.style = !x.style or 4L
!y.style = yold.style or 4L
old_device=!d.(0)
set_plot,'null'
y = findgen(n_elements(x))
plot,x,y,/noerase,/nodata
set_plot,old_device
!y = yold

;
;  reset x style to that on entry (not that requested fore this plot)
;
!x.style = xstyle_in 

;
;  get the plotting range actually used in the dummy plot
;
!x.range = !x.crange
drange   = abs(!x.crange(1)-!x.crange(0))

;
; find appropriate units to have from 2 to 6 tick intervals
;
tick_units=[10^findgen(5)*1.0d-3,10^findgen(4)*.002,10^findgen(4)*.005,$
20.,30.,60.,60.*[2,4,5,6,10,15,20,30,60],3600.*[2.+findgen(5),8.,10.,12.],$
86400.*[findgen(6)+1.,10.,20.,30.,60.]]

;
;  possible time intervals between minor ticks
;
minor_units=[.0001,.0002,.001,.002,.01,.02,.1,.2,1.0,2.0,5.0,10.,20.,60.,$
      120.,300.,600.,3600.,7200.,14400.,3600.*[6.,12.],$
      86400.*[1.,2.,5.,10.]] 

;
; the units should be selected so that there are from 2 to 6 tick intervals
;
;
; is range  < 2 months?

if drange le 62*86400. then begin 
   w_ok=where( (drange/tick_units lt 7) and (drange/tick_units ge 2)) 
   m_ok=max(drange/tick_units(w_ok)) & !C=0
   i_ok=w_ok(!c)
   tick_unit=tick_units(i_ok)
   !x.ticks=drange/tick_unit ;number of tick intervals
;
;which minors divide evenly into major tick intervals
;
   wminors=where( tick_unit mod minor_units eq 0) 
;
;possible #minor intervals
;
   nminors=tick_unit/minor_units(wminors) 
;
;get as close as possible to 4 sub-intervals
;
   test_minors=min(abs(nminors-4)) 
   !x.minor=nminors(!c) &!c=0 ;number of minor tick intervals

;
; set the tick values and names
;
; looking for frac. 
;

   start_off=(min(!x.crange))/tick_unit mod 1.d0 
   tic_n_range=((1.d0-start_off) mod 1. +findgen(!x.ticks+1))*tick_unit $
                + min(!x.crange); + 15019.*86400.d0

endif else begin 
;
; range is > 2 months 
;
   days_month = [0,31,59,90,120,151,181,212,243,273,304,334]
   utyears=86400.d0*365.25*findgen(200)
   iuty=long(utyears/86400.+.5)
;
;  but range < 3 yrs
;
   if drange lt 1096.*86400. then begin 
      tic_n_range=(86400.d0*days_month)#replicate(1.,1,200)+ $
      transpose( (iuty*86400.d0)#replicate(1.,1,12))
      tic_n_range = tic_n_range + 15019.*86400.d0
      for i=1,199,4 do tic_n_range(2,i)=tic_n_range(2:11,i)+86400.d0
;
; approximately one month or more between tick marks
; array tic_n_range has all yy/mm/01 within allowed range
;
      tick_unit=30.d0*86400.d0 
   endif else begin 
;
;  range is >  3 years
;
      tic_n_range=86400.d0*iuty
      tic_n_range = tic_n_range + 15019.*86400.d0
      tick_unit=365.*86400.d0 
     
;
;  range > 25 yrs?
; 
      if drange gt 25.*365.d0*86400.d0 then begin
         tic_n_range=86400.d0*iuty*5.
         tic_n_range = tic_n_range + 15019.*86400.d0
         tick_unit=365.*86400.d0*5. 
      endif
;
;  range > 50 yrs?
;
      if drange gt 50.*365.d0*86400.d0 then begin
         tic_n_range=86400.d0*iuty*10.
         tic_n_range = tic_n_range + 15019.*86400.d0
         tick_unit=365.*86400.d0*10. 
      endif
   endelse
endelse 


;
; Make sure ticks are within range by both methods of time selection
;
; how many possible ticks
;

wyymm=where( (tic_n_range ge min(!x.crange)) and $
             (tic_n_range le max(!x.crange))) 
num_yymm=!err

;
; make sure minor tick marks lie close to month boundaries
;

if drange gt 62*86400. then begin 
;
;number of months/years between ticks
;
   dticks=fix(num_yymm/6.1)+1 
;
;set minor tick marks close to months or years
;
   !x.minor=dticks
;
; use only every dtick month/yr
;
   wyymm=wyymm(where(wyymm mod dticks eq 0))
endif 

;
;  set tick interval and number
;
!x.ticks=n_elements(wyymm)-1 
xtickv=tic_n_range(wyymm)


;
; set the tickname strings
;
for i=0,n_elements(xtickv)-1 do begin
   if (xtickv(i) le max(!x.crange)) then begin
      tt = sec2utc(xtickv(i)+cds_xoffset)
      !x.tickname(i)=utc2str(tt)
;
;  fiddle  (to eliminate spurious 31-Dec entries)
;
      if strmid(!x.tickname(i),5,5) eq '12-31' then begin
         xtickv(i) = xtickv(i) + 86400.d0
         tt = sec2utc(xtickv(i)+cds_xoffset)
         !x.tickname(i)=utc2str(tt)
      endif
;
;  even bigger fiddle on long time base plots which should never have 
;  tick marks labelled 'Dec' something
;
      if drange/86400.d0/365.25 gt 5.0 then begin
         while (strmid(!x.tickname(i),5,2) eq '12') do begin
            xtickv(i) = xtickv(i) + 86400.d0
            tt = sec2utc(xtickv(i)+cds_xoffset)
            !x.tickname(i)=utc2str(tt)
         endwhile
      endif
   endif   
endfor

;
;  determine proper label format
;
;
;SET LABEL FORMAT BASED ON SIZE OF UNITS
;
test_units=[365/2.*86400.,86400.,60.,1., .1, .01,.001]    

;
;  cds format is yyyy-mm-ddThh:mm:ss.xxxZ so transform
;
mon = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
xt = !x.tickname
newxt = strarr(n_elements(xtickv))
for i=0,n_elements(xtickv)-1 do begin
   new = '                                     '
   m = mon(fix(strmid(xt(i),5,2))-1)
   strput,new,strmid(xt(i),8,2),0
   strput,new,'-',2
   strput,new,m,3
   strput,new,'-',6
   strput,new,strmid(xt(i),2,2),7
   strput,new,strmid(xt(i),11,12),10
   newxt(i) = new
endfor

cds_name = !x.tickname
!x.tickname = newxt

if drange/86400.d0/365.25 gt 5.0 then begin
   !x.tickname = strmid(cds_name,0,4)
endif else begin

;
; New Form dd-mmm-yy hh:mm:ss.xxx
;          0123456789012345678901
;
;          * mmm-yy
;                  * dd-mmm
;                        * hh:mm
;                              * mm:ss.x
;                                  * ss.xx
;                                    * ss.xxx
   rhs=       [8,          5,     14, 17, 19, 20, 21]              
   lhs=       [3,          0,     10, 10, 13, 16, 16]             

   wtest=where( tick_unit ge test_units)
   lbl=[lhs(wtest(0)) ,rhs(wtest(0))]

   !x.tickname=strmid(!x.tickname,lbl(0),lbl(1)-lbl(0)+1)
endelse

!x.tickv=xtickv

return

end
