c          
c     
c                            
c
c     Copyright by Dwight Meglan 1990
c
c     Purpose: This the main subroutine to control all exporting of data calculated
c              in ANZ. Exporting means to write the data out as simple ASCII text
c              which can then be read by other programs for further analysis. This
c              information cannot be read back into ANZ. There are three common options
c              that are available in most export quantities:
c              EXP/INC=#    :  set the frame increment- /INC=2 will save every other frame
c              EXP/IGO      :  include text in file to make data read easily into IGOR
c              EXP/NOH      :  don't include any descriptive header text in file
c
c              The increment option is good for shrinking the size of files when alot of
c              the information is not needed- like with force data sample at 500 Hz during
c              normal gait and only every 10th frame is needed. The igor option is to
c              make it easier to use the exported data with a program that I frequently
c              use on the Macintosh by the name of IGOR. It is a wonderful scientific 
c              analysis and display program by Wavemetrics that is much more appropriate
c              for playing with data than trying to use a spreadsheet or graphing program
c              like Kaliedagraph. The last option makes the result data files easy to read
c              by most spreadsheet programs that do not have the intelligence to skip
c              the comments at the beginning of the file. Unfortunately, the resulting files
c              are completely devoid of descriptions so you had better know what is in
c              files later on...  The normal export mode places a descriptive in the 
c              file.
c
      Subroutine ExportData( CMND,MF,SF,JF,FF,
     &                       AF,CF,EF,OF )
      implicit none
                             
      include 'a_struct.inc'

      record /CmndLine/       CMND
      record /marker_flag/    MF
      record /segment_flag/   SF
      record /force_flag/     FF      
      record /joint_flag/     JF
      record /avg_pos_flag/   AF                                   
      record /cycle_flag/     CF
      record /emg_flag/       EF
      record /option_flag/    OF

      integer*4 inc
      logical*4 IgorHeader,RegHeader
      
      integer*4 i
 
      if ( CMND.NumCmnd .lt. 3 ) goto 1000 ! error
c
c      check for options to EXP command which are applicable to all
c      export quantities: /INC=# set frame increment
c                         /IGO   include information to make Igor MAC file
c                         /NOH   do not include any header information
c
      inc= 1
      IgorHeader= .false.
      RegHeader=  .true.
      if ( CMND.NumOpt(1) .gt. 0 ) then
        do i= 1, CMND.NumOpt(1)
          if ( CMND.OptText(i,1) .eq. 'INC' ) then
            if ( (.not. CMND.OptNumOK(1,1)) .or.
     &           (CMND.OptIntVal(1,1) .lt. 1)    ) goto 1020 ! error
            inc= CMND.OptIntVal(1,1)
            call RemoveCmndOpt( CMND,1,i )
          else if ( CMND.OptText(i,1) .eq. 'IGO' ) then
            IgorHeader= .true.
            RegHeader=  .false.
            call RemoveCmndOpt( CMND,1,i )
          else if ( CMND.OptText(i,1) .eq. 'NOH' ) then
            IgorHeader= .false.
            RegHeader=  .false.  
            call RemoveCmndOpt( CMND,1,i )
          else
            goto 1010 ! error
          end if
        end do
      end if
      
      if ( CMND.CmndText(2) .eq. 'MRK' ) then
        call ExportMrk( CMND,inc,RegHeader,IgorHeader,MF,OF )

      else if ( CMND.CmndText(2) .eq. 'SEG' ) then
        call ExportSeg( CMND,inc,RegHeader,IgorHeader,
     &                  SF,MF,OF )
 
      else if ( CMND.CmndText(2) .eq. 'FRC' ) then
        call ExportFrc( CMND,inc,RegHeader,IgorHeader,
     &                  FF,SF,OF )

      else if ( CMND.CmndText(2) .eq. 'JNT' ) then
        call ExportJnt( CMND,inc,RegHeader,IgorHeader,
     &                  JF,SF,CF,OF )

      else if ( CMND.CmndText(2) .eq. 'AVG' ) then
        call ExportAvg( CMND,RegHeader,AF,OF )

      else if ( CMND.CmndText(2) .eq. 'CYC' ) then
        call ExportCyc( CMND,RegHeader,CF,OF )

      else if ( CMND.CmndText(2) .eq. 'REC' ) then
        call ExportRec( CMND,inc,RegHeader,IgorHeader,FF,OF )

      else if ( CMND.CmndText(2) .eq. 'EMG' ) then
        call ExportEMG( CMND,inc,RegHeader,IgorHeader,EF,OF )

      else if ( CMND.CmndText(2) .eq. 'HIS' ) then
        call ExportHistory( CMND,OF )

      else
        write(6,100) CMND.CmndText(2)
        if ( OF.ToLog ) write(3,100) CMND.CmndText(2)
100     format(' Error- ',a3,' is not a valid EXPort command.'/
     &         '         Available commands are: MaRKer  SEGment FoRCe'/
     &         '                                 JoiNT   AVeraGe '/
     &         '                                 REConstructGRL  HIStory')
      end if
      return
                                 
1000  write(6,1005)
      if ( OF.ToLog ) write(3,1005)
1005  format(' Error- EXPort data requires more than two command words.')
      return

1010  write(6,1015) CMND.OptText(i,1)
      if ( OF.ToLog ) write(3,1015) CMND.OptText(i,1)
1015  format(' Error- ',a3,' is not a valid EXPort command option'/
     &       '        Valid options are: /INC=#  /IGOr  /NOHeader')
      return

