{*******************************************************}
{                                                       }
{       Pascal Script Source File                       }
{       Run by RemObjects Pascal Script in CnWizards    }
{                                                       }
{       Generated by CnPack IDE Wizards                 }
{                                                       }
{*******************************************************}

program OTADemo1;

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ToolsAPI, StdCtrls, ExtCtrls, Buttons, CnCommon, CnWizUtils, CnWizIdeUtils;

const
  SCnDefSourceMask = '.PAS;.DPR;CPP;.C;.HPP;.H;.CXX;.CC;.HXX;.HH;.ASM';

procedure ProcessFile(const FileName: string);
var
  Lines: TStringList;
begin
  Lines := TStringList.Create;
  try
    Lines.Text := IdeGetSourceByFileName(FileName);

    // todo: Process a file
    // IdeSetSourceByFileName(FileName, Lines, True);  // Write to file
    
    Writeln(Format('Filename: %s. Line count: %d', [FileName, Lines.Count]));
  finally
    Lines.Free;
  end;   
end;

procedure ProcessProject(Project: IOTAProject);
var
  i: Integer;
  FileName: string;
begin
  if Project = nil then Exit;

  ProcessFile(Project.GetFileName);        // 处理工程文件自身

  for i := 0 to Project.GetModuleCount - 1 do
  begin
    FileName := Project.GetModule(i).GetFileName;
    if IsSourceModule(FileName) then
      ProcessFile(FileName);
  end;
end;

procedure ProcessProjectGroup(ProjectGroup: IOTAProjectGroup);
var
  i: Integer;
begin
  if ProjectGroup = nil then Exit;

  for i := 0 to ProjectGroup.GetProjectCount - 1 do
  begin
    ProcessProject(ProjectGroup.GetProject(i));
  end;
end;

procedure ProcessOpenUnits;
var
  iModuleServices: IOTAModuleServices;
  i: Integer;
  FileName: string;
begin
  iModuleServices := IOTAModuleServices(BorlandIDEServices);

  for i := 0 to iModuleServices.GetModuleCount - 1 do
  begin
    FileName := CnOtaGetFileNameOfModule(iModuleServices.GetModule(i), True);
    ProcessFile(FileName);
  end;
end;

var
  FMasks: string;

procedure OnFindFile(const FileName: string;
  const Info: TSearchRec; var Abort: Boolean);
begin
  if FileMatchesExts(FileName, FMasks) then
  begin
    ProcessFile(FileName);
  end;
end;

procedure ProcessDir(const Dir, FileMask: string; IncludeSubDirs: Boolean);
begin
  if FileMask = '' then
    FMasks := SCnDefSourceMask
  else
    FMasks := FileMask;

  FindFile(Dir, '*.*', @OnFindFile, nil, IncludeSubDirs, False);
end;

var
  Form: TForm;
  rgKind: TRadioGroup;
  gbDir: TGroupBox;
  edtDir: TEdit;
  cbbMask: TComboBox;
  chkIncludeSubDirs: TCheckBox;

procedure btnSelectDirClick(Sender: TObject);
var
  NewDir: string;
begin
  NewDir := edtDir.Text;
  if GetDirectory('Select Directory', NewDir, True) then
    edtDir.Text := NewDir;
end;

begin
  Form := TForm.Create(nil);
  try
    with Form do
    begin
      ClientWidth := 400;
      ClientHeight := 262;
      Position := poScreenCenter;
      BorderStyle := bsDialog;
      Caption := 'CnScript OTA Demo1';
    end;

    rgKind := TRadioGroup.Create(Form);
    with rgKind do
    begin
      Parent := Form;
      SetBounds(8, 8, 385, 120);
      Caption := '&Kind';
      Items.Add('Current Unit');
      Items.Add('Opened Units');
      Items.Add('Project Units');
      Items.Add('Project Group Units');
      Items.Add('Files in Directory');
      ItemIndex := 0;
    end;

    gbDir := TGroupBox.Create(Form);
    with gbDir do
    begin
      Parent := Form;
      SetBounds(8, 132, 385, 89);
      Caption := '&Directory';
    end;

    with TLabel.Create(Form) do
    begin
      Parent := gbDir;
      SetBounds(8, 19, 70, 13);
      Caption := '&Directory:';
    end;
    
    with TLabel.Create(Form) do
    begin
      Parent := gbDir;
      SetBounds(8, 43, 70, 13);
      Caption := '&File Masks:';
    end;

    edtDir := TEdit.Create(Form);
    with edtDir do
    begin
      Parent := gbDir;
      SetBounds(88, 16, 257, 21);
    end;

    with TButton.Create(Form) do
    begin
      Parent := gbDir;
      SetBounds(352, 16, 21, 21);
      Caption := '...';
      OnClick := @btnSelectDirClick;
    end;
    
    cbbMask := TComboBox.Create(Form);
    with cbbMask do
    begin
      Parent := gbDir;
      SetBounds(88, 40, 257, 21);
      Items.Add('.pas;.dpr');
      Items.Add('.cpp;.c;.hpp;.h;.cxx;.cc;.hxx;.hh;.asm');
      Items.Add('.pas;.dpr;cpp;.c;.hpp;.h;.cxx;.cc;.hxx;.hh;.asm');
    end;
    
    chkIncludeSubDirs := TCheckBox.Create(Form);
    with chkIncludeSubDirs do
    begin
      Parent := gbDir;
      SetBounds(88, 64, 200, 17);
      Caption := 'Include &Sub Directories';
    end;

    with TBitBtn.Create(Form) do
    begin
      Parent := Form;
      SetBounds(220, 230, 80, 24);
      Kind := bkOk;
    end;

    with TBitBtn.Create(Form) do
    begin
      Parent := Form;
      SetBounds(308, 230, 80, 24);
      Kind := bkCancel;
    end;
    
    if Form.ShowModal = mrOk then
    begin
      case rgKind.ItemIndex of
        1:
          begin
            ProcessOpenUnits;
          end;
        2:
          begin
            ProcessProject(CnOtaGetCurrentProject);
          end;
        3:
          begin
            ProcessProjectGroup(CnOtaGetProjectGroup);
          end;
        4:
          begin
            ProcessDir(Trim(edtDir.Text), Trim(cbbMask.Text),
              chkIncludeSubDirs.Checked);
          end;
      else
        begin
          ProcessFile(CnOtaGetCurrentSourceFile);
        end;
      end;
    end;
  finally
    Form.Free;
  end;
end.

