!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! DEMO - Spectral Dynamics NeXtMidas Demo Macro
! @author Jeff Schoen, Jeanette McCall
! @since 3.9.0 added extra waveforms and features
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
startmacro/msgid=main

  res oldLookAndFeel env.theme
  lookandfeel java

  call setDatDir

  invoke GEODETIC nxm.sys.lib.Position.GEODETIC
  invoke tdoamodeList nxm.sys.libg.LayerGeo.tdoamodeList
  invoke fdoamodeList nxm.sys.libg.LayerGeo.fdoamodeList
  call setGeoDefaults

  timex now d:startTime sod=mySod      ! get time in double format and also the seconds of the day
  calc midnite startTime mySod -       ! get time at midnite as a double

  noop ^{datDir}.sv3.prm mysv3.tmp{AUX=RAM,TC=^midnite}   ! create file to animate
  calc initsteps 289 300 * 1000 /
  set step 0
  set move 1

  res plot_theme GEAR4


  res psk_file "^{datDir}.psk_iq_t1000.prm"
  res fm_file  "^{datDir}.fm_capture_t1000.prm"

  pipe init

    ! Change the keyMap to custom settings
    env set KEYMAP {PLOT={LEFT="L",RIGHT="R",in=i,down=d,up=u,out=o}}

    set sr 1e5
    panel/setup/controls=gc/wmsgid=main ! special handling of window messages

    ! waveform input -> psd, waveform -> demod - controls allow all types of WAVEFORM output
    waveform/rt/id=waveform _waveform{ps=32k} shape=sin form=cf elem=inf amp=32e3 freq=sr/10 delta=1/sr
    fft/psd/log _waveform _wavepsd nfft=1k
    demod/lut _waveform _wavedemod{ps=32k} mode=fm

    ! file with phase modulation -> psd, file with phase modulation -> demod
    noop/rt/wrap/id=psk psk_file _pskwave{ps=32k}
    fft/psd/log _pskwave _pskpsd nfft=1k 
    demod/lut _pskwave _pskdemod{ps=32k} mode=fm

    ! file containing capture of fm data
    noop/rt/wrap/id=fm fm_file _fmwave{ps=32k}
    fft/psd/log _fmwave _fmpsd nfft=1k 
    demod/lut _fmwave _fmdemod{ps=32k} mode=fm

    !
    plot/id=3dplot/theme=plot_theme ^{datDir}.altitude.prm
    plot/id=gplot/theme=plot_theme ^{datDir}.world.prm|^{datDir}.sv1.prm|^{datDir}.sv2.prm|^{datDir}.sv3.prm options=+BStore view=geo
    plot/id=llplot/mousewheelzoom/usemouseposition/theme=plot_theme ^{datDir}.world.shp|^{datDir}.capital_cities.prm|mysv3.tmp{AUX=RAM} view=latloncontinuous

    shellgui/id=term/theme=plot_theme

    plot/id=plotline/theme=plot_theme _fmpsd{XS=1.6253781708804044E8,XD=23.84185791015625} cnt=motion type=line axis=tf 
    feature ,, hilite {NAME=PK,TYPE=DATA|VLINE,COLOR=WHITE,ENABLE=0,X=sr/8,DX=sr/10} plotline

    plot/id=plotpsd/theme=plot_theme _fmpsd cnt=click axis=bf 

    plot/id=plotiq/theme=plot_theme _fmwave{LAYER={Type="Point"}} cm=RvI

    gcontrol label  macro "MACRO" AlwaysOpen
    gcontrol button state "" "Run,Pause,Stop"  1 /lh=40
    gcontrol label  intype "InputSelection"
    gcontrol button source "Source Selection" "Waveform,PSK,FM" "Waveform"
    gcontrol label  wavef "Waveform" 
    gcontrol choice shape "WaveShape" reg.waveform.shapeList sin
    gcontrol dval   sfreq "SineFreq " ,, -1e5 1e5 1e3 /fmt="#0.0# ?Hz" /mon=reg.waveform.freq /slider
    gcontrol dval   cfreq "CentFreq " 0 0 1e9 1e3
    gcontrol dval   filtw "FilterBW " 1e4 0 1e6 1e4 /fmt="0.0 ?Hz"
    gcontrol label  geola "GeoPlotter" Closed
    gcontrol choice view  "ViewPoint" reg.gplot.viewList "Geo"
    gcontrol choice feat  "Feature  " "New,Move,Clear" /tleft
    gcontrol label  demo  "Demodulator" 
    gcontrol button dmod  "" reg.demod.modeList "FM" /nc=4
    gcontrol label  audm  "Audio Mixer" Open
    gcontrol lval   gain  "Gain  " 5 0 10 1 /slider /nonumb
    gcontrol lval   low   "Low   " 5 0 10 1 /slider /nonumb
    gcontrol lval   mid   "Mid   " 5 0 10 1 /slider /nonumb
    gcontrol lval   high  "High  " 5 0 10 1 /slider /nonumb
    gcontrol label  auds  "Audio Spectra" 
    gcontrol panel  apan  "Spectra" 200 100
    gcontrol button pop   "" "Pop" 0 /nostate/nodepress
    gcontrol label  other "Other" 
    gcontrol prompt comm  "Comment" "All Java" 
    gcontrol lval   "CPU" "CPU Use" 0 0 100 1 /gauge
    gcontrol pipemon pmon _wavepsd
    gcontrol button myButt "Times" "Animate,Small,Large"

    ! moving airplane
    res layT5B reg.llplot.layers.mysv3
    set layT5B.line.symbol "Aero"
    set layT5B.line.symbolSize 16

    call initializeLayerGeo

    plot/id=apan/nopushpop/theme=plot_theme _fmdemod{fs=512} type=line axis=frame 
    set this.timer(0) 0.5

    if /server gt 0 then rmif/http /server _waveb

  pipe run
  pipe wait
  pipe off

  lookandfeel oldLookAndFeel

