with
  text_io,
  ada.integer_text_io,
  ada.long_float_text_io,
  ada.numerics,
  ada.numerics.long_elementary_functions;

procedure dodecahedron is

  edge     : array (integer range 1 .. 30, integer range 1 .. 2) of integer;
  face     : array (integer range 1 .. 12, integer range 1 .. 5) of integer;
  xo,yo,zo : array (integer range 1 .. 20) of long_float;

  procedure initia is

    use
      ada.numerics.long_elementary_functions;

    c1,c2,c3 : long_float;

  begin
    c1 := (1.0 + sqrt(5.0)) / 2.0 / sqrt(3.0);
    c2 := 2.0 / (1.0 + sqrt(5.0)) / sqrt(3.0);
    c3 := 1.0 / sqrt(3.0);

    -- initiate coordinates
    xo(1) := 0.0;
    yo(1) := c2;
    zo(1) := c1;

    xo(2) := 0.0;
    yo(2) := -c2;
    zo(2) := c1;

    xo(3) := c3;
    yo(3) := c3;
    zo(3) := c3;

    xo(4) := -c3;
    yo(4) := c3;
    zo(4) := c3;

    xo(5) := -c3;
    yo(5) := -c3;
    zo(5) := c3;

    xo(6) := c3;
    yo(6) := -c3;
    zo(6) := c3;

    xo(7) := c1;
    yo(7) := 0.0;
    zo(7) := c2;

    xo(8) := -c1;
    yo(8) := 0.0;
    zo(8) := c2;

    xo(9) := c2;
    yo(9) := c1;
    zo(9) := 0.0;

    xo(10) := -c2;
    yo(10) := c1;
    zo(10) := 0.0;

    xo(11) := -c2;
    yo(11) := -c1;
    zo(11) := 0.0;

    xo(12) := c2;
    yo(12) := -c1;
    zo(12) := 0.0;

    xo(13) := c1;
    yo(13) := 0.0;
    zo(13) := -c2;

    xo(14) := -c1;
    yo(14) := 0.0;
    zo(14) := -c2;

    xo(15) := c3;
    yo(15) := c3;
    zo(15) := -c3;

    xo(16) := -c3;
    yo(16) := c3;
    zo(16) := -c3;

    xo(17) := -c3;
    yo(17) := -c3;
    zo(17) := -c3;

    xo(18) := c3;
    yo(18) := -c3;
    zo(18) := -c3;

    xo(19) := 0.0;
    yo(19) := c2;
    zo(19) := -c1;

    xo(20) := 0.0;
    yo(20) := -c2;
    zo(20) := -c1;

    -- initiate edge
    edge(1,1) := 1;
    edge(1,2) := 2;

    edge(2,1) := 1;
    edge(2,2) := 3;

    edge(3,1) := 1;
    edge(3,2) := 4;

    edge(4,1) := 2;
    edge(4,2) := 5;

    edge(5,1) := 2;
    edge(5,2) := 6;

    edge(6,1) := 3;
    edge(6,2) := 7;

    edge(7,1) := 3;
    edge(7,2) := 9;

    edge(8,1) := 4;
    edge(8,2) := 8;

    edge(9,1) := 4;
    edge(9,2) := 10;

    edge(10,1) := 5;
    edge(10,2) := 8;

    edge(11,1) := 5;
    edge(11,2) := 11;

    edge(12,1) := 6;
    edge(12,2) := 7;

    edge(13,1) := 6;
    edge(13,2) := 12;

    edge(14,1) := 7;
    edge(14,2) := 13;

    edge(15,1) := 8;
    edge(15,2) := 14;

    edge(16,1) := 9;
    edge(16,2) := 10;

    edge(17,1) := 9;
    edge(17,2) := 15;

    edge(18,1) := 10;
    edge(18,2) := 16;

    edge(19,1) := 11;
    edge(19,2) := 12;

    edge(20,1) := 11;
    edge(20,2) := 17;

    edge(21,1) := 12;
    edge(21,2) := 18;

    edge(22,1) := 13;
    edge(22,2) := 15;

    edge(23,1) := 13;
    edge(23,2) := 18;

    edge(24,1) := 14;
    edge(24,2) := 16;

    edge(25,1) := 14;
    edge(25,2) := 17;

    edge(26,1) := 15;
    edge(26,2) := 19;

    edge(27,1) := 16;
    edge(27,2) := 19;

    edge(28,1) := 17;
    edge(28,2) := 20;

    edge(29,1) := 18;
    edge(29,2) := 20;

    edge(30,1) := 19;
    edge(30,2) := 20;

    -- initiate face
    face(1,1) := 1;
    face(1,2) := 2;
    face(1,3) := 6;
    face(1,4) := 7;
    face(1,5) := 3;

    face(2,1) := 1;
    face(2,2) := 3;
    face(2,3) := 9;
    face(2,4) := 10;
    face(2,5) := 4;

    face(3,1) := 1;
    face(3,2) := 4;
    face(3,3) := 8;
    face(3,4) := 5;
    face(3,5) := 2;

    face(4,1) := 2;
    face(4,2) := 5;
    face(4,3) := 11;
    face(4,4) := 12;
    face(4,5) := 6;

    face(5,1) := 3;
    face(5,2) := 7;
    face(5,3) := 13;
    face(5,4) := 15;
    face(5,5) := 9;

    face(6,1) := 4;
    face(6,2) := 10;
    face(6,3) := 16;
    face(6,4) := 14;
    face(6,5) := 8;

    face(7,1) := 5;
    face(7,2) := 8;
    face(7,3) := 14;
    face(7,4) := 17;
    face(7,5) := 11;

    face(8,1) := 6;
    face(8,2) := 12;
    face(8,3) := 18;
    face(8,4) := 13;
    face(8,5) := 7;

    face(9,1) := 9;
    face(9,2) := 15;
    face(9,3) := 19;
    face(9,4) := 16;
    face(9,5) := 10;

    face(10,1) := 11;
    face(10,2) := 17;
    face(10,3) := 20;
    face(10,4) := 18;
    face(10,5) := 12;

    face(11,1) := 13;
    face(11,2) := 18;
    face(11,3) := 20;
    face(11,4) := 19;
    face(11,5) := 15;

    face(12,1) := 14;
    face(12,2) := 16;
    face(12,3) := 19;
    face(12,4) := 20;
    face(12,5) := 17;
  end initia;

  procedure input is

    use
      text_io,
      ada.integer_text_io,
      ada.long_float_text_io;

    maxls,maxminor,maxlist,h    : integer;
    lstol,mntol,mnref,mu10,mu01 : long_float;
    io                          : file_type;

  begin
    create(io, out_file, "input.txt");

    -- solution parameters
    lstol := 1.0E-01;
    maxls := 20;
    mntol := 1.0E-05;
    mnref := 1.0;
    maxminor := 600;
    maxlist := 3;

    put(io,"        lstol     maxls             mntol             mnref  maxminor   maxlist");
    new_line(io);
    put(io,":");
    new_line(io);
    put(io,lstol,2,6,3);
    put(io,"     ");
    put(io,maxls,5);
    put(io,"     ");
    put(io,mntol,2,6,3);
    put(io,"     ");
    put(io,mnref,2,6,3);
    put(io,"     ");
    put(io,maxminor,5);
    put(io,"     ");
    put(io,maxlist,5);
    new_line(io);

    -- material parameters
    h := 2;
    mu10 := 0.3750;
    mu01 := -0.1250;

    new_line(io);
    new_line(io);
    put(io,"    h              mu10              mu01");
    new_line(io);
    put(io,":");
    new_line(io);
    put(io,h,5);
    put(io,"     ");
    put(io,mu10,2,6,3);
    put(io,"     ");
    put(io,mu01,2,6,3);
    new_line(io);

    -- node coordinates
    new_line(io);
    new_line(io);
    put(io," node           coord x           coord y           coord z");
    new_line(io);
    put(io,":");
    new_line(io);
    put(io,"   20");
    new_line(io);

    new_line(io);
    for glob in 1 .. 20 loop
      put(io,glob,5);
      put(io,"     ");
      put(io,xo(glob),2,6,3);
      put(io,"     ");
      put(io,yo(glob),2,6,3);
      put(io,"     ");
      put(io,zo(glob),2,6,3);
      new_line(io);
    end loop;

    -- elements
    new_line(io);
    new_line(io);
    put(io," elem      node      node              area");
    new_line(io);
    put(io,":");
    new_line(io);
    put(io,"   30");
    new_line(io);

    new_line(io);
    for e in 1 .. 30 loop
      put(io,e,5);
      for loc in 1 .. 2 loop
        put(io,"     ");
        put(io,edge(e,loc),5);
      end loop;
      put(io,"      1.000000E+00");
      new_line(io);
    end loop;

    -- known displacements
    new_line(io);
    new_line(io);
    put(io," node      axis             displ");
    new_line(io);
    put(io,":");
    new_line(io);
    put(io,"   12");
    new_line(io);

    new_line(io);

    put(io,"    1         1      0.000000E+00");
    new_line(io);
    put(io,"    2         1      0.000000E+00");
    new_line(io);
    put(io,"   19         1      0.000000E+00");
    new_line(io);
    put(io,"   20         1      0.000000E+00");
    new_line(io);

    put(io,"    7         2      0.000000E+00");
    new_line(io);
    put(io,"    8         2      0.000000E+00");
    new_line(io);
    put(io,"   13         2      0.000000E+00");
    new_line(io);
    put(io,"   14         2      0.000000E+00");
    new_line(io);

    put(io,"    9         3      0.000000E+00");
    new_line(io);
    put(io,"   10         3      0.000000E+00");
    new_line(io);
    put(io,"   11         3      0.000000E+00");
    new_line(io);
    put(io,"   12         3      0.000000E+00");
    new_line(io);

    -- force
    new_line(io);
    new_line(io);
    put(io," node      axis             force");
    new_line(io);
    put(io,":");
    new_line(io);
    put(io,"   48");
    new_line(io);

    new_line(io);
    for glob in 1 .. 20 loop
      if xo(glob) /= 0.0 then
        put(io,glob,5);
        put(io,"         1     ");
        put(io,xo(glob),2,6,3);
        new_line(io);
      end if;

      if yo(glob) /= 0.0 then
        put(io,glob,5);
        put(io,"         2     ");
        put(io,yo(glob),2,6,3);
        new_line(io);
      end if;

      if zo(glob) /= 0.0 then
        put(io,glob,5);
        put(io,"         3     ");
        put(io,zo(glob),2,6,3);
        new_line(io);
      end if;
    end loop;
    close(io);
  end input;

  procedure autocad is

    use
      text_io,
      ada.integer_text_io,
      ada.long_float_text_io,
      ada.numerics,
      ada.numerics.long_elementary_functions;

    glob                     : integer;
    xc,yc,zc,r,angle,xp,yp,h : long_float;
    io                       : file_type;

  begin
    -- edge length
    r := 4.0 / sqrt(3.0) / (1.0 + sqrt(5.0));

    -- text height
    h := 0.075;

    create(io, out_file, "dodecahedron.scr");

    -- set running object snap mode to NONE
    put(io,"osmode 0");
    new_line(io);

    -- elements 1
    put(io,"layer make dodecahedron ");
    new_line(io);

    for e in 1 .. 30 loop
      put(io,"3dpoly ");
      for loc in 1 .. 2 loop
        glob := edge(e,loc);
        put(io,xo(glob),1,8,3);
        put(io,",");
        put(io,yo(glob),1,8,3);
        put(io,",");
        put(io,zo(glob),1,8,3);
        put(io," ");
      end loop;
      new_line(io);
    end loop;

    -- face node numbers
    for i in 1 .. 12 loop
      put(io,"layer make face");
      put(io,i,0);
      put(io," ");
      new_line(io);

      -- center of pentagon
      xc := 0.0;
      yc := 0.0;
      zc := 0.0;
      for j in 1 .. 5 loop
          glob := face(i,j);
          xc := xc + xo(glob);
          yc := yc + yo(glob);
          zc := zc + zo(glob);
      end loop;
      xc := 0.2 * xc;
      yc := 0.2 * yc;
      zc := 0.2 * zc;

      -- pentagon UCS coordinates
      put(io,"ucs 3 ");
      put(io,xc,1,8,3);
      put(io,",");
      put(io,yc,1,8,3);
      put(io,",");
      put(io,zc,1,8,3);
      put(io," ");
      glob := face(i,1);
      put(io,xo(glob),1,8,3);
      put(io,",");
      put(io,yo(glob),1,8,3);
      put(io,",");
      put(io,zo(glob),1,8,3);
      put(io," ");
      glob := face(i,2);
      put(io,xo(glob),1,8,3);
      put(io,",");
      put(io,yo(glob),1,8,3);
      put(io,",");
      put(io,zo(glob),1,8,3);
      new_line(io);

      -- node numbers
      for j in 1 .. 5 loop
        angle := 0.4 * pi * long_float(j - 1);
        xp := r * cos(angle);
        yp := r * sin(angle);
        put(io,"text j m ");
        put(io,xp,1,8,3);
        put(io,",");
        put(io,yp,1,8,3);
        put(io," ");
        put(io,h,1,8,3);
        put(io," 0 ");
        put(io,face(i,j),0);
        new_line(io);
      end loop;

      put(io,"ucs w");
      new_line(io);

      put(io,"layer set 0 ");
      new_line(io);

      put(io,"layer off face");
      put(io,i,0);
      put(io," ");
      new_line(io);
    end loop;

    -- nodes
    put(io,"layer make nodes ");
    new_line(io);

    for glob in 1 .. 20 loop
      put(io,"ucs za ");
      put(io,xo(glob),1,8,3);
      put(io,",");
      put(io,yo(glob),1,8,3);
      put(io,",");
      put(io,zo(glob),1,8,3);
      put(io," ");
      put(io,1.1 * xo(glob),1,8,3);
      put(io,",");
      put(io,1.1 * yo(glob),1,8,3);
      put(io,",");
      put(io,1.1 * zo(glob),1,8,3);
      new_line(io);

      put(io,"text j m 0.0,0.0 ");
      put(io,h,1,8,3);
      put(io," 0 ");
      put(io,glob,0);
      new_line(io);

      put(io,"ucs w");
      new_line(io);
    end loop;

    put(io,"layer set 0 ");
    new_line(io);

    -- autocad
    put(io,"zoom ext ext");
    new_line(io);

    close(io);
  end autocad;

begin
  initia;
  input;
  autocad;
end dodecahedron;
