unit UnitMapProp;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ExtCtrls, Spin, DxDraws, DXSprite,
  { Selbstdef units }
  Sprites, GraphicUtils, Grids, Menus;

type
  TFormMapProp = class(TForm)
    BitBtnHide: TBitBtn;
    ListBoxLib: TListBox;
    GroupBox3: TGroupBox;
    BitBtnUpdate: TBitBtn;
    Panel2: TPanel;
    SpinEditMapX: TSpinEdit;
    Panel3: TPanel;
    SpinEditMapY: TSpinEdit;
    Panel4: TPanel;
    SpinEditMapZ: TSpinEdit;
    CheckBoxTile: TCheckBox;
    GroupBox1: TGroupBox;
    Panel1: TPanel;
    ImagePreview: TImage;
    CheckBoxStretch: TCheckBox;
    PanelX: TPanel;
    PanelY: TPanel;
    CheckBoxKeep: TCheckBox;
    Panel5: TPanel;
    SpinEditPatIdx: TSpinEdit;
    procedure ListBoxLibClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure BitBtnHideClick(Sender: TObject);
    procedure BitBtnUpdateClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure CheckBoxStretchClick(Sender: TObject);
    procedure ListBoxLibDrawItem(Control: TWinControl; Index: Integer;
      Rect: TRect; State: TOwnerDrawState);
    procedure SpinEditChange(Sender: TObject);
  private
    FMapSprite: TMapSprite;
    FDXImageList: TDXImageList;
    OldMap: array of array of Integer;
    procedure UpdateMapSprite;
    procedure ClearPreview;
    procedure UpdateListBox;
  public
    property DXImageList: TDXImageList read FDXImageList write FDXImageList;
    property MapSprite: TMapSprite read FMapSprite write FMapSprite;
  end;

var
  FormMapProp: TFormMapProp;

implementation

uses UnitMain;

{$R *.dfm}

procedure TFormMapProp.ListBoxLibClick(Sender: TObject);
var Rec: TRect;
    Item: TPictureCollectionItem;
    i: Integer;
begin
  i := ListBoxLib.ItemIndex;
  if i < 0 then Exit;
  Item := FDXImageList.Items[i];
  if not CheckBoxStretch.Checked then
    with ImagePreview.Canvas do begin
      Brush.Color := clWhite;
      FillRect(ImagePreview.ClientRect);
      Draw(0, 0, Item.Picture.Graphic);
    end else begin
      Rec := ClientRect;
      ScalePic(Item.Picture.Graphic.Width, Item.Picture.Graphic.Height, ImagePreview.Width, ImagePreview.Height, Rec.Right, Rec.Bottom);
      ClearPreview;
      ImagePreview.Canvas.StretchDraw(Rec, Item.Picture.Graphic);
    end;
  SpinEditPatIdx.MaxValue := Item.PatternCount - 1;
  PanelX.Caption := 'X: '+IntToStr(Item.Width);
  PanelY.Caption := 'Y: '+IntToStr(Item.Height);
end;

procedure TFormMapProp.FormShow(Sender: TObject);
begin
  if FDXImageList.Items.Count = 0 then ClearPreview;
  SpinEditMapX.Value := MapSprite.MapWidth;
  SpinEditMapY.Value := MapSprite.MapHeight;
  SpinEditMapZ.Value := MapSprite.Z;
  UpdateListBox;
  ListBoxLib.ItemIndex := MapSprite.ImageIndex;
  ListBoxLibClick(nil);
end;

procedure TFormMapProp.BitBtnHideClick(Sender: TObject);
begin
  Close;
end;

procedure TFormMapProp.BitBtnUpdateClick(Sender: TObject);
begin
  UpdateMapSprite;
end;

procedure TFormMapProp.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  FormMain.ToolButton11.Down := false;
  Action := caHide;
end;

procedure TFormMapProp.CheckBoxStretchClick(Sender: TObject);
begin
  ListBoxLibClick(nil);
end;

