{****************************************************************************}
{Unit VENOMMNG - it is a helper unit for graphics library VenomGFX.          }
{It is not intended to be called by user, because it is used internaly by    }
{      image and font loaders                                                }
{****************************************************************************}
unit VenomMng;
{$IFDEF VER2}{$DEFINE NEWFPC}{$ENDIF}
{$IFDEF VER3}{$DEFINE NEWFPC}{$ENDIF}
{$IFDEF NEWFPC}{$CALLING OLDFPCCALL}{$ENDIF}

interface

const venom_image_loaders = 15;
      venom_font_loaders = 6;
      max_venom_font = 50;
      max_co_volat_po_init_graph = 6;

type po_init_graph = procedure;

var Venom_Image_Mng:record
    pocet:byte;  {pocet registrovanych koncovek souboru}
    koncovka:array[1..venom_image_loaders] of string[3];
    loader:array[1..venom_image_loaders] of pointer;
    end;

    Venom_FontEngines_pocet:byte; {pocet registrovanych koncovek souboru}

    Venom_FontEngines_Mng:array[1..venom_font_loaders] of record
    koncovka:string[3];
    loadproc:pointer;
    prepchar:pointer;
    outstring:pointer;
    setparams:pointer;
    getinfo:pointer;
    deleteproc:pointer;
    end;

    LoadedFontList:array[1..max_venom_font] of record
    rez:string[128];
    typ:byte; {cislo FontEngine ve Venom_FontEngines_Mng}
    fontptr:pointer;
    end;


    Venom_co_volat_po_Init_Graph:array[1..max_co_volat_po_init_graph] of po_init_graph;


var LoadedFontNum:byte;

Procedure RegisterImageLoader(s:string;p:pointer);
Function Get_Image_Loader(s:string):pointer;

Procedure RegisterFontEngine(s:string;loadproc,prepchar,outproc,paramsproc,getinfo,delproc:pointer);
Function RegisterFontFile(s:string):byte;
Function Venom_mng_PrepChar(znak:word):pointer;
Procedure Venom_mng_SetFontStyle(rez:string;velikost,parametry:byte);
Procedure Venom_mng_outstring(kam:pointer;x,y:longint;s:string;color:word);
Function Venom_mng_GetFontInfo(param:longint):longint;
Procedure Venom_mngr_kill_font(rez:string);

Procedure Venom_mngr_Init_graph_list(p:po_init_graph);


implementation
var aktfontvel:byte;
    aktfontslot:byte;
    aktinit_graphslot:byte;

type
loadfontfunc=Function(s:string;size:byte):pointer;
prepcharfunc=Function(fnt:pointer;znak:word):pointer;
outfontproc=Procedure(kam:pointer;x,y:longint;s:string;fnt:pointer;color:word);
setparamsproc=Procedure(fnt:pointer;size,flags:byte);
getinfofunc=Function(fnt:pointer;param:longint):longint;
removefontproc=Procedure(fnt:pointer);


Procedure StartUnit;
{Je volano automaticky pri startu jednotky}
var a:byte;
begin
{vynulujeme loadery obrazku}
Venom_Image_Mng.pocet:=0;
for a:=1 to venom_image_loaders do
    begin
    Venom_Image_Mng.koncovka[a]:='';
    Venom_Image_Mng.loader[a]:=nil;
    end;

{vynulujeme engine na fonty}
Venom_FontEngines_pocet:=0;
for a:=1 to venom_font_loaders do
    begin
    Venom_FontEngines_Mng[a].koncovka:='';
    Venom_FontEngines_Mng[a].loadproc:=nil;
    Venom_FontEngines_Mng[a].outstring:=nil;
    Venom_FontEngines_Mng[a].setparams:=nil;
    Venom_FontEngines_Mng[a].getinfo:=nil;
    Venom_FontEngines_Mng[a].deleteproc:=nil;
    end;

