unit Map;

interface
Uses
  GLScene, quod_A, SysUtils, GLObjects, GLfile3DS,
  Forms, JPEG, GLGeomObjects, GLVectorFileObjects;
type
  Tpole=record
    P : TGLPolygon;
    X,Y : word;
    F : byte;
   end;
  TLand=record
    X,Y : word;
    P : array[1..100,1..100] of Tpole;
    GLWorld, GLLand, GLVis, GLUnVis: TGLDummyCube;
    Cube : array[1..50] of TGLCube;
    MofC : byte;
  end;

  var
    L : TLand;
    AutoT : word;

  Procedure CreatPole;
  Procedure CreatCube(X, Y: real);
  Procedure Save(FN: string);
  Procedure Load(FN: string);

implementation
uses
Model, Script;

Procedure Clear;
var
  i : word;
begin
  if L.GLVis<>nil then FreeAndNil(L.glVis);
  if L.GLUNVis<>nil then FreeAndNil(L.glUnVis);
  if L.GLWorld<>nil then FreeAndNil(L.glWorld);
  if L.GLLand<>nil then FreeAndNil(L.glLand);

  L.GLLand:=TGLDummyCube(quod_A.GLWork.AddNewChild(TGLDummyCube));
  L.GLWorld:=TGLDummyCube(quod_A.GLWork.AddNewChild(TGLDummyCube));
  L.GLUnVis:=TGLDummyCube(quod_A.GLWork.AddNewChild(TGLDummyCube));
  L.GLVis:=TGLDummyCube(L.GLWorld.AddNewChild(TGLDummyCube));

  L.GLUnVis.Visible:=false;
  if quod_A.Shadow<>nil then
  quod_A.Shadow.ShadowingObject:=L.GLWorld;


  L.MofC:=0;
  Model.MofP:=0;
  Model.MofD:=0;
  Script.MoFSC:=0;
end;

Procedure Obram;
var
 Ix, Iy: word;
 R : real;
begin
  if (L.X>5) and (L.X>5) then
  begin
    R:=Random ;
    for Ix:=1 to L.X do
    begin
      L.P[Ix,1].P.Nodes[3].Z:=R;
      L.P[Ix,1].P.Nodes[0].Z:=R;
      L.P[Ix,2].P.Nodes[3].Z:=R;

      L.P[Ix,L.Y].P.Nodes[0].Z:=R;
      L.P[Ix,L.Y].P.Nodes[3].Z:=R;
      L.P[Ix,L.Y-1].P.Nodes[0].Z:=R;
      R:=Random ;
      L.P[Ix,1].P.Nodes[2].Z:=R;
      L.P[Ix,1].P.Nodes[1].Z:=R;
      L.P[Ix,2].P.Nodes[2].Z:=R;

      L.P[Ix,L.Y].P.Nodes[1].Z:=R;
      L.P[Ix,L.Y].P.Nodes[2].Z:=R;
      L.P[Ix,L.Y-1].P.Nodes[1].Z:=R;

    end;
    for Ix:=1 to L.Y do
    begin
      L.P[1,Ix].P.Nodes[3].Z:=R;
      L.P[1,Ix].P.Nodes[2].Z:=R;
      L.P[2,Ix].P.Nodes[3].Z:=R;

      L.P[L.X,Ix].P.Nodes[2].Z:=R;
      L.P[L.X,Ix].P.Nodes[3].Z:=R;
      L.P[L.X-1,Ix].P.Nodes[2].Z:=R;

      R:=Random ;
      L.P[1,Ix].P.Nodes[0].Z:=R;
      L.P[1,Ix].P.Nodes[1].Z:=R;
      L.P[2,Ix].P.Nodes[0].Z:=R;

      L.P[L.x,Ix].P.Nodes[1].Z:=R;
      L.P[L.x,Ix].P.Nodes[0].Z:=R;
      L.P[L.x-1,Ix].P.Nodes[1].Z:=R;
    end;
  end;
end;

Procedure CreatPole;
var
 Ix, Iy: word;
begin
 Clear;
 for Ix:=1 to L.X do
 for Iy:=1 to L.Y do
 begin
  L.P[Ix,IY].P:=TGLPolygon(L.GLLand.AddNewChild(TGLPolygon));
//  L.P[Ix,IY].P:=TGLCube(GLWorld.AddNewChild(TGLCube));
  L.P[Ix,IY].P.Name:='MPO'+inttostr(1000000+Ix*1000+Iy);
  L.P[Ix,IY].X:=Ix;
  L.P[Ix,IY].Y:=Iy;
  L.P[Ix,IY].P.Nodes.AddNode(-1,  1,0);
  L.P[Ix,IY].P.Nodes.AddNode( 1,  1,0);
  L.P[Ix,IY].P.Nodes.AddNode( 1, -1,0);
  L.P[Ix,IY].P.Nodes.AddNode(-1, -1,0);

  L.P[Ix,IY].P.Position.SetPoint(2*Ix, 2*Iy, 0);
  L.P[Ix,IY].P.Material.MaterialLibrary:=quod_A.ML1;
  L.P[Ix,IY].P.Material.LibMaterialName:=inttostr(AutoT);
