unit TxmpReplace;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Template, StdCtrls, ExtCtrls,
  Functions, Data, OniImgClass, Menus, Buttons;

type
  TForm_TxmpReplace = class(TForm_ToolTemplate)
    group_options: TGroupBox;
    btn_replace: TButton;
    check_transparency: TCheckBox;
    check_fading: TCheckBox;
    panel_txmppreview: TPanel;
    btn_save: TButton;
    image_txmppreview: TImage;
    splitter_txmp: TSplitter;
    group_bmpselect: TGroupBox;
    image_bmppreview: TImage;
    panel_load: TPanel;
    btn_load: TButton;
    opend: TOpenDialog;
    saved: TSaveDialog;
    procedure SelectFile(fileinfo: TFileInfo);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure btn_saveClick(Sender: TObject);
    procedure btn_loadClick(Sender: TObject);
    procedure btn_replaceClick(Sender: TObject);
  private
    OniImage_Old: TOniImage;
    OniImage_New: TOniImage;
    fileid: Integer;
  public
  end;

var
  Form_TxmpReplace: TForm_TxmpReplace;

implementation
{$R *.dfm}
uses Main, OniDataClass;



procedure TForm_TxmpReplace.SelectFile(fileinfo: TFileInfo);
var
  Data: Tdata;
  mem:  TMemoryStream;
  fadingbyte, depthbyte, storebyte: Byte;
begin
  fileid := fileinfo.ID;
  OniDataConnection.LoadDatFilePart(fileid, $88, SizeOf(fadingbyte), @fadingbyte);
  OniDataConnection.LoadDatFilePart(fileid, $89, SizeOf(depthbyte), @depthbyte);
  OniDataConnection.LoadDatFilePart(fileid, $90, SizeOf(storebyte), @storebyte);
  check_fading.Checked := (fadingbyte and $01) > 0;
  check_transparency.Checked := (depthbyte and $04) > 0;

  OniImage_Old.LoadFromTXMP(fileid);
  Data := OniImage_Old.GetAsBMP;
  mem  := TMemoryStream.Create;
  mem.Write(Data[0], Length(Data));
  mem.Seek(0, soFromBeginning);
  image_txmppreview.Picture.Bitmap.LoadFromStream(mem);
  mem.Free;

  group_bmpselect.Enabled := True;
end;


procedure TForm_TxmpReplace.btn_loadClick(Sender: TObject);
var
  mem:   TMemoryStream;
  tempd: Tdata;
begin
  if opend.Execute then
  begin
    OniImage_New.LoadFromBMP(opend.FileName);
    tempd := OniImage_New.GetAsBMP;
    mem   := TMemoryStream.Create;
    mem.Write(tempd[0], Length(tempd));
    mem.Seek(0, soFromBeginning);
    image_bmppreview.Picture.Bitmap.LoadFromStream(mem);
    mem.Free;
    group_options.Enabled := True;
  end;
end;




procedure TForm_TxmpReplace.btn_replaceClick(Sender: TObject);
var
  oldsize, newsize: LongWord;
  old_rawaddr, new_rawaddr: LongWord;
  oldfading: Byte;
  tempd:     Tdata;

  datbyte: Word;
begin
  if filelist.ItemIndex >= 0 then
  begin
    OniDataConnection.LoadDatFilePart(fileid, $88, 1, @oldfading);
    if OniDataConnection.OSisMac then
      OniDataConnection.UpdateDatFilePart(fileid, $A0, 4, @old_rawaddr)
    else
      OniDataConnection.LoadDatFilePart(fileid, $9C, 4, @old_rawaddr);

    if (OniImage_Old.Width <> OniImage_New.Width) or
      (OniImage_Old.Height <> OniImage_New.Height) then
    begin
      if MessageBox(Self.Handle, PChar(
        'Current image and new image have different size' + CrLf +
        '(Current: ' + IntToStr(OniImage_Old.Width) +
        'x' + IntToStr(OniImage_Old.Height) + ' - New: ' +
        IntToStr(OniImage_New.Width) + 'x' + IntToStr(OniImage_New.Height) + ')' + CrLf +
        'Replace anyways?'),
        PChar(filelist.Items.Strings[filelist.ItemIndex]),
        MB_YESNO) = idNo then
        Exit;
    end;

    oldsize := OniImage_Old.GetImageDataSize((oldfading and $01) > 0);

    if check_fading.Checked then
      if not OniImage_New.GetMipMappedImage(tempd) then
        if MessageBox(Self.Handle,
          PChar('Can not create a MipMapped-image (probably because of a wrong dimension).' +
          #13 + #10 + 'Do you want to continue without MipMapping?'), PChar('Warning'),
          MB_YESNO) = ID_YES then
          check_fading.Checked := False
        else
          Exit;

    if not check_fading.Checked then
      tempd := OniImage_New.GetAsData;

    newsize := OniImage_New.GetImageDataSize(check_fading.Checked);
    ShowMessage(IntToStr(newsize));

    if (newsize > oldsize) and (OniDataConnection.Backend = ODB_Dat) then
      new_rawaddr := OniDataConnection.AppendRawFile(
        OniDataConnection.OSisMac, Length(tempd), tempd)
    else
    begin
      new_rawaddr := old_rawaddr;
      OniDataConnection.UpdateRawFile(fileid, $9C, Length(tempd), tempd);
    end;

    datbyte := $00;
    if check_fading.Checked then
      datbyte := datbyte or $01;
    OniDataConnection.UpdateDatFilePart(fileid, $88, 1, @datbyte);
    datbyte := $10;
    if check_transparency.Checked then
      datbyte := datbyte or $04;
    OniDataConnection.UpdateDatFilePart(fileid, $89, 1, @datbyte);
    OniDataConnection.UpdateDatFilePart(fileid, $8C, 2, @OniImage_New.Width);
    OniDataConnection.UpdateDatFilePart(fileid, $8E, 2, @OniImage_New.Height);
    datbyte := $08;
    OniDataConnection.UpdateDatFilePart(fileid, $90, 1, @datbyte);
    if OniDataConnection.OSisMac then
      OniDataConnection.UpdateDatFilePart(fileid, $A0, 4, @new_rawaddr)
    else
      OniDataConnection.UpdateDatFilePart(fileid, $9C, 4, @new_rawaddr);

    ShowMessage('TXMP-image replaced');
  end;
end;




procedure TForm_TxmpReplace.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  OniImage_Old.Free;
  OniImage_New.Free;
  inherited;
end;




procedure TForm_TxmpReplace.FormCreate(Sender: TObject);
begin
  inherited;
  OniImage_Old := TOniImage.Create;
  OniImage_New := TOniImage.Create;
  Self.AllowedExts := 'TXMP';
  Self.OnNewFileSelected := SelectFile;
end;




procedure TForm_TxmpReplace.btn_saveClick(Sender: TObject);
begin
  if saved.Execute then
    OniImage_Old.WriteToBMP(saved.FileName);
end;

begin
  AddToolListEntry('txmpreplace', 'TXMP Replacer', 'TXMP');
end.