{a vynulujeme samotnou tabulku fontu}
LoadedFontNum:=0;
for a:=1 to max_venom_font do
    begin
    LoadedFontList[a].typ:=0;
    LoadedFontList[a].fontptr:=nil;
    end;

aktfontvel:=16;
aktfontslot:=0;

{vynuluju seznam procedur, ktere automaticky volat po prvnim VenomGFX.Init_Graph}
aktinit_graphslot:=0;
for a:=1 to max_co_volat_po_init_graph do
    Venom_co_volat_po_Init_Graph[a]:=nil;

end;


Procedure RegisterImageLoader(s:string;p:pointer);
{Toto je volano automaticky pri startu jednotlivych jednotek obsahujicich
 loadery obrazku}
var a:byte;
begin
for a:=1 to Length(s) do s[a]:=UpCase(s[a]);
for a:=1 to Venom_Image_Mng.pocet do  {napred zkontroluju, jestli neni dany}
    if Venom_Image_Mng.koncovka[a]=s then{typ uz zaregistrovan}
       begin  {jestli jo, tak preregistruju}
       Venom_Image_Mng.loader[a]:=p;
       Exit;
       end;
{zjistili jsme, ze dany loader jeste registrovan neni}
inc(Venom_Image_Mng.pocet);
a:=Venom_Image_Mng.pocet;
Venom_Image_Mng.koncovka[a]:=s;
Venom_Image_Mng.loader[a]:=p;
end;

Function Get_Image_Loader(s:string):pointer;
{Je volano z jednotky VenomGFX z obecneho nacitace obrazku}
var a:byte;
begin
for a:=1 to Length(s) do s[a]:=UpCase(s[a]);
for a:=1 to Venom_Image_Mng.pocet do
    if Venom_Image_Mng.koncovka[a]=s then Exit(Venom_Image_Mng.loader[a]);
Get_Image_Loader:=nil;
end;


Procedure RegisterFontEngine(s:string;loadproc,prepchar,outproc,paramsproc,getinfo,delproc:pointer);
{Toto je volano automaticky pri startu jednotlivych jednotek obhaspodarujich
 konkratni fonty}
var a:byte;
begin
inc(Venom_FontEngines_pocet);
a:=Venom_FontEngines_pocet;

Venom_FontEngines_Mng[a].koncovka:=s;

Venom_FontEngines_Mng[a].loadproc:=loadproc;
Venom_FontEngines_Mng[a].prepchar:=prepchar;
Venom_FontEngines_Mng[a].outstring:=outproc;
Venom_FontEngines_Mng[a].setparams:=paramsproc;
Venom_FontEngines_Mng[a].getinfo:=getinfo;
Venom_FontEngines_Mng[a].deleteproc:=delproc;
end;


Function RegisterFontFile(s:string):byte;
var a,b:byte;
    p,proc:pointer;
    konc:string;
    is_new:boolean;
begin
RegisterFontFile:=0;
for a:=1 to Length(s) do s[a]:=UpCase(s[a]);

if s='VGA' then s:=s+'.   ';  {specialni osetreni VGA fontu}

for a:=Length(s) downto 1 do
    if s[a]='.' then Break;
if a=1 then Exit;

konc:=Copy(s,a+1,255);

for a:=1 to LoadedFontNum do
    if s=LoadedFontList[a].rez then Exit(a); {font jiz mame nacteny? Bezva.}

{Projeli jsme cely seznam a zjistili, ze font jeste nacteny nemame}
if LoadedFontNum=MAX_VENOM_FONT then Exit(0); {plna tabulka? Konec}


{Ted budeme muset zjistit, jestli jde o registrovanou priponu}
for a:=1 to Venom_FontEngines_pocet do
    if Venom_FontEngines_Mng[a].koncovka=konc then
       begin   {je to dobre, pro tento typ souboru zname loader}
       proc:=Venom_FontEngines_Mng[a].loadproc;    {pripravim si loader}
       p:=loadfontfunc(proc)(s,16);                {a loaderem nactu font}
       if p=nil then Exit(0);
       inc(LoadedFontNum);
       LoadedFontList[LoadedFontNum].rez:=s;
       LoadedFontList[LoadedFontNum].typ:=a;
       LoadedFontList[LoadedFontNum].fontptr:=p;
       Exit(LoadedFontNum);
       end;