1020  write(6,1025)
      if ( OF.ToLog ) write(3,1025)
1025  format(' Error- The frame increment option must be a number >0')
      return
      end
c                                                                   
c             
c             
c
c     Copyright by Dwight Meglan 1990
c
c     Purpose: Dump the history of the commands used to calculate the present
c              state of the analysis to a text file
c
c
      subroutine ExportHistory( CMND,OF )
      implicit none
                               
      include 'a_const.inc'                              
      include 'a_struct.inc'
      include 'a_prm.inc'

      record /CmndLine/     CMND
      record /option_flag/  OF

      integer*4 i,j,start
      character LineText*80
      logical*4 OpenTextFile

      LineText= CMND.Text(1)  
      Start= CMND.CmndStart(3)
      if ( .not. OpenTextFile(LineText,Start,.true.) ) goto 1000 ! error
      do i= 1, History(1).NumHistory
        do j= 1, History(i).NumLine
          write(2,100) History(i).Line(j)     
100       format(1x,a20)
        end do 
      end do
      return

1000  write(6,1005) 
      if ( OF.ToLog ) write(3,1005)
1005  format(' Error- File could not be opened')        
      end
c                                                                   
c             
c             
c
c     Copyright by Dwight Meglan 1990
c
c     Purpose: Write out the average segment position/orientation, joint angles, or
c              segment reference information to a text file.
c
      subroutine ExportAvg( CMND,RegHeader,AF,OF )
      implicit none
                               
      include 'a_const.inc'                              
      include 'a_struct.inc'
      include 'a_prm.inc'
      include 'a_names.inc'
      include 'a_seg.inc'
      include 'a_jnt.inc'
                        
      record /CmndLine/     CMND
      record /avg_pos_flag/ AF
      record /option_flag/  OF

      logical*4 RegHeader
      
      real*4    LabRM(3,3),angle(3)
      integer*4 i,j,k,ierr,seg,jnt,start
      logical*4 UseRM,OpenTextFile
      character LineText*80
      
      data LabRM / 1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0 /

      if ( CMND.CmndText(3) .eq. 'POS' ) then
        if ( .not. AF.position ) goto 1000
        UseRM= .false.
        if ( CMND.NumOpt(3) .ne. 0 ) then
          if ( CMND.OptText(1,3) .eq. 'MAT' ) then
            UseRM= .true.
          else 
            goto 1020 ! error
          end if
        end if
        LineText= CMND.Text(1)  
        Start= CMND.CmndStart(4)
        if ( .not. OpenTextFile(LineText,Start,.true.) ) goto 1080 ! error
        if ( RegHeader ) then
          if ( UseRM ) then 
            write(2,100)
100         format(' Average Segment position and orientation'//
     &             ' Segment',12x,'X',23x,'Y',23x,'Z',23x,'CNTR(m)'/
     &             '  Name',4x,4('X',7x,'Y',7x,'Z',7x)/)
          else
            write(2,110)
110         format(' Average Segment position and orientation'//
     &             ' Segment',12x,'CNTR(m)',12x,'Angle(deg)'/
     &             '  Name',4x,'X',7x,'Y',7x,'Z',7x,
     &                         'Y',7x,'X',7x,'Z'/)
          end if
        end if ! print header...
        if ( UseRM ) then
          do i= 1, GP.num_seg
            seg= GP.seg_num(i)
            write(2,120) seg_names(seg),
     &                   ((SgpAvg(j,k,seg),j=1,3),k=1,4)
120         format(1x,a4,12(1x,e13.5))
          end do
        else     
          do i= 1, GP.num_seg
            seg= GP.seg_num(i)
            call RotMattoJcsAng( SgpAvg(1,1,seg),angle,ierr )
            write(2,130) seg_names(seg),
     &                   (SgpAvg(j,4,seg),j=1,3),
     &                   (angle(j),j=1,3)
130         format(1x,a4,6(1x,e13.5))
          end do
        end if
        close(unit=2)

      else if ( CMND.CmndText(3) .eq. 'JAN' ) then 
        if ( .not. AF.angle_JCS ) goto 1030
        LineText= CMND.Text(1)  
        Start= CMND.CmndStart(4)
        if ( .not. OpenTextFile(LineText,Start,.true.) ) goto 1080 ! error
        if ( RegHeader ) write(2,140)
140     format(' Average JCS Joint angle (deg)'//
     &         ' Joint',6x,'Flex/Ext',6x,'Ab/Ad',6x,'Int/Ext'/)
        do i= 1, GP.num_jnt
          jnt= GP.jnt_num(i)
          write(2,150) jnt_names(jnt),
     &                 (JangAvgJCS(j,jnt),j=1,3)
150       format(1x,a4,3(1x,e13.5))
        end do
        close(unit=2)

      else if ( CMND.CmndText(3) .eq. 'REF' ) then 
        if ( .not. AF.RefCorrectAng ) goto 1040 ! error
        LineText= CMND.Text(1)  
        Start= CMND.CmndStart(4)
        if ( .not. OpenTextFile(LineText,Start,.true.) ) goto 1080 ! error
        write(2,170)
