unit Expform;
{ -------------------------------------------
  General purpose data file export dialog box
  -------------------------------------------}

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls;

type
  TExportFormat = (FloatingPointFormat,IntegerFormat) ;
  TExportFrm = class(TForm)
    GroupBox1: TGroupBox;
    ckChannel0: TCheckBox;
    ckChannel1: TCheckBox;
    ckChannel2: TCheckBox;
    ckChannel3: TCheckBox;
    ckChannel4: TCheckBox;
    ckChannel5: TCheckBox;
    GrpRecords: TGroupBox;
    edRecRange: TEdit;
    rbAllRecords: TRadioButton;
    rbRange: TRadioButton;
    GrpFormat: TGroupBox;
    rbTabText: TRadioButton;
    rbInteger: TRadioButton;
    rbFloat: TRadioButton;
    bOK: TButton;
    bCancel: TButton;
    rbpClamp: TRadioButton;
    rbCED: TRadioButton;
    ckTime: TCheckBox;
    edStatus: TEdit;
    procedure bOKClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure rbTabTextClick(Sender: TObject);
    procedure rbpClampClick(Sender: TObject);
    procedure rbIntegerClick(Sender: TObject);
  private
    { Private declarations }
    procedure EnableChannels( State : Boolean ) ;
    procedure ConvertWCPToTabText( FileName : string;
                                   RecStart, RecEnd : LongInt ;
                                   UseTime : Boolean ;
                                   UseChannel : Array of Boolean ) ;
    procedure ConvertWCPToBinary( FileName : string;
                                  RecStart, RecEnd : LongInt ;
                                  UseTime : Boolean ;
                                  UseChannel : Array of Boolean ;
                                  ExportFormat : TExportFormat ) ;
  public
    { Public declarations }
    ExportFileName : string ;
  end;

var
   ExportFrm : TExportFrm ;


implementation

{$R *.DFM}

uses convert,global,fileio,shared,log ;

procedure TExportFrm.FormShow(Sender: TObject);
{ -----------------------------------------
  Initialise control when form is displayed
  -----------------------------------------}
begin

     { Match the number of channel selection check boxes to the no. of channels
       and select all available channels }

     ckChannel0.Visible := True ;
     ckChannel0.Checked := True ;
     if FH.NumChannels >= 2 then begin
        ckChannel1.Visible := True ;
        ckChannel1.Checked := True ;
        end ;
     if FH.NumChannels >= 3 then begin
        ckChannel2.Visible := True ;
        ckChannel2.Checked := True ;
        end ;
     if FH.NumChannels >= 4 then begin
        ckChannel3.Visible := True ;
        ckChannel3.Checked := True ;
        end ;
     if FH.NumChannels >= 5 then begin
        ckChannel4.Visible := True ;
        ckChannel4.Checked := True ;
        end ;
     if FH.NumChannels >= 6 then begin
        ckChannel5.Visible := True ;
        ckChannel5.Checked := True ;
        end ;

     { Set range of records to be exported }
     rbAllRecords.checked := True ;
     edRecRange.text := format( '1-%d', [FH.NumRecords] ) ;

     Caption := 'Export to ' + ExportFileName ;

     end;


procedure TExportFrm.bOKClick(Sender: TObject);
{ --------------------------
  OK ... Export data to file
  --------------------------}
var
   Rec,RecStart,RecEnd : LongInt ;
   ch : Integer ;
   UseChannel : Array[0..ChannelLimit] of Boolean ;
