unit USpriteSheet;

interface

uses
  Classes,
  SysUtils,
  StrUtils,
  JEN_Header,
  JEN_Math;

type
  TTextureFrame = class(TInterfacedObject, ITextureFrame)
    constructor Create(const Name: string; Texture: ITexture; const Rect: TRectf);
    private
      FName   : string;
      FTexture: ITexture;
      FRect   : TRectf;
    public
    function GetName: PWideChar; stdcall;
    function GetTexture: ITexture; stdcall;
    function GetTextureRect: TRectf; stdcall;
  end;

  TSpriteSheet = class
    constructor Create(const FileName: string);
    private
      FFrameList: IInterfaceList;
      FTexture:   ITexture;
    public
      function GetFrame(const FrameName: string): ITextureFrame;
      function GetFrameI(Idx: Integer): ITextureFrame;
      property Frame[const FrameName: string]: ITextureFrame read GetFrame; default;
      property FrameI[Idx: Integer]: ITextureFrame read GetFrameI;
  end;

implementation

uses
  Main;

constructor TTextureFrame.Create(const Name: string; Texture: ITexture; const Rect: TRectf);
begin
  FName := Name;
  FTexture := Texture;
  FRect := Rect;
end;

function TTextureFrame.GetName: PWideChar;
begin
  Result := PWideChar(FName);
end;

function TTextureFrame.GetTexture: ITexture;
begin
  Result := FTexture
end;

function TTextureFrame.GetTextureRect: TRectf;
begin
  Result := FRect;
end;

constructor TSpriteSheet.Create(const FileName: string);
var
  Xml: IXml;
  I,J: Integer;
  str: string;
  Rect: TRectf;
  Tex: ITexture;
begin
  FFrameList := TInterfaceList.Create;
  Str := ChangeFileExt(FileName,'.dds');
  ResMan.Load(PWideChar(Str), Tex);
  Helpers.CreateXMLReader(Xml, PWideChar(FileName));

  Xml := Xml['dict'];
  for i := 0 to Xml.Count - 1 do
    if(xml.NodeI[i].Content = 'frames') then
    begin
      Xml := Xml.NodeI[i+1];
      break;
    end;

  I:=0;
  while i <= Xml.Count - 1 do
  begin
    with xml.NodeI[i+1] do
      for J := 0 to Count - 1 do
      case AnsiIndexStr(NodeI[j].Content, ['x', 'y', 'width', 'height']) of
        0: Rect.Location.x := StrToInt(NodeI[j+1].Content);
        1: Rect.Location.y := StrToInt(NodeI[j+1].Content);
        2: Rect.Width := StrToInt(NodeI[j+1].Content) / Tex.Width;
        3: Rect.Height := StrToInt(NodeI[j+1].Content) / Tex.Height;
      end;

    FFrameList.Add(ITextureFrame(TTextureFrame.Create(xml.NodeI[i].Content, Tex, Rect)));
    Inc(i, 2);
  end;

end;

function TSpriteSheet.GetFrame(const FrameName: string): ITextureFrame;
var
  i: Integer;
begin
  Result := nil;
  for I := 0 to FFrameList.Count-1 do
    if (ITextureFrame(FFrameList[i]).Name = FrameName) then
      Exit(ITextureFrame(FFrameList[i]));
end;

function TSpriteSheet.GetFrameI(Idx: Integer): ITextureFrame;
begin
  Result := ITextureFrame(FFrameList[Idx]);
end;


end.
