unit date2dec;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  StdCtrls, Buttons, ComCtrls
  , LazFileUtils //required for ExtractFileNameOnly
  ;

type

  { TForm10 }

  TForm10 = class(TForm)
    Memo1: TMemo;
    OpenDialog1: TOpenDialog;
    SourceFileButton: TBitBtn;
    SourceFileEdit: TEdit;
    StartButton: TButton;
    StatusBar1: TStatusBar;
    procedure SourceFileButtonClick(Sender: TObject);
    procedure StartButtonClick(Sender: TObject);
  private

  public

  end;

var
  Form10: TForm10;

implementation

uses
  Unit1
  , strutils
  , appsettings
  , dateutils //Required to convert logged UTC string to TDateTime
  ;

var
  SourcePathFile:String;
  subfix: ansistring; //Used for time zone conversions

{ TForm10 }

procedure TForm10.SourceFileButtonClick(Sender: TObject);
begin
  OpenDialog1.InitialDir:=RemoveMultiSlash(appsettings.LogsDirectory);
  if OpenDialog1.Execute then begin
    SourcePathFile:=OpenDialog1.FileName;
    SourceFileEdit.Text:=SourcePathFile;
  end;
end;

{ Convert file and write to the outputfile.}
procedure TForm10.StartButtonClick(Sender: TObject);
Var
    Infile: TStringList;
    pieces: TStringList;
    OutFile: TextFile;
    ComposeString: String;
    OutputPathFileName, SourceFileName:String;
    WorkingPath, OutputPath:String;
    WriteAllowable: Boolean = True; //Allow output file to be written or not.
    s: String; //Temporary string
    i:Integer;//Counter

    UTCRecord :TDateTime;
    LocalRecord :TDateTime;

Begin
  Infile := TStringList.Create;
  pieces := TStringList.Create;

  SourceFileName:=SourcePathFile;
  WorkingPath:=RemoveMultiSlash(SourcePathFile + DirectorySeparator);
  OutputPath:=ExtractFilePath(SourcePathFile);
  OutputPathFileName:=RemoveMultiSlash(WorkingPath+'JDUTDEC' + DirectorySeparator);

  { So far there are no conditions to prevent writing files.
    The output directory either already exists, or has been created.
    The output files will overwrite previous output files.}
  WriteAllowable:=True;

  if WriteAllowable then begin

  { Process the file }

  try

      {Start reading file.}

      { Define Input file. }
      SourceFileName:= ExtractFileName(SourcePathFile);

      { Define Output file. }
      OutputPathFileName:=OutputPath+LazFileUtils.ExtractFileNameWithoutExt(SourceFileName)+'_JDUTDEC.dat';
      AssignFile(OutFile, OutputPathFileName);
      Rewrite(OutFile); //Open file for writing

      {$I+}
      try

         StatusBar1.Panels.Items[0].Text:='Reading Input file';


         Infile.LoadFromFile(OpenDialog1.Filename);

          {Go through all lines in input file}
          for s in Infile do begin

              {Get Data Line, begins with # UTC Date & Time}
              if AnsiContainsStr(s,'# UTC Date & Time') then begin
                { Parse field definition line to insert new fields. }
                pieces.Delimiter := ',';
                pieces.StrictDelimiter := True; //Do not parse spaces also
                pieces.DelimitedText := s;

                ComposeString:=pieces.Strings[0]+','+pieces.Strings[1]+', Julian Date, UT date';

                { Get the field locations. }
                for i:=2 to pieces.Count-1 do begin
                  ComposeString:=ComposeString+','+pieces.Strings[i];
                end;
              end

              {Get Data Line, begins with # YYYY-MM-DDTHH:mm:ss.fff;}
              else if AnsiContainsStr(s,'# YYYY-MM-DDTHH:mm:ss.fff;') then begin
                { Parse field definition line to insert new fields. }
                pieces.Delimiter := ';';
                pieces.StrictDelimiter := True; //Do not parse spaces also
                pieces.DelimitedText := s;

                ComposeString:=pieces.Strings[0]+';'+pieces.Strings[1]+';day.frac;day.frac ';

                { Get the field locations. }
                for i:=2 to pieces.Count-1 do begin
                  ComposeString:=ComposeString+';'+pieces.Strings[i];
                end;
              end

              {General comment line}
              else if AnsiContainsStr(s,'# ') then begin
                ComposeString:=s;
              end

              {Data line}
              else begin
               pieces.Delimiter := ';';
               pieces.StrictDelimiter := True; //Do not parse spaces
               { Separate the fields of the record. }
               pieces.DelimitedText := s;

               { Pass first and second field untouched. }
               ComposeString:=pieces.Strings[0]+';'+pieces.Strings[1];

               { Assume that the first field is UT time. }
               UTCRecord:=ScanDateTime('yyyy-mm-dd"T"hh:nn:ss.zzz',pieces.Strings[0]);

               { Perform the conversion to Julian date.
                 Output UT datetime as decimal with enough precision to indicate seconds.}
               ComposeString:=ComposeString+format(';%.1f;%.8f',[DateTimeToJulianDate(UTCRecord), UTCRecord]);

               { Compose remainder of string untouched. }
               for i:=2 to pieces.count-1 do begin
                 ComposeString:=ComposeString+';'+pieces.Strings[i];
               end;

              end;

              { Write corrected line to output file. }
              WriteLn(OutFile,ComposeString);

          end;

         Flush(OutFile);
         CloseFile(OutFile);

         StatusBar1.Panels.Items[0].Text:='Finished file'+SourceFileName;

       except
         on E: EInOutError do
         begin
          MessageDlg('Error', 'File handling error occurred. Details: '+E.ClassName+'/'+E.Message, mtError, [mbOK],0);
         end;
       end;


  StatusBar1.Panels.Items[0].Text:='Finished converting file. Result stored in :'+OutputPath;


  finally
  end;
end;

end;

initialization
  {$I date2dec.lrs}

end.

