unit CTypes;

interface
uses Classes, Graphics;


type
 TObjProp=record
  Name, Value :string;
 end;
 TPropsList=class(TList)
  private
   FDefaultVal: string;
   function GetValue(const AName:string):string;
   procedure SetValue(const AName, AValue:string);
  public
   procedure AddProp(AName, AValue:string);
  // function NameOf(AValue:string):string;
   function IndexOfValue(AValue:string):Integer;
   function IndexOfName(AName:string):Integer;
   property Values[const AName:string]:string read GetValue write SetValue;
   property DefaultValue:string read FDefaultVal write FDefaultVal;
   constructor Create;
   destructor Free;
//   property Values[const AIndex:Integer]:string read GetValueI write SetValueI;
 end;
 TObjPos=record
  x, y:single;
 end;
 TItemType=(itOther, itBot, itBuilding, itAlien, itPortable, itDecor);
 TCCat = class
  public
   //category: word;
   CatName: string;
   IncProps:TStringList;
   Props: TPropsList;
   OptProps: TPropsList;
   ItemType: TItemType;
   Radius:single;
//   Image: string;
   Photo: TPicture;
   LongName: string;
   constructor Create;
   destructor Free;
 end;
 TCObject=class//(TCCat)
  public
   category: TCCat;
   position: TObjPos;
   orientation: single;
   Props: TPropsList;
 end;
 TCatsList=class(TList)
  private
   function GetCat(const AName:string):TCCat;
  public
   function GetCatByLongName(const s:string):TCCat;
   property Cats[const AName:string]:TCCat read GetCat;
 end;

 TFloatRect=record
  Left, Top, Right, Bottom: single;
 end;

function ObjPosToStr(const AObjPos:TObjPos):string;
function StrToObjPos(s:string):TObjPos;
function StrToDir(s:string):single;

var AllCats: TCatsList;
//function GetCatByName(const AName:string):TCCat;

implementation

uses SysUtils, StrUtils;

function ObjPosToStr(const AObjPos:TObjPos):string;
begin
 Result := StringReplace(FloatToStrF(AObjPos.x,ffFixed,5,2),',','.',[])+';'+
           StringReplace(FloatToStrF(AObjPos.y,ffFixed,5,2),',','.',[]);
end;

function StrToObjPos(s:string):TObjPos;
var sp:byte;
begin
 s := StringReplace(s,'.',',',[rfReplaceAll]);
 sp := PosEx(';',s);
 Result.x := StrToFloat(LeftStr(s, sp-1));
 Result.y := StrToFloat(RightStr(s, Length(s)-sp));
end;

function StrToDir(s:string):single;
begin
 Result := StrToFLoat(StringReplace(s, '.',',',[]));
end;

function TPropsList.IndexOfName(AName:string):Integer;
var i:integer;
begin
 Result := -1;
 if Count<1 then exit;
 for i := 0 to Count-1 do if TObjProp(Items[i]^).Name=AName then begin
  Result := i;
  break;
 end;
end;

function TPropsList.IndexOfValue(AValue:string):Integer;
var i:integer;
begin
 Result := -1;
 for i := 0 to Count-1 do if TObjProp(Items[i]^).Value=AValue then begin
  Result := i;
  break;
 end;
end;

procedure TPropsList.SetValue(const AName, AValue:string);
var id:integer; ip:^TObjProp;
begin
 id := IndexOfName(AName);
 if id<0 then begin
  //GetMem(ip, SizeOf(TObjProp));
  New(ip);
  ip^.Name := AName;
  ip^.Value := AValue;
  Add(ip);
 end else begin
  ip := Items[id];
  ip^.Value := AValue;
 end;
end;

function TPropsList.GetValue(const AName:string):string;
var r:integer;
begin
 r := IndexOfName(AName);
 if (r<0) then begin
  Result := FDefaultVal;
  exit;
 end;
 Result := TObjProp(Items[r]^).Value;
end;

procedure TPropsList.AddProp(AName, AValue:string);
begin
 SetValue(AName, AValue);
end;

constructor TPropsList.Create;
begin
 FDefaultVal := '';
end;

destructor TPropsList.Free;
var i:integer;
begin
 for i := 0 to Count-1 do FreeMem(Items[i]);
 inherited Free;
end;

constructor TCCat.Create;
begin
 inherited;
 Props := TPropsList.Create;
 OptProps := TPropsList.Create;
 IncProps := TStringList.Create;
end;

destructor TCCat.Free;
begin
 Props.Free;
 OptProps.Free;
 IncProps.Free;
 inherited Free;
end;

function TCatsList.GetCat(const AName:string):TCCat;
var i:integer;
begin
 Result := nil;
 for i := 0 to Count-1 do if TCCat(Items[i]).CatName=AName then begin
  Result := TCCat(Items[i]);
  break;
 end;
end;

function TCatsList.GetCatByLongName(const s:string):TCCat;
var i:word; r:TCatsList;
begin
 r := TCatsList.Create;
 Result := nil;
 for i := 0 to Count-1 do if TCCat(Items[i]).LongName=s then begin
  r.Add(Items[i]);
 end;
 if r.Count>0 then Result := TCCat(r.Items[Random(r.Count)]) else Result := nil;
end;


initialization

AllCats := TCatsList.Create;

finalization

AllCats.Free;

end.
