unit untData;

{$mode Delphi}{$H+}

interface

uses
  Classes, SysUtils, SQLDB, DB, SQLite3Conn, fgl, untCard, Dialogs;

type
  { TCardDatabase }

  TCardDatabase = class
  private
    FDatabase: TSQLite3Connection;
    FTrans: TSQLTransaction;
    FQuery: TSQLQuery;
  public
    constructor Create;
    destructor Destroy; override;
    function SearchCards(keyword: string): TFPGList<TCard>;
    function GetCards(list: TFPGList<Int64>): TFPGList<TCard>;
    function GetCardName(cardId: Int64): string;
    function GetCardInfo(cardId: Int64): TCard;
  end;

type

  { TCardUtil }

  TCardUtil = class
  public
    class function ParseCardType(typ: Int64): TCardType;
    class function IsXyzMonster(typ: Int64): Boolean;
    class function IsLinkMonster(typ: Int64): Boolean;
  end;


var
  Cards: TCardDatabase;

implementation

uses
  untConfig;

{ TCardDatabase }

constructor TCardDatabase.Create;
var
  APath: string;
begin
  APath:= TConfigReader.GetMDPro3InstallPath() + DirectorySeparator + 'Data' + DirectorySeparator + 'locales' + DirectorySeparator + 'zh-CN' + DirectorySeparator + 'cards.cdb';
  if (not FileExists(APath)) then raise EFileNotFoundException.CreateFmt('数据库 [%s] 不存在，请重新安装 MDPro3', [APath]);
  FTrans := TSQLTransaction.Create(nil);
  FDatabase := TSQLite3Connection.Create(nil);
  FDatabase.DatabaseName := APath;
  FDatabase.Transaction := FTrans;
  FDatabase.Open;
  FQuery := TSQLQuery.Create(nil);
  FQuery.DataBase := FDatabase;
  FQuery.Transaction := FTrans;
end;

destructor TCardDatabase.Destroy;
begin
  if FQuery <> nil then begin
    FQuery.Close;
    FQuery.Free;
  end;
  if FDatabase <> nil then begin
    FDatabase.Close();
    FDatabase.Free;
  end;
  if FTrans <> nil then begin
    FTrans.Free;
  end;
  inherited Destroy;
end;

function TCardDatabase.SearchCards(keyword: string): TFPGList<TCard>;
var
  item: TCard;
  list: TFPGList<TCard>;
  AType: Int64;
begin
  list := TFPGList<TCard>.Create;
  FQuery.Close;
  FQuery.SQL.Text:= 'select t.id, t.name, d.type from texts t left join datas d on t.id = d.id where t.name like ''%'+keyword+'%'';';
  FQuery.Open;
  while (not FQuery.EOF) do begin
    item := TCard.Create;
    item.CardId := FQuery.FieldByName('id').AsLargeInt;
    item.CardName:= FQuery.FieldByName('name').AsString;
    AType:= FQuery.FieldByName('type').AsLargeInt;
    item.CardType:= TCardUtil.ParseCardType(AType);
    item.IsXyzMonster:= TCardUtil.IsXyzMonster(AType);
    item.IsLinkMonster:= TCardUtil.IsLinkMonster(AType);
    list.Add(item);
    FQuery.Next;
  end;
  FQuery.Close;
  Exit(list);
end;

function TCardDatabase.GetCards(list: TFPGList<Int64>): TFPGList<TCard>;
var
  i: Integer;
  item: TCard;
  cardList: TFPGList<TCard>;
  inStr: string = '';
begin
  for i := 0 to list.Count - 1 do begin
    if i > 0 then begin
      inStr += ',';
    end;
    inStr += Format('%d', [list[i]]);
  end;
  cardList := TFPGList<TCard>.Create;
  FQuery.Close;
  FQuery.SQL.Text:= 'select t.id, t.name from texts t where t.id in (' + inStr + ');';
  FQuery.Open;
  while (not FQuery.EOF) do begin
    item := TCard.Create;
    item.CardId := FQuery.FieldByName('id').AsLargeInt;
    item.CardName:= FQuery.FieldByName('name').AsString;
    cardList.Add(item);
    FQuery.Next;
  end;
  FQuery.Close;
  Exit(cardList);
end;

function TCardDatabase.GetCardName(cardId: Int64): string;
var
  cn: string = '';
begin
  FQuery.Close;
  FQuery.SQL.Text:= 'select t.name from texts t where t.id = ' + IntToStr(cardId) + ';';
  FQuery.Open;
  while (not FQuery.EOF) do begin
    cn := FQuery.FieldByName('name').AsString;
    Break;
  end;
  FQuery.Close;
  Exit(cn);
end;

function TCardDatabase.GetCardInfo(cardId: Int64): TCard;
var
  c: TCard = nil;
  AType: Int64;
begin
  FQuery.Close;
  FQuery.SQL.Text:= 'select t.id, t.name, d.type from texts t left join datas d on t.id = d.id where t.id = ' + IntToStr(cardId) + ';';
  FQuery.Open;
  while (not FQuery.EOF) do begin
    c := TCard.Create;
    c.CardId := FQuery.FieldByName('id').AsLargeInt;
    c.CardName:= FQuery.FieldByName('name').AsString;
    AType:= FQuery.FieldByName('type').AsLargeInt;
    c.CardType:= TCardUtil.ParseCardType(AType);
    c.IsXyzMonster:= TCardUtil.IsXyzMonster(AType);
    c.IsLinkMonster:= TCardUtil.IsLinkMonster(AType);
    Break;
  end;
  FQuery.Close;
  Exit(c);
end;

{ TCardUtil }

class function TCardUtil.ParseCardType(typ: Int64): TCardType;
begin
  if (typ and $1000000 <> 0) then begin
    Exit(ctPendulum);
  end else if (typ and $4 <> 0) then begin
    Exit(ctTrap);
  end else if (typ and $2 <> 0) then begin
    Exit(ctSpell);
  end else begin
    Exit(ctMonster);
  end;
end;

class function TCardUtil.IsXyzMonster(typ: Int64): Boolean;
var
  AType: TCardType;
begin
  AType:= ParseCardType(typ);
  if (AType = ctMonster) or (AType = ctPendulum) then begin
    Exit(typ and $800000 <> 0);
  end else begin
    Exit(False);
  end;
end;

class function TCardUtil.IsLinkMonster(typ: Int64): Boolean;
var
  AType: TCardType;
begin
  AType:= ParseCardType(typ);
  if (AType = ctMonster) then begin
    Exit(typ and $4000000 <> 0);
  end else begin
    Exit(False);
  end;
end;


initialization
  Cards := TCardDatabase.Create;

finalization
  Cards.Free;

end.