endmacro

!****************************************************************************!
! This is the callback procedure that is automatically called by NeXtMidas
! when there is a (targeted or automatic) message (msg) to send to this macro.
! See the Users's Guide ->Macros ->Messages in Macros section for more details
procedure processMessage m:msg

!say "Msg ^msg.name = ^msg.data from ^msg.fid"
if msg.name eqs "TIMER"
    call movePlane
elseif msg.fid eqs "PANEL"
  if msg.name eqs "STATE"
    pipe ^msg.data
  elseif msg.name eqs "VIEW"
    set reg.gplot.view msg.data
  elseif msg.name eqs "FEAT"
    if msg.data eqs "NEW"
      set l:nfeat reg.gplot.mp.features.getsize+1
      feature ,, ff {NAME=F^nfeat,TYPE=4,X=10,Y=20,DX=2,DY=2,COLOR=red} gplot
    endif
  elseif msg.name eqs "SOURCE"
    res selectedIQ "_waveform{LAYER={Type="Point"}}"
    res selectedPsd "_wavepsd"
    res selectedDemod "_waveDemod{fs=512}"
    if msg.data EQS "PSK" then
      res selectedIQ "_pskwave{LAYER={Type="Point"}}"
      res selectedPsd "_pskpsd"
      res selectedDemod "_pskDemod{fs=512}"
    elseif msg.data EQS "FM" then
      res selectedIQ "_fmwave{LAYER={Type="Point"}}"
      res selectedPsd "_fmpsd"
      res selectedDemod "_fmDemod{fs=512}"
    endif
    message FUNC=send ID=plotLine NAME=OPENFILE INFO=-1 DATA=^selectedPsd
    message FUNC=send ID=plotPSD NAME=OPENFILE INFO=-1 DATA=^selectedPsd
    message FUNC=send ID=apan NAME=OPENFILE INFO=-1 DATA=^selectedDemod
    message FUNC=send ID=plotIQ  NAME=OPENFILE INFO=-1 DATA=^selectedIQ
  elseif msg.name eqs "SHAPE"
    set reg.waveform.shape msg.data
  elseif msg.name eqs "DMOD"
    set reg.demod.mode msg.data
  elseif msg.name eqs "WINDOW" then
    if msg.data eqs "CLOSING" pipe stop
  elseif msg.name eqs "POP" then
    if msg.data eqs "POP" then
      message send apan ,, "POP" -1 "TOGGLE"
      set gc.pop.items "Push"
    else
      message send apan ,, "POP" -1 "TOGGLE"
      set gc.pop.items "Pop"
    endif
  endif

elseif msg.fid eqss "PLOT" then
  set fid msg.fid
  if msg.fid eqs "PLOTLINE"
    set toid "PLOTPSD"
  else
    set toid "PLOTLINE"
  endif
  if msg.name eqs "MARK" or msg.name eqs "POINTER" then
    if msg.fid eqs "PLOTPSD"
      set hilite.x msg.data.x
      set hilite.enable 0x1
    endif
    set reg.waveform.freq msg.data.x
  elseif msg.name eqs "ZOOM" then
    set msg.name "ZOOMX"
    message pass ^toid msg
  elseif msg.name eqs "UNZOOM" then
    message pass ^toid msg
  elseif msg.name eqs "PANXY" then
    pause 0.2
    message prune ,, msg
    set msg.name "PANX"
    message pass ^toid msg
  elseif msg.name eqs "PANX" then
    message pass ^toid msg
  endif

else
  ! say "Unhandled message ^msg.name from ^msg.fid"
endif
return

!******************************************************************************!
! Set the dat directory
!******************************************************************************!
procedure setDatDir
  invoke nxmMajor env.nmversion.subString(0,1)
  invoke major java.lang.Integer.valueOf(nxmMajor)
  if major GE 4 then
    invoke s:datDir           nxm.sys.test.DatLocator.getDatDirLocation()
    invoke s:datDirSlash      nxm.sys.test.DatLocator.getDatDirSlashLocation()
    invoke z:sysDatFull       nxm.sys.test.DatLocator.sysDatFull()
    invoke z:sysTestDatExists nxm.sys.test.DatLocator.sysTestDatExists()
  else
    set s:datDir           "nxm.sys.dat"
    set s:datDirSlash      "nxm/sys/dat"
    set z:sysDatFull       true
    set z:sysTestDatExists false
  endif
