unit uSynchronizeDirectoriesDialog;
{$INCLUDE 'DirSync3.inc'}

interface

uses
  SysUtils, Windows, Classes,
  {$IFDEF FAR3} Plugin3, {$ELSE} PluginW, {$ENDIF} FarKeysW, FarColor,
  uSystem, uFAR, uLog,
  uDirSyncConsts, uMessages, uOptions;

type

  TSynchronizeDirectoriesDialog = class(TFarDialog)
  public
    type
      TDifferentFilesAction = (dfaAsk, dfaSkip, dfaCopyToLeft, dfaCopyToRight);
      TSynchronizeDirectoriesAction = (sdaSynchronize, sdaReturnToEditor, sdaCancel);
  private
    fCopyToLeftPanel: boolean;
    fConfirmOverwriteLeft: boolean;
    fCopyToRightPanel: boolean;
    fConfirmOverwriteRight: boolean;
    fDeleteLeftMissingOnRight: boolean;
    fDeleteRightMissingOnLeft: boolean;
    fDiffTypesPresent: array[TDifferenceType] of boolean;
    fDifferentFilesAction: TDifferentFilesAction;
    fSilentMode: boolean;
    fGlobalRemember: boolean;
    function GetDiffTypePresent(DiffType: TDifferenceType): boolean;
    procedure SetDiffTypePresent(DiffType: TDifferenceType; const Value: boolean);
  private
    fCheckCopyToLeft: integer;
    fCheckCopyToLeftOverwrite: integer;
    fCheckCopyToRight: integer;
    fCheckCopyToRightOverwrite: integer;
    fCheckDeleteLeft: integer;
    fCheckDeleteRight: integer;
    fRadioDifferentFilesAsk: integer;
    fRadioDifferentFilesOverwriteLeft: integer;
    fRadioDifferentFilesOverwriteRight: integer;
    fRadioDifferentFilesSkip: integer;
    fCheckSilentMode: integer;
    fCheckGlobalRemember: integer;
    fButtonOK: integer;
    fButtonCancel: integer;
    fButtonEditor: integer;
  protected
  public
    constructor Create;
    destructor Destroy; override;
    procedure ClearDialog; override;
    function Execute: TSynchronizeDirectoriesAction;
    procedure SetDefaultSettings;
    property CopyToLeftPanel: boolean read fCopyToLeftPanel write fCopyToLeftPanel;
    property ConfirmOverwriteLeft: boolean read fConfirmOverwriteLeft write fConfirmOverwriteLeft;
    property CopyToRightPanel: boolean read fCopyToRightPanel write fCopyToRightPanel;
    property ConfirmOverwriteRight: boolean read fConfirmOverwriteRight write fConfirmOverwriteRight;
    property DeleteLeftMissingOnRight: boolean read fDeleteLeftMissingOnRight write fDeleteLeftMissingOnRight;
    property DeleteRightMissingOnLeft: boolean read fDeleteRightMissingOnLeft write fDeleteRightMissingOnLeft;
    property DifferentFilesAction: TDifferentFilesAction read fDifferentFilesAction write fDifferentFilesAction;
    property DiffTypePresent[DiffType: TDifferenceType]: boolean read GetDiffTypePresent write SetDiffTypePresent;
    property SilentMode: boolean read fSilentMode write fSilentMode;
    property GlobalRemember: boolean read fGlobalRemember write fGlobalRemember;
  end;

implementation

{ TDirSyncSyncDialog }

procedure TSynchronizeDirectoriesDialog.ClearDialog;
begin
  inherited;
  fCheckCopyToLeft := -1;
  fCheckCopyToLeftOverwrite := -1;
  fCheckCopyToRight := -1;
  fCheckCopyToRightOverwrite := -1;
  fCheckDeleteLeft := -1;
  fCheckDeleteRight := -1;
  fRadioDifferentFilesAsk := -1;
  fRadioDifferentFilesOverwriteLeft := -1;
  fRadioDifferentFilesOverwriteRight := -1;
  fRadioDifferentFilesSkip := -1;
  fCheckSilentMode := -1;
  fCheckGlobalRemember := -1;
  fButtonOK := -1;
  fButtonCancel := -1;
  fButtonEditor := -1;
