unit fMain;

interface
{$INCLUDE SGDXF.INC}

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, ExtDlgs, Menus, ExtCtrls, sgDrawingNavigator, DXFImage,
  sgSelection, DXFConv, sgConsts, Buttons, ComCtrls, StdCtrls,
  {$IFNDEF sgDXFONLY}
  DWG, HPGL2,
  {$ENDIF}
  ToolWin, sgSManager, sgBlockLibrary;

type
  TEvent=procedure(Sender: TObject) of object;

  TfmMain = class(TForm)
    mmmain: TMainMenu;
    mmiFile: TMenuItem;
    mmiOpen: TMenuItem;
    mmiClose: TMenuItem;
    N1: TMenuItem;
    mmiExit: TMenuItem;
    OpenDialog: TOpenPictureDialog;
    mmiSelection: TMenuItem;
    sbrMain: TStatusBar;
    mmiSelectAll: TMenuItem;
    mmiDeselectAll: TMenuItem;
    pnlMain: TPanel;
    BtnOpen: TSpeedButton;
    btnClose: TSpeedButton;
    pnlSelection: TPanel;
    btnCopy: TSpeedButton;
    btnPaste: TSpeedButton;
    Preview1: TMenuItem;
    pnlButtons: TPanel;
    pnlEntInsp: TPanel;
    BtnSelect: TSpeedButton;
    BtnMSelect: TSpeedButton;
    btnEntityInspector: TSpeedButton;
    splImage: TSplitter;
    sbPreviewSelection: TSpeedButton;
    procedure FileOpen;
    procedure FormCreate(Sender: TObject);
    procedure sbxImageBoxResize(Sender: TObject);
    procedure Select;
    procedure MSelect;
    procedure FileClose;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure spbtnMSelectClick(Sender: TObject);
    procedure spbtnSelectClick(Sender: TObject);
    procedure mmiExitClick(Sender: TObject);
    procedure mmiOpenClick(Sender: TObject);
    procedure mmiCloseClick(Sender: TObject);
    procedure mmiSelectAllClick(Sender: TObject);
    procedure mmiDeselectAllClick(Sender: TObject);
    procedure BtnSelectClick(Sender: TObject);
    procedure BtnMSelectClick(Sender: TObject);
    procedure BtnOpenClick(Sender: TObject);
    procedure btnCloseClick(Sender: TObject);
    procedure btnPasteClick(Sender: TObject);
    procedure btnCopyClick(Sender: TObject);
    procedure Preview1Click(Sender: TObject);
    procedure btnEntityInspectorClick(Sender: TObject);
    procedure FormResize(Sender: TObject);
  private
    FManager: TsgSelectionManager;
    FDNavigator: TsgDrawingNavigator;
    procedure FMSChange(var Message: TMessage); message SM_SELECTIONCHANGED;
    procedure DNMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  public
    FBlockLibrary: TsgBlockLibrary;
    procedure OnSelectionChange;
    procedure InsertBlock(AIndex: Integer; X, Y: Single);
    property DNavigator: TsgDrawingNavigator read FDNavigator;
  end;

var
  fmMain: TfmMain;

implementation

uses
  fEntityInspector, BlockInsert, fPreview;

{$R *.dfm}

type
  TsgDXFImageAccess = class(TsgDXFImage);

function sgFloatToStrF(Value: TsgFloat): string;
begin
 if Value < 10000000 then
   Result := FloatToStrF(Value, ffGeneral, 7, 0)
 else
   Result := Format('%.7e', [Value]);
end;

procedure TfmMain.FMSChange(var Message: TMessage);
begin
  OnSelectionChange;
end;

procedure TfmMain.DNMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
  vPt: TFPoint;
begin
  sbrMain.Panels[1].Text := 'X:' + IntToStr(X) + '  Y:' + IntToStr(Y);
  vPt := DNavigator.GetDrawingInternalCoordsWithoutSnap(X, Y);
  sbrMain.Panels[2].Text := 'X:' + sgFloatToStrF(vPt.X) + '  Y:' + sgFloatToStrF(vPt.Y) +
    '  Z:' + sgFloatToStrF(vPt.Z);
end;

procedure TfmMain.FileOpen;
var
  I: Integer;
begin
  FManager.DeselectAll;
  OpenDialog.FileName := '';
  if not OpenDialog.Execute then
    Exit;
  DNavigator.Picture.Graphic := nil;
  DNavigator.LoadFromFile(OpenDialog.FileName);
  FManager.DNavigator := DNavigator;
  FBlockLibrary.DNavigator := DNavigator;
  Caption := OpenDialog.FileName + ' Editor';
  BtnSelect.Enabled := True;
  BtnMSelect.Enabled := True;
  BtnClose.Enabled := True;
  BtnSelect.Down := True;
  BtnMSelect.Down := False;
  mmiClose.Enabled := True;
  mmiSelection.Enabled := True;
  DNavigator.Align := alClient;
  DNavigator.FitToSize;
  if DNavigator.Picture.Graphic is TsgDXFImage then
  begin
    TsgDXFImageAccess(DNavigator.Picture.Graphic).SetMatrixMode(smEnabled);
    DNavigator.Update;
  end;
  sbrMain.Panels[0].Text := OpenDialog.FileName;
  for I := 1 to sbrMain.Panels.Count - 1 do
    sbrMain.Panels[I].Text := '';
