{/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* Original author:
* - Pavel Cvrcek <jasnapaka@jasnapaka.com>
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */}

unit ZipFactory;

interface

uses Classes, ZipMstr19, Forms, Windows, Dialogs,
// own
Configuration, BackupTask, BackupTaskExternal, ProgressWindow;

type
  TZipFactory = class(TObject)
    private
      zipFilePath: String;
      rootDir: String;
      password: String;
      ZipMaster1 : TZipMaster19;
      currentFilesSize: int64;
      totalFilesSize: int64;

      procedure addFile (FilePath: String; UserRootDir: String); overload;
      procedure addFileList (FileList: TStringList);
    protected
    public
      constructor Create (ZipFilePath: String; Password: String); overload;
      constructor Create (ZipFilePath: String; RootDir: String; Password: String); overload;
      destructor Destroy;

      procedure addBackupTask(BackupTask: TBackupTask);

//      procedure addFile (FilePath: String); overload;
//      procedure addDirectory (DirectoryPath: String; Mask: String);overload;
//      procedure addDirectory (DirectoryPath: String; Mask: String; UserRootDir: String);overload;
      function extractFile (FilePath: String):integer; overload;
      function extractFile (FilePath: String; UserRootDir: String):integer; overload;
      function extractFileList (FileList: TStringList):Integer;
      function extractDirectory (DirectoryPath: String; Mask: String):Integer;overload;
      function extractDirectory (DirectoryPath: String; Mask: String; UserRootDir: String):Integer;overload;
      function getRootDir():String;
      procedure setRootDir(RootDir: String);

     procedure zipMaster1PasswordError(Sender: TObject;
      IsZipAction: Boolean; var NewPassword: String; const ForFile: String;
      var RepeatCount: LongWord; var Action: TMsgDlgBtn );
     procedure zipMaster1ItemProgress(Sender: TObject; details: TZMProgressDetails);
     procedure ZipMaster1OnMessage(Sender: TObject; ErrCode: Integer; const ErrMsg: TZMString);
     procedure ZipMaster1OnZipDialog(Sender: TObject; const title: String; var msg: String; var Result: Integer; btns: TMsgDlgButtons);
  end;

implementation

uses Hlavni, Heslo2, SysUtils, Config, ZMDlg19, JPDialogs, MozProfile;

// default compression level for zip file
const DEFAULT_COMPRESSION_LEVEL = 9;

constructor TZipFactory.Create(ZipFilePath: String; Password: string);
begin
  Create(ZipFilePath, '', Password);
end;

constructor TZipFactory.Create(ZipFilePath: string; RootDir: string; Password: string);
begin
  self.zipFilePath:= ZipFilePath;
  self.password:= Password;
  self.rootDir:= RootDir;

  // vytvoøení ZIP souboru
  ZipMaster1:= TZipMaster19.Create(nil);
  ZipMaster1.DLLDirectory:= '.\dll\';
  ZipMaster1.ZipFileName:= ZipFilePath;
  ZipMaster1.AddCompLevel:= Configuration.getIntConfiguration(Configuration.SECTION_GENERAL,
                            Configuration.COMPRESSION_LEVEL, 9);

  with ZipMaster1 do
    begin
      AddOptions:= AddOptions + [AddRecurseDirs, AddDirNames];
      ExtrOptions:= ExtrOptions + [ExtrDirNames, ExtrOverWrite, ExtrForceDirs];
    end;

  if Length (Password) > 0 then
    begin
      ZipMaster1.AddOptions:= ZipMaster1.AddOptions + [AddEncrypt];
      ZipMaster1.Password:= Password;
    end;

  ZipMaster1.OnPasswordError:= ZipMaster1PasswordError;
  ZipMaster1.OnProgress:= ZipMaster1ItemProgress;
  ZipMaster1.OnMessage:= ZipMaster1OnMessage;
  ZipMaster1.OnZipDialog:= ZipMaster1OnZipDialog;

  Application.ProcessMessages;
end;

procedure TZipFactory.ZipMaster1PasswordError(Sender: TObject;
      IsZipAction: Boolean; var NewPassword: String; const ForFile: String;
      var RepeatCount: LongWord; var Action: TMsgDlgBtn );
begin
  Form5.Edit1.Clear;
  Form5.Caption:= Config.l10n.getL10nString ('TForm5', 'LANG_CAPTION');
  Form5.Label1.Caption:= Config.l10n.getL10nString ('TForm5', 'LANG_LABEL1');
  Form5.Label2.Caption:= Config.l10n.getL10nString ('TForm4', 'LANG_HESLO');

  Form5.Button1.Caption:= Config.l10n.getL10nString ('TForm1', 'LANG_BUTTON_OK');
  Form5.Button2.Caption:= Config.l10n.getL10nString ('TForm1', 'LANG_BUTTON_2');

  Form5.ShowModal;

  if Form5.Potvrzeno = true then
    begin
      NewPassword:= Form5.Edit1.Text;
      ZipMaster1.Password:= Form5.Edit1.Text;
      Form1.Password:= Form5.Edit1.Text;
    end;
end;

