unit Extractor;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Template, StdCtrls, ExtCtrls, ComCtrls, Menus, Buttons;

type
  TForm_Extractor = class(TForm_ToolTemplate)
    group_extract: TGroupBox;
    group_singlefiles: TGroupBox;
    btn_sel_dat: TButton;
    btn_sel_datraw: TButton;
    btn_sel_datraw_convert: TButton;
    btn_all_dat: TButton;
    btn_all_datraw: TButton;
    btn_all_datraw_convert: TButton;
    btn_sel_files_toone: TButton;
    btn_all_files_toone: TButton;
    group_onefile: TGroupBox;
    group_progress: TGroupBox;
    lbl_progress: TLabel;
    lbl_estimated: TLabel;
    progress: TProgressBar;
    btn_abort: TButton;
    saved: TSaveDialog;
    procedure FormCreate(Sender: TObject);
    procedure Extract(Sender: TObject);
    procedure btn_abortClick(Sender: TObject);
  private
  public
  end;

var
  Form_Extractor: TForm_Extractor;

implementation
{$R *.dfm}
uses Main, Functions, Data, OniDataClass;

procedure TForm_Extractor.FormCreate(Sender: TObject);
begin
  inherited;
  Self.AllowMultiSelect := True;

  btn_sel_dat.Caption    := 'Selected files' + CrLf + '(dat contents only)';
  btn_sel_datraw.Caption := 'Selected files' + CrLf + '(dat+raw contents)';
  btn_sel_datraw_convert.Caption :=
    'Selected files' + CrLf + '(dat+raw contents)' + CrLf + '(with convert if possible)';
  btn_all_dat.Caption    := 'All files in list' + CrLf + '(dat contents only)';
  btn_all_datraw.Caption := 'All files in list' + CrLf + '(dat+raw contents)';
  btn_all_datraw_convert.Caption :=
    'All files in list' + CrLf + '(dat+raw contents)' + CrLf + '(with convert if possible)';
  btn_sel_files_toone.Caption := 'Selected files' + CrLf + '(dat contents only)';
  btn_all_files_toone.Caption := 'All files in list' + CrLf + '(dat contents only)';
end;

procedure TForm_Extractor.btn_abortClick(Sender: TObject);
begin
  ShowMessage('X');
end;

procedure TForm_Extractor.Extract(Sender: TObject);
var
  sel_only:  Boolean;
  dat_only:  Boolean;
  convert:   Boolean;
  one_file:  Boolean;
  settings:  TExportSet;
  files:     LongWord;
  i, done:   LongWord;
  begintime: Double;
begin
  sel_only := Pos('sel', TButton(Sender).Name) > 0;
  dat_only := not (Pos('datraw', TButton(Sender).Name) > 0);
  convert  := Pos('convert', TButton(Sender).Name) > 0;
  one_file := Pos('toone', TButton(Sender).Name) > 0;
  if dat_only then
    settings := [DO_dat]
  else
    settings := [DO_dat, DO_raw];
  if convert then
    settings := settings + [DO_convert];
  if one_file then
    settings := settings + [DO_toone];
  progress.Position := 0;

  if saved.Execute then
  begin
    begintime := Time;
    group_progress.Visible := True;
    panel_files.Enabled := False;
    group_singlefiles.Enabled := False;
    group_onefile.Enabled := False;
    lbl_estimated.Caption := 'Estimated finishing time: unknown';
    if one_file then
    begin
      if FileExists(saved.FileName) then
      begin
        if MessageBox(Self.Handle, PChar(
          'File already exists. Do you want to overwrite it?'), PChar('Warning!'), MB_YESNO) =
          ID_YES then
        begin
          DeleteFile(saved.FileName);
        end
        else
        begin
          group_progress.Visible    := False;
          panel_files.Enabled      := True;
          group_singlefiles.Enabled := True;
          group_onefile.Enabled     := True;
          Exit;
        end;
      end;
      i := FileCreate(saved.FileName);
      FileClose(i);
      i := 0;
    end;
    if sel_only then
    begin
      files := filelist.SelCount;
      lbl_progress.Caption := 'Files done: 0/' + IntToStr(files);
      progress.Max := files;
      done  := 0;
      for i := 0 to filelist.Count - 1 do
      begin
        if filelist.Selected[i] then
        begin
          if one_file then
          begin
            ExportFile(OniDataConnection.ExtractFileID(
              filelist.Items.Strings[filelist.ItemIndex]), ExtractFileName(saved.FileName),
              settings, ExtractFileDir(saved.FileName));
          end
          else
          begin
            ExportFile(OniDataConnection.ExtractFileID(
              filelist.Items.Strings[filelist.ItemIndex]), filelist.Items.Strings[i], settings, 'D:');
          end;
          Inc(done);
        end;
        if ((done mod 10) = 0) and (done >= 50) then
          lbl_estimated.Caption := 'Estimated finishing time: ' + TimeToStr(
            (Time - begintime) / done * files + begintime);
        if (i mod 10) = 0 then
        begin
          progress.Position    := done;
          lbl_progress.Caption := 'Files done: ' + IntToStr(done) + '/' + IntToStr(files);
          Application.ProcessMessages;
        end;
      end;
    end
    else
    begin
      files := filelist.Count;
      lbl_progress.Caption := 'Files done: 0/' + IntToStr(files);
      progress.Max := files;
      for i := 0 to filelist.Count - 1 do
      begin
        if one_file then
        begin
          ExportFile(OniDataConnection.ExtractFileID(
            filelist.Items.Strings[filelist.ItemIndex]), ExtractFileName(saved.FileName),
            settings, ExtractFileDir(saved.FileName));
        end
        else
        begin
          ExportFile(OniDataConnection.ExtractFileID(
            filelist.Items.Strings[filelist.ItemIndex]), filelist.Items.Strings[i], settings, 'D:');
        end;
        if ((i mod 10) = 0) and (i >= 50) then
          lbl_estimated.Caption := 'Estimated finishing time: ' + TimeToStr(
            (Time - begintime) / i * files + begintime);
        if (i mod 5) = 0 then
        begin
          progress.Position    := i;
          lbl_progress.Caption := 'Files done: ' + IntToStr(i) + '/' + IntToStr(files);
          Application.ProcessMessages;
        end;
      end;
    end;
    group_progress.Visible    := False;
    panel_files.Enabled      := True;
    group_singlefiles.Enabled := True;
    group_onefile.Enabled     := True;
  end;
end;

begin
  AddToolListEntry('extractor', 'Extractor', '');
end.