end;

procedure TfmMain.FormCreate(Sender: TObject);
begin
  FDNavigator := TsgDrawingNavigator.Create(Self);
  FDNavigator.Parent := Self;
  FDNavigator.AutoFocus := True;
  FDNavigator.RectZooming := True;
  FDNavigator.OnMouseMove := DNMouseMove;
  FManager := TsgSelectionManager.Create;
  FBlockLibrary := TsgBlocklibrary.Create;
  FManager.Mode := mmSelect;
  BtnSelect.Down := False;
  BtnSelect.Enabled := False;
  BtnMSelect.Down := False;
  BtnMSelect.Enabled := False;
  BtnClose.Enabled := False;
  mmiClose.Enabled := False;
  mmiSelection.Enabled := False;
  {$IFDEF SGDEL_4}
  pnlEntInsp.Anchors := [akLeft, akTop, akRight, akBottom];
  pnlEntInsp.BiDiMode := bdRightToLeft;
  pnlEntInsp.DockSite := True;
  pnlEntInsp.ParentBiDiMode := False;
  {$ENDIF}
end;

procedure TfmMain.sbxImageBoxResize(Sender: TObject);
begin
  if not DNavigator.Empty then
    DNavigator.SetBounds(DNavigator.Left,DNavigator.Top,DNavigator.Width,DNavigator.Height);
end;

procedure TfmMain.Select;
begin
  DNavigator.Cursor := crArrow;
  FManager.Mode := mmSelect;
end;

procedure TfmMain.MSelect;
begin
  DNavigator.Cursor := crCross;
  FManager.Mode := mmMultiSelect;
end;

procedure TfmMain.FileClose;
var
  I: Integer;
begin
  FManager.Cancel;
  DNavigator.Picture.Graphic := nil;
  DNavigator.Align := alNone;
  DNavigator.SetBounds(0,0,0,0);
  Caption := Application.Title;
  BtnSelect.Down := False;
  BtnSelect.Enabled := False;
  BtnMSelect.Down := False;
  BtnMSelect.Enabled := False;
  BtnClose.Enabled := False;
  mmiSelection.Enabled := False;
  for I := 0 to sbrMain.Panels.Count - 1 do
    sbrMain.Panels[I].Text := '';
end;

procedure TfmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FBlockLibrary.Free;
  FileClose;
  FManager.Free;
end;

procedure TfmMain.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_ESCAPE then
    FManager.DeselectAll;
end;

procedure TfmMain.OnSelectionChange;
begin
  MessageBox(Self.Handle, 'Selection is changed!!!', 'Information', 0);
end;

procedure TfmMain.spbtnMSelectClick(Sender: TObject);
begin
  MSelect;
end;

procedure TfmMain.spbtnSelectClick(Sender: TObject);
begin
  Select;
end;

procedure TfmMain.mmiExitClick(Sender: TObject);
begin
  Close;
end;

procedure TfmMain.mmiOpenClick(Sender: TObject);
begin
  FileOpen;
end;

procedure TfmMain.mmiCloseClick(Sender: TObject);
begin
  FileClose;
end;

procedure TfmMain.mmiSelectAllClick(Sender: TObject);
begin
  FManager.SelectAll;
end;

procedure TfmMain.mmiDeselectAllClick(Sender: TObject);
begin
  FManager.DeselectAll;
end;

procedure TfmMain.BtnSelectClick(Sender: TObject);
begin
  Select;
  btnSelect.Down := True;
  btnMSelect.Down := False;
end;

procedure TfmMain.BtnMSelectClick(Sender: TObject);
begin
  MSelect;
  btnSelect.Down := False;
  btnMSelect.Down := True;
end;

procedure TfmMain.BtnOpenClick(Sender: TObject);
begin
  FileOpen;
end;

procedure TfmMain.btnCloseClick(Sender: TObject);
begin
  FileClose;
end;

procedure TfmMain.btnPasteClick(Sender: TObject);
begin
  fmBlockInsert.ShowModal;
end;

procedure TfmMain.btnCopyClick(Sender: TObject);
begin
  if (FManager.Entities <> nil) and (FManager.Entities.Count > 0) then
    FBlockLibrary.CopyAsBlock(FManager.Entities);
end;

procedure TfmMain.Preview1Click(Sender: TObject);
begin
  CreatePreview(Self, FManager, TsgDXFImage(DNavigator.Picture.Graphic));
end;

procedure TfmMain.btnEntityInspectorClick(Sender: TObject);
begin
 if fmEntityInspector.Visible then
   fmEntityInspector.SetFocus
 else
   fmEntityInspector.Show;
end;

procedure TfmMain.InsertBlock(AIndex: Integer; X, Y: Single);
begin
  fmEntityInspector.AddEntity(FBlockLibrary.PasteAsBlock(AIndex, X, Y), True);
end;

procedure TfmMain.FormResize(Sender: TObject);
var
  I, vSize: Integer;
begin
  vSize := 0;
  for I := 1 to sbrMain.Panels.Count - 1 do
    Inc(vSize, sbrMain.Panels[I].Width);
  sbrMain.Panels[0].Width := sbrMain.Width - vSize;
end;

end.