procedure TFormMapProp.ListBoxLibDrawItem(Control: TWinControl;
  Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
  Can: TCanvas;
  Graphic: TGraphic;
  NewRect: TRect;
begin
  Can := (Control as TListBox).Canvas;
  Graphic := FDXImageList.Items[Index].Picture.Graphic;
  if not Assigned(Graphic) then Exit;
  with Can do begin
    FillRect(Rect);
    ScalePic(Graphic.Width, Graphic.Height, ListBoxLib.ItemHeight, ListBoxLib.ItemHeight, Rect.Right, Rect.Bottom);
    NewRect.Left := Rect.Left + (ListBoxLib.ItemHeight - Rect.Right) DIV 2;
    NewRect.Top := Rect.Top + (ListBoxLib.ItemHeight - Rect.Bottom) DIV 2;
    NewRect.Right := NewRect.Left + Rect.Right;
    NewRect.Bottom := NewRect.Top + Rect.Bottom;
    StretchDraw(NewRect, Graphic);
    Rect.Left := Rect.Left + ListBoxLib.ItemHeight;
    Font.Style := [fsBold];
    TextOut(Rect.Left, Rect.Top, (Control as TListBox).Items[Index]);
    Font.Style := [];
    TextOut(Rect.Left, Rect.Top + 16, 'W: ' + IntToStr(Graphic.Width) +
      ' - H: ' + IntToStr(Graphic.Height) + ' - Key: ' + ColorToString(FDXImageList.Items[Index].TransparentColor));
  end;
end;

procedure TFormMapProp.UpdateMapSprite;
var x, y, dx, dy: Integer;
begin
  if (ListBoxLib.Count = 0) or (ListBoxLib.ItemIndex < 0) then Exit;

  dx := MapSprite.MapWidth;
  dy := MapSprite.MapWidth;
  SetLength(OldMap, dx, dy);

  if CheckBoxKeep.Checked then
    for x := 0 to dx - 1 do
      for y := 0 to dy - 1 do
        OldMap[x, y] := MapSprite.Chips[x, y];

  MapSprite.SetMapSize(SpinEditMapX.Value, SpinEditMapY.Value);

  if not CheckBoxKeep.Checked then 
    for x := 0 to dx - 1 do
      for y := 0 to dy - 1 do
        MapSprite.Chips[x, y] := SpinEditPatIdx.Value;

  if CheckBoxKeep.Checked then begin
    if MapSprite.MapWidth < dx then dx := MapSprite.MapWidth;
    if MapSprite.MapHeight < dy then dy := MapSprite.MapHeight;
    for x := 0 to dx - 1 do
      for y := 0 to dy - 1 do
        MapSprite.Chips[x, y] := OldMap[x, y];
  end;

  MapSprite.Tile := CheckBoxTile.Checked;
  
  with MapSprite do begin
    ImageName := ListBoxLib.Items[ListBoxLib.ItemIndex];
    Image := FDXImageList.Items.Find(ImageName);
    ImageIndex := FDXImageList.Items.Find(ImageName).Index;
    Z := SpinEditMapZ.Value;
    Width := Image.Width;
    Height := Image.Height;
  end;
  FormMain.MapModified := true;
end;

procedure TFormMapProp.ClearPreview;
begin
  with ImagePreview.Canvas do begin
     Brush.Color := clWhite;
     FillRect(ImagePreview.ClientRect);
  end;
end;

procedure TFormMapProp.UpdateListBox;
var i: Integer;
begin
  ListBoxLib.Clear;
  for i := 0 to FDXImageList.Items.Count - 1 do
    ListBoxLib.AddItem (FDXImageList.Items[i].Name, FDXImageList.Items[i]);
end;

procedure TFormMapProp.SpinEditChange(Sender: TObject);
begin
  if (Sender as TSpinEdit).Value < (Sender as TSpinEdit).MinValue then (Sender as TSpinEdit).Value := 0;
  if (Sender as TSpinEdit).Value > (Sender as TSpinEdit).MaxValue then (Sender as TSpinEdit).Value := (Sender as TSpinEdit).MaxValue;
end;

end.