//  L.P[Ix,IY].T:=1;
 end;
 Obram;
end;

procedure CreatCube(X, Y: real);
begin
  L.MofC:=L.MofC+1;
  L.Cube[L.MofC]:=TGLCube(L.GLWorld.AddNewChild(TGLCube));
  L.Cube[L.MofC].Name:='MPC'+inttostr(100+L.MofC);
  L.Cube[L.MofC].Scale.SetVector(2,2,2);
  L.Cube[L.MofC].Position.X:=X;
  L.Cube[L.MofC].Position.Y:=Y;
  L.Cube[L.MofC].Material.MaterialLibrary:=quod_A.ML1;
  L.Cube[L.MofC].Position.Z:=L.Cube[L.MofC].Scale.Z/2;
end;
//////////////////////////////////////////////////////////////////////////
///////////////////////////////////////

procedure saveCube(I: byte; var F : textfile);
begin
  writeln(F,
  inttostr(round(L.Cube[i].Position.X*1000))+'Y'+
  inttostr(round(L.Cube[i].Position.Y*1000))+'Z'+
  inttostr(round(L.Cube[i].Position.Z*1000))+'W'+
  inttostr(round(L.Cube[i].Scale.X*1000))+'H'+
  inttostr(round(L.Cube[i].Scale.Y*1000))+'L'+
  inttostr(round(L.Cube[i].Scale.Z*1000))+'T'+
  L.Cube[i].Material.LibMaterialName);
end;

procedure saveDeko(I: byte; var F : textfile);
begin
  writeln(F, inttostr(Model.DecO[i].Et)+'X'+
  inttostr(round(Model.DecO[i].F.Position.X*1000))+'Y'+
  inttostr(round(Model.DecO[i].F.Position.Y*1000))+'Z'+
  inttostr(round(Model.DecO[i].F.Position.Z*1000))+'W'+
  inttostr(round(Model.DecO[i].F.Scale.X*1000))+'H'+
  inttostr(round(Model.DecO[i].F.Scale.Y*1000))+'L'+
  inttostr(round(Model.DecO[i].F.Scale.Z*1000))+'A'+
  inttostr(round(Model.DecO[i].F.RollAngle)));
end;

procedure savePers(I: byte; var F : textfile);
begin
  writeln(F, inttostr(Model.Pers[i].Et)+'X'+
  inttostr(round(Model.Pers[i].A.Position.X*1000))+'Y'+
  inttostr(round(Model.Pers[i].A.Position.Y*1000))+'Z'+
  inttostr(round(Model.Pers[i].A.Position.Z*1000))+'W'+
  inttostr(round(Model.Pers[i].A.Scale.X*1000))+'H'+
  inttostr(round(Model.Pers[i].A.Scale.Y*1000))+'L'+
  inttostr(round(Model.Pers[i].A.Scale.Z*1000))+'A'+
  inttostr(round(Model.Pers[i].A.RollAngle)));
end;

Procedure Save(FN: string);
var
  F : textfile;
  IX, IY, I : word;
begin
  assignfile(F,fn);
  rewrite(F);
  writeln(F,'__cdmlex quod mapfile__');

  /////////////////
  writeln(F, L.X);
  writeln(F, L.Y);
  For IY:=1 to L.Y do
    begin
      For IX:=1 to L.X do
      write(F, L.P[IX,IY].P.Material.libMaterialname+',');
      writeln(F);
    end;
  ////////////////

  writeln(F,'_Cube_');
  writeln(F,  L.MofC);
  For I:=1 to L.MofC do
  savecube(I,F);

  writeln(F,'_Deco_');
  writeln(F,  Model.MofD);
  For I:=1 to Model.MofD do
  savedeko(I,F);

  writeln(F,'_Pers_');
  writeln(F,  Model.MofP);
  For I:=1 to Model.MofP do
  savepers(I,F);

  closefile(F);
end;
////////////////////////////////////////

///////////////
procedure findYZH(S : string; var X,Y,Z,W,H,L1,A, Q: word);
var
   N: word;
begin
  Q:=length(S);
  For N:=0 to Q do
    begin
      if copy(S,N,1)='X' then X:=N;
      if copy(S,N,1)='Y' then Y:=N;
      if copy(S,N,1)='Z' then Z:=N;
      if copy(S,N,1)='W' then W:=N;
      if copy(S,N,1)='H' then H:=N;
      if copy(S,N,1)='L' then L1:=N;
      if copy(S,N,1)='A' then A:=N;
     end;
end;

procedure loadCube(I: byte; var F : textfile);
var
  Y,Z,W,H,L1,T, Q, N: word;
  S : String;