begin

      { Get range of records to be exported }
      if rbAllRecords.Checked then begin
         RecStart := 1 ;
         RecEnd := FH.NumRecords ;
         end
      else GetIntRangeFromEditBox(edRecRange,RecStart,RecEnd,1,FH.NumRecords) ;

      { Get channels to be exported }
      for ch := 0 to ChannelLimit do UseChannel[ch] := False ;
      if ckChannel0.checked and ckChannel0.visible then UseChannel[0] := True ;
      if ckChannel1.checked and ckChannel1.visible then UseChannel[1] := True ;
      if ckChannel2.checked and ckChannel2.visible then UseChannel[2] := True ;
      if ckChannel3.checked and ckChannel3.visible then UseChannel[3] := True ;
      if ckChannel4.checked and ckChannel4.visible then UseChannel[4] := True ;
      if ckChannel5.checked and ckChannel5.visible then UseChannel[5] := True ;

      WriteToLogFile( format( 'File : %s', [FH.FileName] )) ;

      { Export to an Axon ABF format file }
     if rbpClamp.checked then ConvertWCPTopClamp( ExportFileName ) ;
     { Export to an ASCII tab text file }
     if rbTabText.checked then ConvertWCPToTabText( ExportFileName,
                                                    RecStart,RecEnd,
                                                    ckTime.Checked,UseChannel) ;
     { Export to a 16 bit integer binary file }
     if rbInteger.checked then  ConvertWCPToBinary( ExportFileName,
                                RecStart, RecEnd,
                                ckTime.Checked, UseChannel, IntegerFormat ) ;
     { Export to a single precision floating point file }
     if rbFloat.checked then    ConvertWCPToBinary( ExportFileName,
                                RecStart, RecEnd,
                                ckTime.Checked, UseChannel, FloatingPointFormat ) ;

     end ;


procedure TExportFrm.ConvertWCPToTabText( FileName : string;
                                          RecStart, RecEnd : LongInt ;
                                          UseTime : Boolean ;
                                          UseChannel : Array of Boolean ) ;

{ -------------------------------------------------
  Convert a WCP data file to a Tab Text format file
  -------------------------------------------------}
var
   Rec,nWritten : LongInt ;
   i,j,ch : Integer ;
   y : single ;
   s : string ;
   F : TextFile ;
   Buf : ^TIntArray ;
   RH : ^TRecHeader ;

begin
     try
        { Create buffers }
        New(RH) ;
        New(Buf) ;
        { Create file to hold exported data }
        AssignFile( F, FileName ) ;
        Rewrite(F) ;

        { Write records to the data file }
        nWritten := 0 ;
        for Rec := RecStart to RecEnd do begin

            { Read record from WCP file }
            GetRecord( FH, rH^, Rec, Buf^ ) ;

            Application.ProcessMessages ;
            edStatus.text := format( '%d/%d', [Rec,RecEnd]) ;

            { Only export, if it is accepted }
            if rH^.Status = 'ACCEPTED' then begin

               Inc( nWritten ) ;

               for i := 0 to FH.NumSamples-1 do begin
                   s := '' ;
                   if UseTime then s := format( '%.4g', [i*rH^.dt] ) ;
                   for ch := 0 to FH.NumChannels-1 do
                       if UseChannel[Ch] then begin
                          j := i*FH.NumChannels + Channel[ch].ChannelOffset ;
                          y := (Buf^[j]-Channel[ch].ADCZero)*Channel[ch].ADCScale ;
                          s:= s + chr(9) + format( '%.4g',[y] ) ;
                          end ;
                   WRiteLn( F, s ) ;
                   end ;
               end ;
            end ;

        finally
               WriteToLogFile(format('Exported to %s', [FileName] )) ;
               WriteToLogFile(format('%d records written in Tab Text format',
                                                 [nWritten] )) ;
               CloseFile(F) ;
               Dispose(Buf) ;
               Dispose(RH) ;
               end ;
     end ;


procedure TExportFrm.ConvertWCPToBinary( FileName : string;
                                        RecStart, RecEnd : LongInt ;
                                        UseTime : Boolean ;
                                        UseChannel : Array of Boolean ;
                                        ExportFormat : TExportFormat ) ;
{ --------------------------------------------------------------------------
  Convert a WCP data file to a binary format file (integer or floating point)
  --------------------------------------------------------------------------}