procedure TZipFactory.ZipMaster1OnMessage(Sender: TObject; ErrCode: Integer; const ErrMsg: TZMString);
begin
  // log to error log
  {if (ErrCode <> 0) then
    begin
      WriteMsgToErrorLog(IntToStr (ErrCode) + ' ' + ErrMsg);
    end;}
end;

procedure TZipFactory.ZipMaster1OnZipDialog(Sender: TObject; const title: string; var msg: string; var Result: Integer; btns: TMsgDlgButtons);
begin
  // writing error
  if (ZipMaster1.ErrCode = 11671) then
    begin
      Result:= showErrorDialog(Config.l10n.getL10nString('MozBackup14', 'LANG_ERROR'),
                            Config.l10n.getL10nString('MozBackup15', 'LANG_WRITE_ERROR3'));
    end;
end;

procedure TZipFactory.zipMaster1ItemProgress(Sender: TObject; details: TZMProgressDetails);
begin
  Application.ProcessMessages;

  if (Form1.Akce = 1) then
    begin

      if (details.ItemPerCent = 0) then
        begin
          ProgressWindowAddMessage(Config.l10n.getL10nString('MozBackup14', 'LANG_FILE') + ': ' + details.ItemName);
        end;

      ProgressWindowProgress (currentFilesSize + details.ItemSize, totalFilesSize);

      if (details.ItemPerCent = 100) then
        begin
          // update progress
          currentFilesSize:= currentFilesSize + details.ItemSize;
          ProgressWindowProgress (currentFilesSize, totalFilesSize);
        end;
        
    end;
end;

destructor TZipFactory.Destroy; 
begin
  ZipMaster1.Destroy;
  ZipMaster1:= nil;
end;

// deprecated
procedure TZipFactory.addFile (FilePath: String; UserRootDir: String);
begin
  ZipMaster1.FSpecArgs.Add (FilePath);
  ZipMaster1.RootDir:= UserRootDir;
  ZipMaster1.Add;
end;

procedure TZipFactory.addBackupTask(BackupTask: TBackupTask);
var I: integer;
    externalFiles: TList;
    backupTaskExternal: TBackupTaskExternal;
begin
  currentFilesSize:= 0;
  totalFilesSize:= BackupTask.getFilesSize();

  addFileList (BackupTask.getFiles);

  externalFiles:= BackupTask.getExternalFiles;
  for I := 0 to externalFiles.Count - 1 do
    begin
      backupTaskExternal:= TBackupTaskExternal(externalFiles[i]);
      addFile (backupTaskExternal.getRelativePath(), backupTaskExternal.getAbsolutePath());
    end;    
end;

// pøidá seznam souborù do ZIP archivu
procedure TZipFactory.addFileList (FileList: TStringList);
begin
  ZipMaster1.FSpecArgs.Assign(FileList);
  ZipMaster1.RootDir:= rootDir;
  ZipMaster1.Add;
  Application.ProcessMessages;
end;

// rozbalení souboru
function TZipFactory.extractFile (FilePath: String):integer;
begin
  Result:= extractFile (FilePath, rootDir);
end;

function TZipFactory.extractFile (FilePath: String; UserRootDir: String):integer;
begin
  ZipMaster1.FSpecArgs.Append (FilePath);
  ZipMaster1.ExtrBaseDir:= UserRootDir;

  if (Length (Form1.Password) > 0) then
    begin
      ZipMaster1.Password:= Form1.Password;
    end;

  ZipMaster1.Extract;
  Application.ProcessMessages;
  Result:= ZipMaster1.SuccessCnt;  
end;

// rozbalení seznamu souborù
function TZipFactory.extractFileList (FileList: TStringList): Integer;
begin
  ZipMaster1.FSpecArgs.Assign(FileList);
  ZipMaster1.ExtrBaseDir:= rootDir;

  if (Length (Form1.Password) > 0) then
    begin
      ZipMaster1.Password:= Form1.Password;
    end;

  ZipMaster1.Extract;
  Application.ProcessMessages;
  Result:= ZipMaster1.SuccessCnt;  
end;

// rozbaleni adresare
function TZipFactory.extractDirectory (DirectoryPath: String; Mask: String):Integer;
begin
  Result:= extractDirectory (DirectoryPath, Mask, rootDir);
end;

function TZipFactory.extractDirectory (DirectoryPath: String; Mask: String; UserRootDir: String): Integer;
begin
  if (Length (DirectoryPath) > 0) then
    begin
      ZipMaster1.FSpecArgs.Append (DirectoryPath + '\' + Mask);
    end
  else
    begin
          if (pos ('mab', mask) > 0) then
      begin
        ShowMessage (DirectoryPath + '\' + Mask);
      end;
      ZipMaster1.FSpecArgs.Append (Mask);
    end;
  ZipMaster1.ExtrBaseDir:= UserRootDir;
  ZipMaster1.Extract;
  Application.ProcessMessages;

  Result:= ZipMaster1.SuccessCnt;  
end;

// vrátí adresáø na disku, ke kterému je vztahována cesta souboru v ZIPu
function TZipFactory.getRootDir():String;
begin
  Result:= rootDir;
end;

// nastaví adresáø na disku, ke kterému se vztahuje cesta k ZIP souboru
procedure TZipFactory.setRootDir(RootDir: string);
begin
  self.rootDir:= RootDir;
end;

end.