begin
  readln(F,S);
  Q:=length(S);
  For N:=0 to Q do
    begin
      if copy(S,N,1)='Y' then Y:=N;
      if copy(S,N,1)='Z' then Z:=N;
      if copy(S,N,1)='W' then W:=N;
      if copy(S,N,1)='H' then H:=N;
      if copy(S,N,1)='L' then L1:=N;
      if copy(S,N,1)='T' then T:=N;
     end;
  CreatCube(strtoint(copy(S,0,Y-1))/1000, strtoint(copy(S,Y+1,Z-Y-1))/1000);
  Map.L.Cube[Map.L.MofC].Position.Z:=strtoint(copy(S,Z+1,W-Z-1))/1000;
  Map.L.Cube[Map.L.MofC].Scale.X:=strtoint(copy(S,W+1,H-W-1))/1000;
  Map.L.Cube[Map.L.MofC].Scale.Y:=strtoint(copy(S,H+1,L1-H-1))/1000;
  Map.L.Cube[Map.L.MofC].Scale.Z:=strtoint(copy(S,L1+1,T-L1-1))/1000;
  Map.L.Cube[Map.L.MofC].Material.LibMaterialName:=copy(S,T+1,Q-T);
end;

procedure loadDeco(I: byte; var F : textfile);
var
  X,Y,Z,W,H,L1,A, Q : word;
  S : String;
begin
  readln(F,S);
  findYZH(S,X,Y,Z,W,H,L1,A, Q);
  Model.creatdecor(strtoint(copy(S,0,X-1)),strtoint(copy(S,X+1,Y-X-1))/1000,
                                           strtoint(copy(S,Y+1,Z-Y-1))/1000);
  with Model.DecO[Model.MofD].F do
  begin
    Position.Z:=strtoint(copy(S,Z+1,W-Z-1))/1000;
    Scale.X:=strtoint(copy(S,W+1,H-W-1))/1000;
    Scale.Y:=strtoint(copy(S,H+1,L1-H-1))/1000;
    Scale.Z:=strtoint(copy(S,L1+1,A-L1-1))/1000;
    RollAngle:=strtoint(copy(S,A+1,Q-A));
  end;
end;

procedure loadPers(I: byte; var F : textfile);
var
  X,Y,Z,W,H,L1,A, Q : word;
  S : String;
begin
  readln(F,S);
  findYZH(S,X,Y,Z,W,H,L1,A, Q);
  Model.creatPers(strtoint(copy(S,0,X-1)),strtoint(copy(S,X+1,Y-X-1))/1000,
                                           strtoint(copy(S,Y+1,Z-Y-1))/1000);
  with Model.Pers[Model.MofP].A do
  begin

    Scale.X:=strtoint(copy(S,W+1,H-W-1))/1000;
    Scale.Y:=strtoint(copy(S,H+1,L1-H-1))/1000;
    Scale.Z:=strtoint(copy(S,L1+1,A-L1-1))/1000;
    RollAngle:=strtoint(copy(S,A+1,Q-A));
  end;
end;

procedure loadScrCube(I: byte; var F : textfile);
var
  Y,W,H,A, Q, N: word;
  S, S1, S2 : String;
  B : boolean;
begin
  readln(F,S);
  Q:=length(S);
  For N:=0 to Q do
    begin
      if copy(S,N,1)='Y' then Y:=N;
      if copy(S,N,1)='W' then W:=N;
      if copy(S,N,1)='H' then H:=N;
     end;

  readln(F,S1);
  readln(F,S2);
  if S1='TRUE' then
  B:=true else B:=false;

  CreatScrCube(strtoint(copy(S,0,Y-1))/1000, strtoint(copy(S,Y+1,W-Y-1))/1000,
  strtoint(copy(S,W+1,H-W-1))/1000,  strtoint(copy(S,H+1,Q-H))/1000, S1,B);
end;

Procedure Load(FN: string);
var
  F : textfile;
  IX, IY, I, N, II, TT, M : word;
  S : string;
begin
  assignfile(F,extractfilepath(Application.ExeName)+fn);
  reset(F);
  readln(F, S);
  if S='__cdmlex quod mapfile__' then
    begin
      readln(F, L.X);
      readln(F, L.Y);
      CreatPole;
      for IY:=1 to L.Y do
        begin
          readln(F,S);
          TT:=0;
          IX:=0;
          For I:=1 to length(S) do
          if copy(S,I,1)=',' then
            begin
              IX:=IX+1;
              L.P[IX,IY].P.Material.LibMaterialName:=copy(S,TT+1,I-TT-1);
              TT:=I;
            end;
        end;
///   Куб:
      readln(F, S);
      readln(F, N);
      for I:=1 to N do
      loadcube(I, F);
///   Декорации:
      readln(F, S);
      readln(F, N);
      for I:=1 to N do
      loaddeco(I, F);
///   Живые объекты:
      readln(F, S);
      readln(F, N);
      for I:=1 to N do
      loadpers(I, F);
///   Скрипты:
      readln(F, S);
      readln(F, N);
      for I:=1 to N do
      loadScrCube(I, F);
    end;
  closefile(F);
end;
end.