end;

constructor TSynchronizeDirectoriesDialog.Create;
begin
  inherited Create( {$IFDEF FAR3_UP} PLUGIN_GUID, DIALOG_SYNC_GUID {$ELSE} FarApi.ModuleNumber {$ENDIF} );
  SetDefaultSettings;
end;

destructor TSynchronizeDirectoriesDialog.Destroy;
begin
  inherited;
end;

function TSynchronizeDirectoriesDialog.Execute: TSynchronizeDirectoriesAction;
const
  EnabledFlag: array[boolean] of DWORD = (DIF_DISABLE, 0);
var
  i, Button: integer;
begin
  Result := sdaCancel;
  // Build the dialog
  ClearDialog;
                                        AddDoubleBox(  3,  1, 70, 17, GetMsg(MTitle), 0);
                                        AddLabel    (  5,  2,         GetMsg(MBothFilesExist), 0);
  fCheckCopyToLeft :=                   AddCheckbox (  5,  3,         GetMsg(MCopyRightToLeft), CopyToLeftPanel and (DiffTypePresent[dtMissingLeft] or DiffTypePresent[dtOlderLeft]), EnabledFlag[DiffTypePresent[dtMissingLeft] or DiffTypePresent[dtOlderLeft]]);
  fCheckCopyToLeftOverwrite :=          AddCheckbox (  8,  4,         GetMsg(MOverwriteRightToLeft), ConfirmOverwriteLeft {and DiffTypePresent[dtOlderLeft]}, EnabledFlag[DiffTypePresent[dtMissingLeft] or DiffTypePresent[dtOlderLeft]]);
  fCheckCopyToRight :=                  AddCheckbox (  5,  5,         GetMsg(MCopyLeftToRight), CopyToRightPanel and (DiffTypePresent[dtMissingRight] or DiffTypePresent[dtOlderRight]), EnabledFlag[DiffTypePresent[dtMissingRight] or DiffTypePresent[dtOlderRight]]);
  fCheckCopyToRightOverwrite :=         AddCheckbox (  8,  6,         GetMsg(MOverwriteLeftToRight), ConfirmOverwriteRight {and DiffTypePresent[dtOlderRight]}, EnabledFlag[DiffTypePresent[dtMissingRight] or DiffTypePresent[dtOlderRight]]);
                                        AddLabel    (  5,  7,         GetMsg(MBothFilesExistSameDate), 0);
  fRadioDifferentFilesAsk :=            AddRadio    (  0,  8,         GetMsg(MAskUser), True, DIF_CENTERGROUP or EnabledFlag[DiffTypePresent[dtDifferent]]);
  fRadioDifferentFilesSkip :=           AddRadio    (  0,  8,         GetMsg(MSkip), False, DIF_CENTERGROUP or EnabledFlag[DiffTypePresent[dtDifferent]]);
  fRadioDifferentFilesOverwriteLeft :=  AddRadio    (  0,  8,         GetMsg(MOverwriteLeft2), False, DIF_CENTERGROUP or EnabledFlag[DiffTypePresent[dtDifferent]]);
  fRadioDifferentFilesOverwriteRight := AddRadio    (  0,  8,         GetMsg(MOverwriteRight2), False, DIF_CENTERGROUP or EnabledFlag[DiffTypePresent[dtDifferent]]);
                                        AddLabel    (  5,  9,         GetMsg(MEraseAbsentFiles), 0);
  fCheckDeleteLeft :=                   AddCheckbox (  5, 10,         GetMsg(MEraseAbsentFilesLeft), DeleteLeftMissingOnRight and DiffTypePresent[dtMissingRight], EnabledFlag[DiffTypePresent[dtMissingRight]]);
  fCheckDeleteRight :=                  AddCheckbox (  5, 11,         GetMsg(MEraseAbsentFilesRight), DeleteRightMissingOnLeft and DiffTypePresent[dtMissingLeft], EnabledFlag[DiffTypePresent[dtMissingLeft]]);
                                        AddLabel    (  5, 12,         nil, DIF_SEPARATOR);
  fCheckSilentMode :=                   AddCheckbox (  5, 13,         GetMsg(MSilentMode), SilentMode, 0);
  fCheckGlobalRemember :=               AddCheckbox (  5, 14,         GetMsg(MGlobalRemember), GlobalRemember, 0);
                                        AddLabel    (  5, 15,         nil, DIF_SEPARATOR);
  fButtonOK :=                          AddButton   (  0, 16,         GetMsg(MOk), DIF_CENTERGROUP);
  fButtonEditor :=                      AddButton   (  0, 16,         GetMsg(MReturnToEditor), DIF_CENTERGROUP);
  fButtonCancel :=                      AddButton   (  0, 16,         GetMsg(MCancel), DIF_CENTERGROUP);
  // Set focus to the first enabled checkbox
  for i := 0 to Pred(Count) do
    if Items[i].ItemType = DI_CHECKBOX then
      if (Items[i].Flags and DIF_DISABLE) = 0 then begin
        {$IFDEF FAR3_UP}
        Items[i].Flags := Items[i].Flags or DIF_FOCUS;
        {$ELSE}
        Items[i].Focus := 1;
        {$ENDIF}
        Break;
      end;
  // Set the default button
  {$IFDEF FAR3_UP}
  Items[fButtonOK].Flags := Items[fButtonOK].Flags or DIF_DEFAULTBUTTON;
  {$ELSE}
  Items[fButtonOK].DefaultButton := 1;
  {$ENDIF}
  // Show the dialog
  if Build(-1, -1, 74, 19, 0, 'Synchronize') then
    if inherited Execute(Button) then
      if Button = fButtonOK then begin
        //Log('OK pressed, reading the settings');
        CopyToLeftPanel := ItemChecked[fCheckCopyToLeft];
        ConfirmOverwriteLeft := ItemChecked[fCheckCopyToLeftOverwrite];
        CopyToRightPanel := ItemChecked[fCheckCopyToRight];
        ConfirmOverwriteRight := ItemChecked[fCheckCopyToRightOverwrite];
        DeleteLeftMissingOnRight := ItemChecked[fCheckDeleteLeft];
        DeleteRightMissingOnLeft := ItemChecked[fCheckDeleteRight];
        if ItemChecked[fRadioDifferentFilesAsk] then
          DifferentFilesAction := dfaAsk
        else if ItemChecked[fRadioDifferentFilesOverwriteLeft] then
          DifferentFilesAction := dfaCopyToLeft
        else if ItemChecked[fRadioDifferentFilesOverwriteRight] then
          DifferentFilesAction := dfaCopyToRight
        else if ItemChecked[fRadioDifferentFilesSkip] then
          DifferentFilesAction := dfaSkip
        else
          DifferentFilesAction := dfaAsk;
        fSilentMode := ItemChecked[fCheckSilentMode];
        fGlobalRemember := ItemChecked[fCheckGlobalRemember];
        Result := sdaSynchronize;
      end
      else if Button = fButtonEditor then begin
        Result := sdaReturnToEditor;
      end;
end;

function TSynchronizeDirectoriesDialog.GetDiffTypePresent(DiffType: TDifferenceType): boolean;
begin
  Result := fDiffTypesPresent[DiffType];
end;

procedure TSynchronizeDirectoriesDialog.SetDefaultSettings;
begin
  CopyToLeftPanel := True;
  ConfirmOverwriteLeft := True;
  CopyToRightPanel := True;
  ConfirmOverwriteRight := True;
  DeleteLeftMissingOnRight := False;
  DeleteRightMissingOnLeft := False;
  DifferentFilesAction := dfaAsk;
  SilentMode := False;
  GlobalRemember := False;
end;

procedure TSynchronizeDirectoriesDialog.SetDiffTypePresent(DiffType: TDifferenceType; const Value: boolean);
begin
  fDiffTypesPresent[DiffType] := Value;
end;

end.