return

!******************************************************************************!
! This is the callback procedure that is automatically called by NeXtMidas
! when there is an uncaught exception thrown from commands in this macro
procedure processException m:emsg
  if emsg.data instanceof java.awt.HeadlessException
    if /server gt 0 and /headless isTrue then
      ! ignore exception since BOTH /headless and /server=<port> was specified  
    else ! otherwise stop pipe section and hence the macro 
      warn "No display server! Got error from ^emsg.fid. Stopping macro..."
      pipe stop
    endif
  else 
    warn "Unexpected exception: from ^emsg.fid ^emsg data=^emsg.data"
    if "Trace" SUBS ENV.DEBUG then invoke ,, emsg.data.printStackTrace()
  endif
return
!******************************************************************************!
procedure movePlane
  calc newTime midnite step +
  set layT5B.time newTime
  calc step step initsteps +
  pause .1
  invoke ,, layT5B.refresh()
return
!******************************************************************************!
procedure setGeoDefaults

  set def {}
  set def.tdoaMode "Region"
  set def.tdoa 0
  set def.dtdoa 1e-3

  set def.fdoaMode "Region"
  set def.fdoa 0
  set def.dfdoa 0.01 !!! Changed from 0.1 on 05OCT06 so that the FDOA
                     !!! lines are visible...what I do not know is if
                     !!! I just did not notice they were not there or
                     !!! whether something else had changed that would
                     !!! have affected this.
    
  set def.targetLabel "Target"
  set def.siteLabel   "MYSITE"
  set def.svaLabel    "SVA"
  set def.svbLabel    "SVB"

  set def.gridsizex   32
  set def.gridsizey   22

  set def.conic 1
  set def.targetPos {LAT=5,LON=-100}
  set def.pointPosA {LAT=-75,LON=-75}
  set def.pointPosB {LAT=-45,LON=-45}
  set def.coneangle 1

  set def.flagsStr "ALL"
  set def.predictRef "SITE"

  invoke colorObj nxm.sys.libg.LayerGeo.DEFAULT_HORIZON_COLOR
  invoke def.colorA      nxm.sys.libg.MColor.toString(colorObj)
  invoke def.colorB      nxm.sys.libg.MColor.toString(colorObj)

  invoke colorObj nxm.sys.libg.LayerGeo.DEFAULT_TARGET_COLOR
  invoke def.colorTarget nxm.sys.libg.MColor.toString(colorObj)

  invoke colorObj nxm.sys.libg.LayerGeo.DEFAULT_SITE_COLOR
  invoke def.colorSite   nxm.sys.libg.MColor.toString(colorObj)

  invoke colorObj nxm.sys.libg.LayerGeo.DEFAULT_TDOA_COLOR
  invoke def.colorTDOA  nxm.sys.libg.MColor.toString(colorObj)
  invoke colorObj nxm.sys.libg.LayerGeo.DEFAULT_FDOA_COLOR
  invoke def.colorFDOA  nxm.sys.libg.MColor.toString(colorObj)

return

!******************************************************************************!
procedure initializeLayerGeo

  new nxm.sys.lib.Position(GEODETIC) site
  set site.lat 10
  set site.lon 10
  set site.alt 0
  layer "Geo" geoLayer {NAME=GL,SVA=^{datDir}.sv1.prm,SVB=^{datDir}.sv2.prm,&
                        SVALABEL="^def.svaLabel",SVBLABEL="^def.svbLabel",&
                        SITE=site,SITELABEL="^def.siteLabel",&
                        TARGETLABEL="^def.targetLabel",&
                        CONIC=def.conic,TDOAMODE=def.tdoaMode,FDOAMODE=def.fdoaMode,&
                        FLINKT=1e6,FLINKA=-1e6,FLINKB=-1e6,&
                        FLAGS=^def.flagsStr,PREDICTREFERENCE=def.predictRef,TDOA=^def.tdoa,FDOA=^def.fdoa,&
                        DTDOA=^def.dtdoa,DFDOA=^def.dfdoa} llplot

  timex ssm t
  set geolayer.time ^t

  ! Set the target position
  new nxm.sys.lib.Position(GEODETIC) tPos
  set tPos.lat ^def.targetPos.lat
  set tPos.lon ^def.targetPos.lon
  set geolayer.pos tPos

  ! Set the pointing position A
  new nxm.sys.lib.Position(GEODETIC) pA
  set pA.lat ^def.pointPosA.lat
  set pA.lon ^def.pointPosA.lon
  set geolayer.pointposA pA

  ! Set the pointing position B
  new nxm.sys.lib.Position(GEODETIC) pB
  set pB.lat ^def.pointPosB.lat
  set pB.lon ^def.pointPosB.lon
  set geolayer.pointposB pB
  
return
