unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, XPMan, Buttons, Mask, ToolEdit, RecurseDir,
  Edit, ComCtrls, SkinCaption, WinSkinData, ShellAPI, ExeMod, ztvregister,
  ztvBase, ztvUnZip, FTPEdit, IdBaseComponent, IdComponent,
  IdTCPConnection, IdTCPClient, IdFTP;

type
  TMainForm = class(TForm)
    XPManifest1: TXPManifest;
    Panel1: TPanel;
    Label1: TLabel;
    Panel2: TPanel;
    Panel3: TPanel;
    btnNext: TSpeedButton;
    btnPrevious: TSpeedButton;
    btnClose: TSpeedButton;
    RecurseDir: TRecurseDir;
    Notebook: TNotebook;
    Label4: TLabel;
    FieldsList: TListBox;
    btnAdd: TButton;
    btnEdit: TButton;
    Label5: TLabel;
    chkCaseSensitive: TCheckBox;
    btnDelete: TButton;
    btnClear: TButton;
    Label6: TLabel;
    CurrentEdit: TEdit;
    PBar: TProgressBar;
    Label7: TLabel;
    Label8: TLabel;
    btnStop: TSpeedButton;
    SkinData: TSkinData;
    SkinCaption: TSkinCaption;
    Panel: TPanel;
    Image2: TImage;
    Image3: TImage;
    btnHelp: TSpeedButton;
    Label9: TLabel;
    UnZip: TUnZip;
    Button1: TButton;
    FTP: TIdFTP;
    PBar2: TProgressBar;
    procedure btnCloseClick(Sender: TObject);
    procedure btnAddClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnEditClick(Sender: TObject);
    procedure btnDeleteClick(Sender: TObject);
    procedure btnClearClick(Sender: TObject);
    procedure btnNextClick(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
    procedure RecurseDirFileFound(Sender: TObject; FileName: String);
    procedure RecurseDirEnd(Sender: TObject);
    procedure btnPreviousClick(Sender: TObject);
    procedure btnHelpClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    StopOperation: Boolean;
    Files, Values: TStringList;
    FTPDirectory: String;
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

{ Delete a directory & everything in it }
function DelDir(aDir: string): Boolean;
var
  T: TSHFileOpStruct;
begin
  if not DirectoryExists(aDir) then
  begin
    Result := True;
    Exit;
  end;

  { Proceed with delete }
  Fillchar(T, SizeOf(T), #0);
  with T do
  begin
    Wnd := 0; { NewObjects handle -> NewObjects animation }
    wFunc := FO_DELETE;
    pFrom := pchar(aDir + #0#0);
    fFlags := FOF_SILENT or FOF_NOCONFIRMATION; { just do it, no confirmation }
  end;
  Application.ProcessMessages;
  if (SHFileOperation(T) <> 0) then
    RemoveDir(aDir);
{  if DirectoryExists(aDir) then
   ExecuteAndWait('rd "'+aDir+'" /s /q');}

  Result := not DirectoryExists(aDir);
end;

function GetTempFolder: String;
var
  tempFolder: array[0..MAX_PATH] of Char;
begin
  GetTempPath(MAX_PATH, @tempFolder);
  result := StrPas(tempFolder);
  if result<>'' then
   if result[length(result)]<>'\' then
    result:=result+'\';
end;

procedure TMainForm.btnCloseClick(Sender: TObject);
begin
  Close;
end;

procedure TMainForm.btnAddClick(Sender: TObject);
begin
  with TEditForm.Create(Self) do
  try
    ShowModal;
  finally
    if ModalResult = mroK then
    begin
      FieldsList.Items.Add(NameEdit.Text);
      Values.Add(ValueEdit.Text);
      FieldsList.ItemIndex := FieldsList.Items.Count-1;
    end;
    Free;
  end;
end;

procedure TMainForm.FormCreate(Sender: TObject);

procedure ExtractZip(ZIP, DestDir: String);
Var
   FilesExtracted: Integer;
Begin
	UnZip.OverwriteMode := omOverwrite;
   UnZip.ArchiveFile := ZIP;    // archive filename
   UnZip.ConfirmOverwrites := False; // default = False
   UnZip.RecurseDirs := True; // default = False
   UnZip.FileSpec.Clear();             //
   UnZip.FileSpec.Add('*.*');
   UnZip.ExtractDir := DestDir;
   If DirectoryExists(DestDir) Then  // if the directory exists then extract
   Begin
      FilesExtracted := UnZip.Extract();
   End
   Else
   Begin
      ShowMessage('Extract directory not found!');
      Exit;
   End;
end;

begin
  // get from EXE
  ForceDirectories(GetTempFolder+'HTMLB');
  Extract2File('TAGS', GetTempFolder+'HTMLB\Tags.dat');
  FieldsList.Items.LoadFromFile(GetTempFolder+'HTMLB\Tags.dat');
  Caption := FieldsList.Items[0] + ' - Website Rebrander';
  Application.Title := Caption;
  FieldsList.Items.Delete(0);
  DeleteFile(GetTempFolder+'HTMLB\Tags.dat');
  // extract ZIP
  Extract2File('ZIP', GetTempFolder+'HTMLB\Zip.zip');
  ForceDirectories(GetTempFolder+'HTMLB\HTML');
  ExtractZIP(GetTempFolder+'HTMLB\Zip.zip',GetTempFolder+'HTMLB\HTML');
  DeleteFile(GetTempFolder+'HTMLB\Zip.zip');

  // continue
  Values := TStringList.Create;
  Values.Assign(FieldsList.Items);
  Files := TStringList.Create;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  // remove temp folder
  DelDir(GetTempFolder+'HTMLB');
  Values.Free;
  Files.Free;
end;

procedure TMainForm.btnEditClick(Sender: TObject);
begin
  if FieldsList.ItemIndex < 0 then Exit;
  with TEditForm.Create(Self) do
  try
    NameEdit.Text := FieldsList.Items[FieldsList.ItemIndex];
    ValueEdit.Text := Values[FieldsList.ItemIndex];
    ShowModal;
  finally
    if ModalResult = mroK then
    begin
      FieldsList.Items[FieldsList.ItemIndex] := NameEdit.Text;
      Values[FieldsList.ItemIndex] := ValueEdit.Text;
    end;
    Free;
  end;
end;

procedure TMainForm.btnDeleteClick(Sender: TObject);
begin
  if FieldsList.ItemIndex < 0 then Exit;
  Values.Delete(FieldsList.ItemIndex);
  FieldsList.Items.Delete(FieldsList.ItemIndex);
end;

procedure TMainForm.btnClearClick(Sender: TObject);
begin
  if FieldsList.Count > 0 then
   if Application.MessageBox('Are you sure you want to delete all the fields entered so far?', 'Warning', MB_YESNO+MB_ICONQUESTION)=mrYes then
   begin
     FieldsList.Items.Clear;
     Values.Clear;
   end;
end;

procedure TMainForm.btnNextClick(Sender: TObject);
begin
  if Notebook.PageIndex = 0 then
  begin
    StopOperation := False;

    btnClose.Enabled := False;
    btnPrevious.Enabled := False;
    btnNext.Enabled := False;
    btnNext.Down := True;

    Files.Clear;
    RecurseDir.Directory := GetTempFolder+'HTMLB\HTML';
    RecurseDir.Mask := '*.*';
    CurrentEdit.Text := 'Building list of files to process...';
    Notebook.PageIndex := 1;
    PBar2.Position := 0;
    PBar.Position := 0;
    RecurseDir.Execute;
  end;
end;

procedure TMainForm.btnStopClick(Sender: TObject);
begin
  StopOperation := True;
  btnStop.Enabled := True;
end;

procedure TMainForm.RecurseDirFileFound(Sender: TObject; FileName: String);
begin
  Application.ProcessMessages;
  Files.Add(FileName);
  if StopOperation then
    RecurseDir.StopRecursion := True;
end;

procedure TMainForm.RecurseDirEnd(Sender: TObject);
var I: Integer;

function GetFirstDir(S: String): String;
begin
  Result := Copy(S, 1, Pos('\', S)-1);
end;

function MakeDirectoryStructure(FTP: TIdFTP; Path: String): Integer;
var S: String;
    LS: TStringList;
begin
  if Path = '' then
  begin
    Result := 0;
    Exit;
  end
  else
  begin
    S := GetFirstDir(Path);
    if S='' then S := Path;
    LS := TStringList.Create;
    FTP.List(LS);
    if LS.IndexOf(S) >= 0 then
     FTP.ChangeDir(S)
    else
    begin
      try
       FTP.MakeDir(S);
      except
      end;
      FTP.ChangeDir(S);
    end;
    if S<>Path then
     Delete(Path, 1, Length(S)+1)
    else
     Path := '';
    LS.Free;
    Result := MakeDirectoryStructure(FTP, Path) + 1;
  end;
end;

procedure ProcessFile(FName: String);
var List: TStringList;
    S: String;
    I: Integer;
begin
  List := TStringList.Create;
  List.LoadFromFile(FName);
  S := List.Text;
  for I:=0 to FieldsList.Items.Count-1 do
  begin
    if chkCaseSensitive.Checked then
      S := StringReplace(S, FieldsList.Items[I], Values[I], [rfReplaceAll])
    else
      S := StringReplace(S, FieldsList.Items[I], Values[I], [rfReplaceAll, rfIgnoreCase]);
    Application.ProcessMessages;
    if StopOperation then Break;
  end;
  if not StopOperation then
  begin
    // save changes to file
    List.Text := S;
    try
      List.SaveToFile(FName);
    except
      Application.MessageBox(PChar('Unable to save changes to file "'+FName+'"!'), 'Warning', MB_OK+MB_ICONWARNING);
    end;
  end;
  List.Free;
end;

function AddSlash(S: String): String;
begin
  if S<>'' then
   if S[Length(S)]<>'\' then
    S := S+'\';
  Result := S;
end;

function RemoveSlash(S: String): String;
begin
  if S<>'' then
   if S[Length(S)]='\' then
    Delete(S, Length(S), 1);
  Result := S;
end;

var J, Levels: Integer; SS: String;
begin
  if StopOperation then
  begin
    btnPrevious.Enabled := True;
    btnClose.Enabled := True;
    CurrentEdit.Text := 'Operation stopped by user';
    Exit;
  end;

  // now we have the list of files, so process each one
  for I:=0 to Files.Count-1 do
  if StopOperation then
  begin
   CurrentEdit.Text := 'Operation stopped by user';
   btnPrevious.Enabled := True;
   btnClose.Enabled := True;
   Break;
  end
  else
  begin
    Application.ProcessMessages;
    PBar.Position := I*100 div Files.Count;
    CurrentEdit.Text := Files[I];
    if (LowerCase(ExtractFileExt(Files[I]))='.htm') or (LowerCase(ExtractFileExt(Files[I]))='.html') then
     ProcessFile(Files[I]);
  end;

   // now begin the upload by FTP
  { Upload files? }
  begin
    PBar2.Max := Files.Count;
    FTP.Connect();
    try
      if Trim(FTPDirectory) <> '' then
       FTP.ChangeDir(FTPDirectory); { change to working dir }
      { begin uploading files }
      for I:=0 to Files.Count-1 do
      begin
        if StopOperation then Break;
        SS := RemoveSlash(ExtractFilePath(Files[I]));
        Delete(SS, 1, Length(GetTempFolder+'HTMLB\HTML\'));
        if SS <> '' then
         Levels := MakeDirectoryStructure(FTP, RemoveSlash(SS))
        else
         Levels := 0;
        FTP.Put(Files[I], ExtractFileName(Files[I]));

        PBar2.Position := PBar2.Position + 1;
        Application.ProcessMessages;

        for J:=0 to Levels-1 do { Go 'Levels' up }
         FTP.ChangeDirUp;
      end;
    except
    end;
    if FTP.Connected then
     FTP.Disconnect;
  end;

   // finished
   PBar.Position := PBar.Max;
   btnStop.Enabled := False;
   CurrentEdit.Text := 'Operation completed successfully. '+FloatToStrF(Files.Count, ffNumber, 18, 0)+' file(s) processed.';
   btnPrevious.Enabled := True;
   btnClose.Enabled := True;
   StopOperation := False;
end;

procedure TMainForm.btnPreviousClick(Sender: TObject);
begin
  btnPrevious.Down := True;
  btnNext.Enabled := True;
  btnPrevious.Enabled := True;
  Notebook.PageIndex := 0;
end;

procedure TMainForm.btnHelpClick(Sender: TObject);
begin
  ShellExecute(Handle, 'open', 'http://www.htmlbrander.com/help', '', '', SW_SHOWNORMAL);
end;

procedure TMainForm.Button1Click(Sender: TObject);
begin
  with FTPEditForm do
   ShowModal;
end;

end.