RegisterFontFile:=0;  {o registrovanou priponu nejde...}
end;


Procedure Venom_mng_SetFontStyle(rez:string;velikost,parametry:byte);
var b,typ:byte;
    p,proc:pointer;

begin
b:=RegisterFontFile(rez);
AktFontSlot:=b;
if b<>0 then
   begin
   p:=LoadedFontList[AktFontSlot].fontptr;
   typ:=LoadedFontList[AktFontSlot].typ;

   proc:=Venom_FontEngines_Mng[LoadedFontList[b].typ].setparams;
   setparamsproc(proc)(p,velikost,parametry);

   aktfontvel:=velikost;
   end
   else aktfontvel:=0;
end;


Function Venom_mng_PrepChar(znak:word):pointer;
var typ:byte;
    p,pc:pointer;

begin
if AktFontSlot=0 then Venom_mng_PrepChar:=nil
   else begin
   p:=LoadedFontList[AktFontSlot].fontptr;
   typ:=LoadedFontList[AktFontSlot].typ;
   pc:=Venom_FontEngines_Mng[typ].prepchar;
   Venom_mng_PrepChar:=prepcharfunc(pc)(p,znak);
   end;
end;


Procedure Venom_mng_outstring(kam:pointer;x,y:longint;s:string;color:word);
var typ:byte;
    p,os:pointer;
begin
if aktfontslot<>0 then
   begin
   p:=LoadedFontList[AktFontSlot].fontptr;
   typ:=LoadedFontList[AktFontSlot].typ;
   os:=Venom_FontEngines_Mng[typ].outstring;
   outfontproc(os)(kam,x,y,s,p,color);
   end;
end;


Function Venom_mng_GetFontInfo(param:longint):longint;
var typ:byte;
    p,gi:pointer;
begin
if AktFontSlot=0 then Venom_mng_GetFontInfo:=0
   else begin
   p:=LoadedFontList[AktFontSlot].fontptr;
   typ:=LoadedFontList[AktFontSlot].typ;
   gi:=Venom_FontEngines_Mng[typ].getinfo;
   Venom_mng_GetFontInfo:=getinfofunc(gi)(p,param);
   end;

end;


Procedure Venom_mngr_kill_font(rez:string);
var a,b,c:byte;
    konc:string;
    p,dp:pointer;
begin
for a:=1 to Length(rez) do rez[a]:=UpCase(rez[a]);
if rez='VGA' then rez:=rez+'.   ';
for a:=1 to LoadedFontNum do
    if rez=LoadedFontList[a].rez then {nalezli jsme dany font? Bezva.}
       begin
       p:=LoadedFontList[a].fontptr;  {odkaz na font}
       b:=LoadedFontList[a].typ;      {jaky mame pouzit engine?}
       dp:=Venom_FontEngines_Mng[b].deleteproc; {pripravim odstranovac}
       removefontproc(dp)(p);
       {mame smazano, takze jeste musim aktualizovat seznam nactenych fontu}
       for c:=a to LoadedFontNum do
           begin
           LoadedFontList[c].rez:=LoadedFontList[c+1].rez;
           LoadedFontList[c].typ:=LoadedFontList[c+1].typ;
           LoadedFontList[c].fontptr:=LoadedFontList[c+1].fontptr;
           end;
       dec(LoadedFontNum);
       Exit;
       end;
end;


Procedure Venom_mngr_Init_graph_list(p:po_init_graph);
begin
inc(aktinit_graphslot);
Venom_co_volat_po_Init_Graph[aktinit_graphslot]:=p;
end;


begin
StartUnit;
end.