var
   Rec,nw,nWritten : LongInt ;
   iy : Smallint ;
   i,j,ch : Integer ;
   t,y : single ;
   FileHandle : Integer ;
   Buf : ^TIntArray ;
   RH : ^TRecHeader ;

begin
     try
        { Create buffers }
        New(RH) ;
        New(Buf) ;
        { Create file to hold exported data }
        FileHandle := FileCreate( FileName ) ;

        { Write records to the data file }
        nWritten := 0 ;
        for Rec := RecStart to RecEnd do begin

            Application.ProcessMessages ;
            edStatus.text := format( '%d/%d', [Rec,RecEnd]) ;

            { Read record from WCP file }
            GetRecord( FH, rH^, Rec, Buf^ ) ;

            { Only export, if it is accepted }
            if rH^.Status = 'ACCEPTED' then begin
               Inc( nWritten ) ;
               for i := 0 to FH.NumSamples-1 do begin
                   { Note. Time channel only available for floating point format }
                   if UseTime and (ExportFormat = FloatingPointFormat) then begin
                      t := i*rH^.dt ;
                      nw := FileWrite( FileHandle, t, SizeOf(t) ) ;
                      end ;
                   for ch := 0 to FH.NumChannels-1 do
                       if UseChannel[Ch] then begin
                          j := i*FH.NumChannels + Channel[ch].ChannelOffset ;
                          if ExportFormat = FloatingPointFormat then begin
                             { Write 4 byte floating point }
                             y := (Buf^[j]-Channel[ch].ADCZero)*Channel[ch].ADCScale ;
                             nw := FileWrite( FileHandle, y, SizeOf(t) ) ;
                             end
                          else begin
                             { Write 2 byte integer }
                             iy := Buf^[j] ;
                             nw := FileWrite( FileHandle, iy , SizeOf(iy) )
                             end ;
                          end ;
                   end ;
               end ;
            end ;

        finally
               WriteToLogFile(format('Exported to %s', [FileName] )) ;
               if ExportFormat = FloatingPointFormat then
                  WriteToLogFile(format('%d records written in floating point format.',
                                    [nWritten] ))
               else
                  WriteToLogFile(format('%d records written in integer format.',
                                    [nWritten] )) ;
               FileClose(FileHandle) ;
               Dispose(Buf) ;
               Dispose(RH) ;
               end ;
     end ;


procedure TExportFrm.rbTabTextClick(Sender: TObject);
begin
     EnableChannels( True ) ;
     end;


procedure TExportFrm.rbpClampClick(Sender: TObject);
{ --------------------------------------------------------
  Enable all channels, if exporting to an Axon or CED file
  -------------------------------------------------------- }
begin
     ckTime.checked := True ;
     ckChannel0.checked := True ;
     if FH.NumChannels >=2 then ckChannel1.checked := True ;
     if FH.NumChannels >=3 then ckChannel2.checked := True ;
     if FH.NumChannels >=4 then ckChannel3.checked := True ;
     if FH.NumChannels >=5 then ckChannel4.checked := True ;
     if FH.NumChannels >=6 then ckChannel5.checked := True ;
     { Disable any changes to channels }
     EnableChannels ( False ) ;
     end;


procedure TExportFrm.EnableChannels( State : Boolean ) ;
{ ------------------------------------------------------
  Enable/disable changes to channel selected check boxes
  ------------------------------------------------------}
begin
     ckTime.Enabled := State ;
     ckChannel0.Enabled := State ;
     ckChannel1.Enabled := State ;
     ckChannel2.Enabled := State ;
     ckChannel3.Enabled := State ;
     ckChannel4.Enabled := State ;
     ckChannel5.Enabled := State ;
     end ;

procedure TExportFrm.rbIntegerClick(Sender: TObject);
{ ---------------------------------------------
  Time channel not available for integer output
  ---------------------------------------------}
begin
     EnableChannels( True ) ;
     ckTime.Checked := False ;
     ckTime.Enabled := False ;
     end;

end.