170     format(' Segment reference orientation correction transformation angles'/
     &         ' Segment',10x,'Reference Angles (deg)'/
     &         10x,'Y',9x,'X',9x,'Z',5x//)
        do i= 1, GP.num_seg
          seg= GP.seg_num(i)
          write(2,180) seg_names(seg),
     &                 (SgpRefCorAng(j,seg),j=1,3)
180       format(2x,a4,3x,3e13.5)  
        end do
        close(unit=2)
        
      else ! error
        write(6,160) CMND.CmndText(3)
        if ( OF.ToLog ) write(3,160) CMND.CmndText(3)
160     format(' Error- ',a3,' is not a valid EXP AVG command'/
     &         '        Valid commands are: POS JAN REF')
      end if
      return      

1000  write(6,1005)                                      
      if ( OF.ToLog ) write(3,1005)
1005  format(' Error- Segment average position has not been calculated yet')        
      return

1020  write(6,1025) CMND.OptText(1,3)
      if ( OF.ToLog ) write(3,1025) CMND.OptText(1,3)
1025  format(' Error- ',a3,' is not a valid option for EXP AVG POS'/
     &       '        Valid option is /MATrix')        
      return

1030  write(6,1035)                                      
      if ( OF.ToLog ) write(3,1035)
1035  format(' Error- Joint average angle has not been calculated yet')        
      return

1040  write(6,1045)                                      
      if ( OF.ToLog ) write(3,1045)
1045  format(' Error- Segment reference orientation correction has not been calculated yet')        
      return

1080  write(6,1085)                                      
      if ( OF.ToLog ) write(3,1085)
1085  format(' Error- File could not be opened')        
      return
      end
c
c                              
c
c
c     Copyright by Dwight Meglan 1990
c
c     Purpose: Write the time-distance parameter information for the gait cycle
c              to a text file.
c
c
      subroutine ExportCyc( CMND,RegHeader,CF,OF )
      implicit none

      include 'a_const.inc'
      include 'a_struct.inc'
      include 'a_prm.inc'
      include 'a_names.inc'

      record /CmndLine/    CMND
      record /cycle_flag/  CF
      record /option_flag/ OF

      logical*4 RegHeader

      integer*4 i,start
      real*4    feet,inch
      logical*4 OpenTextFile
      character LineText*80
                       
      data feet,inch / 3.2808,39.3696 /     ! conversion ft/m, in/m
                 
      if ( .not. CF.event ) goto 1000
      LineText= CMND.Text(1)  
      Start= CMND.CmndStart(3)
      if ( .not. OpenTextFile(LineText,Start,.true.) ) goto 1080 ! error
        write(2,205) GP.name,GP.age,
     &               GP.weight,GP.height,
     &               GP.comment
205     format(/' Name   : ',a40/
     &          ' Age    : ',i4/
     &          ' Weight : ',f8.3,' kg'/
     &          ' Height : ',f8.3,' m'/
     &          ' Comment: ',a80//)
      write(2,190) ( MP.rhs_frm(i),i= 1, MP.num_rhs )
190   format(' Cycle event frame #''s'//
     &       ' Right heel strike : ',5(i3,1x) )
      write(2,200) ( MP.lhs_frm(i),i= 1, MP.num_lhs )
200   format(' Left heel strike  : ',5(i3,1x) )
      write(2,210) ( MP.rto_frm(i),i= 1, MP.num_rto )
210   format(' Right toe off     : ',5(i3,1x) )
      write(2,220) ( MP.lto_frm(i),i= 1, MP.num_lto )
220   format(' Left toe off      : ',5(i3,1x) )
      write(2,223) MP.first_frm
223   format(/' First motion frame absolute frame # : ',i3/)
      if ( CF.statistics ) then
        write(2,8) CP.velocity,          CP.velocity*feet,
     &           CP.velocity*inch,
     &           CP.NormVelocity,      CP.PctNormVelocity,
     &           CP.stride_length,     CP.stride_length*feet,
     &           CP.stride_length*inch,
     &           CP.NormStrideLength,  CP.PctNormStrideLength,
     &           CP.step_length(rt),   CP.step_length(rt)*feet,
     &           CP.step_length(rt)*inch,
     &           CP.NormStepLength(rt),CP.PctNormStepLength(rt),
     &           CP.step_length(lf),   CP.step_length(lf)*feet,
     &           CP.step_length(lf)*inch,
     &           CP.NormStepLength(lf),CP.PctNormStepLength(lf),
     &           CP.step_width,        CP.step_width*feet,
     &           CP.step_width*inch,
     &           CP.NormStepWidth,     CP.PctNormStepWidth,
     &           CP.cadence,        
     &           CP.NormCadence,       CP.PctNormCadence
8       format(/16x,'meters',8x,'feet',8x,'inches',6x,'Normal(m)',3x,'% Normal'//
     &       ' Velocity   : ',5(f8.3,5x)/
     &       ' Stride     : ',5(f8.3,5x)/
     &       ' R Step     : ',5(f8.3,5x)/
     &       ' L Step     : ',5(f8.3,5x)/          
     &       ' Step Width : ',5(f8.3,5x)//
     &       ' Cadence    : ',f8.3,' step/min',22x,2(f8.3,5x)/)
        write(2,10) CP.total_time(rt),CP.total_percent(rt),
     &            CP.NormTotalPct(rt),
     &            CP.total_time(lf),CP.total_percent(lf),
     &            CP.NormTotalPct(lf),
     &            CP.sgl_time(rt),  CP.sgl_percent(rt),
     &            CP.NormSglPct(rt),
     &            CP.sgl_time(lf),  CP.sgl_percent(lf),
     &            CP.NormSglPct(lf),
     &            CP.dbl_time(rt),  CP.dbl_percent(rt),
     &            CP.NormDblPct(rt),
     &            CP.dbl_time(lf),  CP.dbl_percent(lf),
     &            CP.NormDblPct(lf)
10      format('            Time (s)        Percent Cycle        Normal'/
     &       ' R TLST  ',3(f8.3,11x)/
     &       ' L TLST  ',3(f8.3,11x)/
     &       ' R SLST  ',3(f8.3,11x)/
     &       ' L SLST  ',3(f8.3,11x)/
     &       ' R DLS   ',3(f8.3,11x)/
     &       ' L DLS   ',3(f8.3,11x)/)       
        if ( CP.first_side .eq. rt ) then
          write(2,12) CP.HS_percent(1),CP.NormHsPct(1),
     &              CP.TO_percent(1),CP.NormToPct(1),
     &              CP.HS_percent(2),CP.NormHsPct(2),
     &              CP.TO_percent(2),CP.NormToPct(2),
     &              CP.HS_percent(3),CP.NormHsPct(3)
12       format(' RHS                        ',f8.3,11x,f8.3/
     &       ' LTO                        ',f8.3,11x,f8.3/
     &       ' LHS                        ',f8.3,11x,f8.3/
     &       ' RTO                        ',f8.3,11x,f8.3/
     &       ' RHS                        ',f8.3,11x,f8.3/ )
        else
          write(2,14) CP.HS_percent(1),CP.NormHsPct(1),
     &              CP.TO_percent(1),CP.NormToPct(1),
     &              CP.HS_percent(2),CP.NormHsPct(2),
     &              CP.TO_percent(2),CP.NormToPct(2),
     &              CP.HS_percent(3),CP.NormHsPct(3)
14       format(' LHS                        ',f8.3,11x,f8.3/
     &       ' RTO                        ',f8.3,11x,f8.3/
     &       ' RHS                        ',f8.3,11x,f8.3/
     &       ' LTO                        ',f8.3,11x,f8.3/
     &       ' LHS                        ',f8.3,11x,f8.3/ )
        end if ! first_side
      else
        write(2,290)
290     format(/' Cycle Statistics not calculated.')
      end if ! Statistics present
      close(unit=2)
      return

1000  write(6,1005)                                      
      if ( OF.ToLog ) write(3,1005)
1005  format(' Error- Cycle gait events have not been input yet')        
      return

1080  write(6,1085)                                      
      if ( OF.ToLog ) write(3,1085)
1085  format(' Error- File could not be opened')        
      return
      end
c
c                              
c
c
c     Copyright by Dwight Meglan 1990
c
c     Purpose: Write the reconstructed ground reaction load data to a text
c
c
      subroutine ExportRec( CMND,inc,RegHeader,IgorHeader,FF,OF )
      implicit none

      include 'a_const.inc'
      include 'a_struct.inc'
      include 'a_prm.inc'
      include 'a_names.inc'
      include 'a_gls2.inc'
      include 'a_frc.inc'

      record /CmndLine/    CMND
      record /force_flag/  FF
      record /option_flag/ OF

      integer*4 inc
      logical*4 IgorHeader,RegHeader
      
      real*4    TimeInc
      integer*4 CSType,NumCmnd,Start,i,j,k,side
      logical*4 ExpComb,ExpFoot,OpenTextFile
      character CompName(12)*11,LoadName(6)*2,UnitName(2)*3,
     &          DirName(3)*1,CS*1,LineText*80
      
      data LoadName / 'Fx','Fy','Fz','Mx','My','Mz' /
      data DirName,UnitName / 'x','y','z','N ','Nm' /

      if ( .not. FF.Reconstructed ) goto 1000
      if ( (CMND.CmndText(3) .ne. 'GRL') .and.
     &     (CMND.CmndText(3) .ne. 'CPR') .and.
     &     (CMND.CmndText(3) .ne. 'SI ')       ) goto 1010
c
c     Figure whether combined or individual foot data to be exported
c     if GRL or CPR commands are present
c     
      NumCmnd= 4
      if ( (CMND.CmndText(3) .eq. 'GRL') .or.
     &     (CMND.CmndText(3) .eq. 'CPR')      ) then
        NumCmnd= 5
        ExpComb= .false.
        ExpFoot= .false.
        if ( CMND.CmndText(4) .eq. 'COM' ) then
          ExpComb= .true.
        else if ( CMND.CmndText(4) .eq. 'FT ' ) then
          ExpFoot= .true.
        else
          goto 1020
        end if
        if ( ExpFoot ) then ! check for Coord System option
          CSType= GCS_CS
          CS= 'G'
          if ( CMND.NumOpt(4) .gt. 0 ) then
            if ( CMND.NumOpt(4) .gt. 1 ) goto 1030 ! error
            if ( CMND.OptText(1,4) .eq. 'GCS' ) then
              CSType= GCS_CS
              CS= 'G'
            else if ( CMND.OptText(1,4) .eq. 'LCS' ) then
              CSType= LCS_CS
              CS= 'L'
            else
              goto 1040 ! error - bad option
            end if
          end if
        end if ! check coord system option
      end if ! CMND = GRL or CPR
c
c     Open file for output
c
      LineText= CMND.Text(1)  
      Start= CMND.CmndStart(NumCmnd)
      if ( .not. OpenTextFile(LineText,Start,.true.) ) goto 1050 ! error
c
c     Now export it !
c
      TimeInc= 1.0/float(FP.frm_rate)
      if ( CMND.CmndText(3) .eq. 'GRL' ) then
        if ( IgorHeader ) then
          if ( ExpComb ) then
            do i= 1, 6
              CompName(i)= 'RecGrlCb'//LoadName(i)//'G'
            end do
            write(2,100) (CompName(i),i=1,6)
100         format(' IGOR'/
     &             ' WAVES ',5(a11,', '),a11/
     &             ' BEGIN'/)
            do i= 1, FP.nfrm, inc
              write(2,110) (rCmbGrl(j,i),j=1,6)
110           format(2x,6(e13.5,1x))
            end do
            write(2,119)
119         format(' END')
            do i= 1, 3
              write(2,120) TimeInc,CompName(i),UnitName(1),CompName(i)
            end do
            do i= 4, 6
              write(2,120) TimeInc,CompName(i),UnitName(2),CompName(i)
            end do
120         format(' X SetScale /P x 0,',f10.6,',"sec", ',a11/
     &             ' X SetScale y 0,0,"',a2,'", ',a11/ )
          else ! ExpFoot
            do side= rt, lf
              if ( side .eq. rt ) then
                do i= 1, 6
                  CompName(i)= 'RecGrlFr'//LoadName(i)//CS
                end do
                write(2,100) (CompName(i),i=1,6)
              else
                do i= 1, 6
                  CompName(i)= 'RecGrlFl'//LoadName(i)//CS
                end do
                write(2,125) (CompName(i),i=1,6)
125             format(/' WAVES ',5(a11,', '),a11/' BEGIN'/)
              end if
              do i= 1, FP.nfrm, inc
                if ( CSType .eq. GCS_CS ) then
                  write(2,110) (rFtGrlGCS(j,i,side),j=1,6)
                else
                  write(2,110) (rFtGrlLCS(j,i,side),j=1,6)
                end if
              end do
              write(2,119)
              do i= 1, 3
                write(2,120) TimeInc,CompName(i),UnitName(1),CompName(i)
              end do
              do i= 4, 6
                write(2,120) TimeInc,CompName(i),UnitName(2),CompName(i)
              end do
            end do ! side
          end if ! ExpComb or ExpFoot
        else ! regular export of GRL
          if ( RegHeader ) then
            if ( ExpComb ) then
              write(2,130)
130           format(' Reconstructed Combined GRL (N, Nm)'//
     &               ' Frame',6x,'Fx',11x,'Fy',11x,'Fz',
     &                       11x,'Mx',11x,'My',11x,'Mz'/)
            else ! ExpFoot
              if ( CSType .eq. GCS_CS ) then
                write(2,140)
140             format(' Reconstructed Foot GRL relative to GCS (N, Nm)'/)
                write(2,150)
150             format(' Frame',5x,'RtFx',9x,'RtFy',9x,'RtFz',
     &                          9x,'RtMx',9x,'RtMy',9x,'RtMz',
     &                          5x,'LfFx',9x,'LfFy',9x,'LfFz',
     &                          9x,'LfMx',9x,'LfMy',9x,'LfMz'/)
              else ! LCS_CS
                write(2,160)
160             format(' Reconstructed Foot GRL relative to Foot LCS (N, Nm)'/)
                write(2,150)
              end if
            end if ! ExpComb or ExpFoot
          end if ! print header...
          if ( ExpComb ) then
            do i= 1, FP.nfrm, inc
              write(2,170) i,(rCmbGrl(j,i),j=1,6)
170           format(2x,i4,2x,6(e13.5,1x))
            end do
          else ! ExpFoot
            do i= 1, FP.nfrm, inc
              if ( CSType .eq. GCS_CS ) then
                write(2,180) i,((rFtGrlGCS(j,i,k),j=1,6),k=1,2)
180             format(2x,i4,2x,12(e13.5,1x))
              else
                write(2,180) i,((rFtGrlLCS(j,i,k),j=1,6),k=1,2)
              end if
            end do
          end if ! regular export of ExpComb or ExpFoot
        end if ! Igor or Regular export of REC GRL
        
      else if ( CMND.CmndText(3) .eq. 'CPR' ) then
        if ( IgorHeader ) then
          if ( ExpComb ) then
            do i= 1, 3
              CompName(i)= 'RecCprCb'//DirName(i)//'G'
            end do
            write(2,200) (CompName(i),i=1,3)
200         format(' IGOR'/
     &             ' WAVES ',2(a10,', '),a10/
     &             ' BEGIN'/)
            do i= 1, FP.nfrm, inc
              write(2,210) (rCmbCp(j,i),j=1,3)
210           format(2x,3(e13.5,1x))
            end do
            write(2,219)
219         format(' END')
            do i= 1, 3
              write(2,220) TimeInc,CompName(i),CompName(i)
            end do
220         format(' X SetScale /P x 0,',f10.6,',"sec", ',a10/
     &             ' X SetScale y 0,0,"m", ',a10/ )
          else ! ExpFoot
            do side= rt, lf
              if ( side .eq. rt ) then
                do i= 1, 3
                  CompName(i)= 'RecCprFr'//DirName(i)//CS
                end do
                write(2,200) (CompName(i),i=1,3)
              else
                do i= 1, 3
                  CompName(i)= 'RecCprFl'//DirName(i)//CS
                end do
                write(2,225) (CompName(i),i=1,3)
225             format(/' WAVES ',2(a10,', '),a10/' BEGIN'/)
              end if
              do i= 1, FP.nfrm, inc
                if ( CSType .eq. GCS_CS ) then
                  write(2,210) (rFtCpGCS(j,i,side),j=1,3)
                else
                  write(2,110) (rFtCpLCS(j,i,side),j=1,3)
                end if
              end do
              write(2,219)
              do i= 1, 3
                write(2,220) TimeInc,CompName(i),CompName(i)
              end do
            end do ! side
          end if ! ExpComb or ExpFoot
        else ! regular export of REC CPR
          if ( RegHeader ) then
            if ( ExpComb ) then
              write(2,230)
230           format(' Reconstructed Combined Center of Pressure (m)'//
     &               ' Frame',6x,'x',11x,'y',11x,'z')
            else ! ExpFoot
              if ( CSType .eq. GCS_CS ) then
                write(2,240)
240             format(' Reconstructed Foot Center of Pressure relative to GCS (m)'/)
                write(2,250)
250             format(' Frame',5x,'Rtx',10x,'Rty',10x,'Rtz',
     &                         10x,'Lfx',10x,'Lfy',10x,'Lfz'/)
              else ! LCS_CS
                write(2,260)
260             format(' Reconstructed Foot Center of Pressure relative to Foot LCS (m)'/)
                write(2,250)
              end if
            end if ! ExpComb or ExpFoot
          end if ! print header...
          if ( ExpComb ) then
            do i= 1, FP.nfrm, inc
              write(2,270) i,(rCmbCp(j,i),j=1,3)
270           format(2x,i4,2x,3(e13.5,1x))
            end do
          else ! ExpFoot
            do i= 1, FP.nfrm, inc
              if ( CSType .eq. GCS_CS ) then
                write(2,280) i,((rFtCpGCS(j,i,k),j=1,3),k=1,2)
280             format(2x,i4,2x,6(e13.5,1x))
              else
                write(2,280) i,((rFtCpLCS(j,i,k),j=1,3),k=1,2)
              end if
            end do
          end if ! regular export of ExpComb or ExpFoot
        end if ! Igor or regular export of REC CPR

      else ! REC SI
        if ( IgorHeader ) then
          write(2,310) 
310       format(' IGOR'/
     &           ' WAVES RecFsiR, RecFsiL'/
     &           ' BEGIN')
          do i= 1, FP.nfrm, inc
            write(2,320) (rStrIdx(i,j),j=1,2)
320         format(2x,2(e12.4))
          end do
          write(2,330) ((TimeInc),i=1,2)
330       format(' END'/
     &           ' X SetScale /P x 0,',f10.6,',"sec", RecFsiR'/
     &           ' X SetScale y 0,0,"m", RecFsiR'/
     &           ' X SetScale /P x 0,',f10.6,',"sec", RecFsiL'/
     &           ' X SetScale y 0,0,"m", RecFsiL')
        else ! regular foot REC SI export
          if ( RegHeader ) write(2,340) 
340       format(' Reconstructed Strike Index for feet'//
     &           ' Frame      Right     Left'/)
          do i= 1, FP.nfrm, inc
            write(2,350) i,(rStrIdx(i,j),j=1,2)
350         format(2x,i4,2x,2f11.4)
          end do
        end if ! Igor or Regular export of REC SI
      end if
      close(unit=2)
      return
      
1000  write(6,1005)
      if ( OF.ToLog ) write(3,1005)
1005  format(' Error- GRL has not been reconstructed yet')
      return

1010  write(6,1015) CMND.CmndText(3)
      if ( OF.ToLog ) write(3,1015) CMND.CmndText(3)
1015  format(' Error- ',a3,' is not a valid EXP REC command'/
     &       '        Valid commands are: GRL CPR SI')
      return

1020  write(6,1025) CMND.CmndText(4),CMND.CmndText(3)
      if ( OF.ToLog ) write(3,1025) CMND.CmndText(4),CMND.CmndText(3)
1025  format(' Error- ',a3,' is not a valid EXP REC ',a3,' command'/
     &       '        Valid commands are: COM FT')
      return

1030  write(6,1035) CMND.NumOpt(4)
      if ( OF.ToLog ) write(3,1035) CMND.NumOpt(4)
1035  format(' Error- There are ',i1,' options present for the FT command'/
     &       '        but only a single option is available ([GCS],LCS)')
      return

1040  write(6,1045) CMND.OptText(1,4),CMND.CmndText(3)
      if ( OF.ToLog ) write(3,1045) CMND.OptText(1,4),CMND.CmndText(3)
1045  format(' Error- ',a3,' is not a valid option for EXP REC ',a3,' FT'/
     &       '        Valid option is ([GCS],LCS)')
      return

1050  write(6,1055)
      if ( OF.ToLog ) write(3,1055)
1055  format(' Error- File could not be opened')
      return
      end
c
c
c
c
c     Copyright by Dwight Meglan 1990
c
c     Purpose: Write the EMG data to a text file
c
c
      subroutine ExportEMG( CMND,inc,RegHeader,IgorHeader,EF,OF )
      implicit none
      include 'a_const.inc'

      include 'a_struct.inc'
      include 'a_prm.inc'
      include 'a_emg.inc'

      record /CmndLine/    CMND
      record /emg_flag/    EF
      record /option_flag/ OF

      integer*4 inc
      logical*4 IgorHeader,RegHeader

      real*4    TimeInc
      integer*4 i,j,Start,len,numfrm,LogtoInt
      character EMGType(2)*7,LineText*80,chnum(12)*2,IgorText*120
      logical*4 OpenTextFile 
                 
      data EMGType / 'Surface','Wire   ' /
      
      data chnum / '1 ','2 ','3 ','4 ','5 ','6 ',
     &             '7 ','8 ','9 ','10','11','12'  /

      if ( .not. EF.read ) goto 1000
      LineText= CMND.Text(1)
      Start= CMND.CmndStart(3)
      numfrm= EP.NumSamples
      if ( EP.NumSamples .gt. MAX_EMF ) numfrm= MAX_EMF 
      if ( .not. OpenTextFile(LineText,Start,.true.) ) goto 1010
      if ( IgorHeader ) then
        do i= 1, 80
          IgorText(i:i)= ' '
        end do
        Len= 0
        do i= 1, EP.NumChnl-1
          IgorText(Len+1:Len+7)= 'Emg'//chnum(i)//', '
          Len= Len+7                                             
        end do
        IgorText(Len+1:Len+5)= 'Emg'//chnum(EP.NumChnl)
        Len= Len+5
        write(2,100) IgorText
100     format(' IGOR'/
     &         ' WAVES ',a120/
     &         ' BEGIN')
        do i= 1, numfrm, inc
          write(2,110) (EMGData(i,j),j=1,EP.NumChnl)
110       format(2x,12(e13.5,1x))
        end do     
        TimeInc= 1.0/float(EP.SampleRate)
        write(2,115)
115     format(' END')
        do i= 1, EP.NumChnl
          write(2,120) TimeInc,chnum(i),chnum(i)
120       format(' X SetScale /P x 0,',f10.6,',"sec", Emg',a2/
     &           ' X SetScale y 0,0,"V", Emg',a2 )
        end do                       
      else ! regular text export
        if ( RegHeader ) then
          if ( EF.Maximum ) then
            write(2,201) EP.SampleRate
201         format(' EMG SampleRate : ',i5,' Hz'//
     &             ' Chnl#   Maximum     Type     Name'/)
            do i= 1, EP.NumChnl
              write(2,211) i,float(EP.CodeNum(i))/1000.0,
     &                     EMGType(LogtoInt(EP.Surface(i))+1),EP.Name(i)
211           format(3x,i2,6x,e13.5,5x,a7,3x,a20)
            end do ! i
          else
            write(2,200) EP.SampleRate
200         format(' EMG SampleRate : ',i5,' Hz'//
     &             ' Chnl#   Code#   Type     Name'/)
            do i= 1, EP.NumChnl
              write(2,210) i,EP.CodeNum(i),EMGType(LogtoInt(EP.Surface(i))+1),
     &                     EP.Name(i)
210           format(3x,i2,6x,i2,5x,a7,3x,a20)
            end do ! i
          end if      
          write(2,220) (i,i= 1, EP.NumChnl)
220       format(//' Sample # ',16(5x,i2,5x) )
        end if ! print header...
        do i= 1, numfrm, inc
          write(2,230) i,(EMGData(i,j),j=1,EP.NumChnl)
230       format(2x,i5,12(1x,e13.5))
        end do          
      end if                  
      close(unit=2)
      return                                    
      
1000  write(6,1005)           
      if ( OF.ToLog ) write(3,1005)
1005  format(' Error - No EMG data has been read in yet')
      return

1010  write(6,1015)                 
      if ( OF.ToLog ) write(3,1015)
1015  format(' Error- File could not be opened')        
      return
      end
c              
c                       
c
c
c     Copyright by Dwight Meglan 1990
c
c     Purpose : Determine whether a valid segment name has been given and if so
c               then return the array index number corresponding to it
c
c
      logical*4 function GetSegNum( Text,SegNum )
      implicit none
      include 'a_const.inc'
                 
      include 'a_struct.inc'
      include 'a_prm.inc'

      integer*4 SegNum,i,j                                     
      character Text*3,SegNamesA(15)*3,SegNamesB(15)*3
      logical*4 SegFound

      data SegNamesA / 'RTF','RTC','RTT','LFF','LFC','LFT','PEL','TRN',
     &                 'RTU','RTL','LFU','LFL','HEA','RTH','LFH' /

      data SegNamesB / 'RFT','RCF','RTH','LFT','LCF','LTH','PLV','TRK',
     &                 'RUA','RLA','LUA','LLA','HED','RHD','LHD' /
                                     
      GetSegNum= .false.
      j= 1
      SegFound= .false.
      do while ( (j .le. 15) .and. (.not. SegFound) )
        if ( (Text .eq. SegNamesA(j)) .or. (Text .eq. SegNamesB(j)) ) then
          SegFound= .true.
        else
          j= j + 1      
        end if
      end do
      if ( SegFound ) then
        SegNum= j
        i= 1
        do while ( (i .le. GP.num_seg) .and. (.not. GetSegNum) )
          if ( SegNum .eq. GP.seg_num(i) ) GetSegNum= .true.
          i= i + 1
        end do
      end if            
      return
      end
c
c                          
c
c
c     Copyright by Dwight Meglan 1990
c
c     Purpose : Determine whether a valid joint name has been given and if so
c               then return the array index number corresponding to it
c
c
      logical*4 function GetJntNum( Text,JntNum )
      implicit none
      include 'a_const.inc'
              
      include 'a_struct.inc'
      include 'a_prm.inc'

      integer*4 JntNum,i,j                          
      character Text*3,JntNamesA(15)*3,JntNamesB(15)*3
      logical*4 JntFound

      data JntNamesA / 'RTA','RTK','RTH','LFA','LFK','LFH','PVL','PVT',
     &                 'RTE','RTS','LFE','LFS','NEC','RTW','LFW' /

      data JntNamesB / 'RAK','RKN','RHP','LAK','LKN','LHP','PVL','PVT',
     &                 'REL','RSH','LEL','LSH','NEC','RWR','LWR' /

      GetJntNum= .false.
      j= 1
      JntFound= .false.
      do while ( (j .le. 15) .and. (.not. JntFound) )
        if ( (Text .eq. JntNamesA(j)) .or. (Text .eq. JntNamesB(j)) ) then
          JntFound= .true.
        else      
          j= j + 1      
        end if
      end do
      if ( JntFound ) then
        JntNum= j
        i= 1
        do while ( (i .le. GP.num_jnt) .and. (.not. GetJntNum) )
          if ( JntNum .eq. GP.jnt_num(i) ) GetJntNum= .true.
          i= i + 1
        end do
      end if            
      return
      end     
c                             
c
c               
c
c     Copyright by Dwight Meglan 1990
c
c     Purpose : Determine whether a valid marker number has been given
c
c
      logical*4 function GetMrkNum(Text,Num,Mrk,All)
      implicit none
      
      include 'a_const.inc'
      include 'a_struct.inc'
      include 'a_prm.inc'
      
      integer*4 Num,Mrk,i
      character Text*4,MrkText*4
      logical*4 All
      
      GetMrkNum= .false.
      All= .false.
      if ( Text .eq. 'ALL' ) then
        All= .true.
        GetMrkNum= .true.
        return                  
      end if
      do i= 1, MP.num_mrk
        MrkText= MP.mrk_name(i)
        call MakeUpperCase(MrkText)
        if ( Text .eq. MrkText ) then
          Mrk= i
          GetMrkNum= .true.
          return
        end if
      end do
      if ( (Num .gt. 0) .and. (Num .le. MP.num_mrk) ) then
        Mrk= Num
        GetMrkNum= .true.
      end if
      return
      end
c                             
c
c               
c
c     Copyright by Dwight Meglan 1990
c
c     Purpose: Identify the type of coordinate system indicated by the string
c              and return the id code number
c
c     Types of coordinate systems
c      Global (GCS)        - 1
c      Local Segment (LCS) - 2
c      Proximal Segment    - 3
c      Distal Segment      - 4
c      Joint (JCS)         - 5
c      Euler (EUL)         - 6
c                       
c
      logical*4 function GetCSType(NumOpt,Text,CSType)
      implicit none

      integer*4 CSType,i,j,NumOpt
      character Text(5)*3,CSTypeNames(6)*3

      data CSTypeNames / 'GCS','LCS','PRO','DIS','JCS','EUL' /

      GetCSType= .false.                    
      j= 1                                                               
      do while ( (j .le. NumOpt) .and. (.not. GetCSType) )
        i= 1
        do while ( (i .le. 6) .and. (.not. GetCSType) )
          if ( Text(j) .eq. CSTypeNames(i) ) then
            CSType= i
            GetCSType= .true.
          end if
          i= i + 1
        end do
        j= j + 1
      end do
      return
      end
c                         
c
c
c
c     Copyright by Dwight Meglan 1990
c
c     Purpose: Open a text file to receive the exported ANZ data. Note that there
c              is commented code here for using the program with the Language Systems
c              fortran compiler on the Macintosh. This was added to make it easier to
c              target what folder the files would be saved into on the macintosh when
c              I was experimenting with the program.
c
      logical*4 function OpenTextFile( Text,pos,New )
      implicit none
      
      integer*4 pos
      logical*4 New
      character text*(*)
                                       
      integer*4 length,ierr,i,jvrefnum,MaxChr
      character filename*60,extension*3,NewOrOld*3
      logical*4 GetFileName

      NewOrOld= 'old'
      if ( New ) NewOrOld= 'new'
      OpenTextFile= .false.
      if ( pos .eq. 0 ) goto 1000 ! no filename
c																	! MAC
c     The following is applicable to the macintosh version only		! MAC
c      																! MAC
c      if ( text(pos:pos) .eq. '*' ) then							! MAC
c        open( unit=2,file=*,type=NewOrOld,recl=512,					! MAC
c     &        creator='TCEd',filetype='TEXT',iostat=ierr,err=1010 )	! MAC
c        OpenTextFile= .true.										! MAC
c        i= jvrefnum(2)
c        call f_setvolume(i)								! MAC
c        return														! MAC									! MAC
c      end if														! MAC
c
c     VAX and Mac version
c
      if ( .not. GetFileName(text,pos,filename,extension,length) ) return
      if ( index(filename(1:length),'.') .eq. 0 )
     &  filename= filename(1:length)//'.txt'
c      open( unit=2,file=filename,type=NewOrOld,recl=512,			! MAC
c     &      creator='TCEd',filetype='TEXT',err=1010,iostat=ierr )	! MAC
      if ( .not. New ) then
        open( unit=2,file=filename,status='old',recl=512,
     &        carriagecontrol='none',err=1010,iostat=ierr )
      else
        open( unit=2,file=filename,status='unknown',recl=512,
     &        err=1010,iostat=ierr )
      end if
      OpenTextFile= .true.
      return

1000  write(6,1005)
1005  format(' Error- No file name present')
      return

1010  write(6,1015) ierr,filename
1015  format(' Error- Error # ',i4,' occurred while opening ',a60)
      return
      end                                   
                          
