#!/usr/local/bin/perl -w
# Visibility check
use DBI;

use CGI;


$database = '***';
$hostname = '***';
$user = '***';
$password = '***';
$TITLE="Visibility Form";


$query = new CGI;

$path_info = $query->path_info;

if ($query->param ('Get the VRML document')){
    
   print $query->header('x-world/x-vrml');
 
   &print_VRML;
}
else {

   print $query->header;

# If no path information is provided, then we create 
# a side-by-side frame set
   if (!$path_info) {
      &print_frameset;
      exit 0;
   }


#Start HTML page

   &print_html_header;
   &print_query if $path_info=~/query/;
   &print_response if $path_info=~/response/;
   &print_html_end;
}

exit;

#----------------------------------------
# Subroutines
#-----------------------------------------

sub print_html_header {
    print $query->start_html($TITLE);
}
#-----------------------------------------
sub print_html_end {
       print $query->end_html;
}
#-----------------------------------------
sub print_frameset {
    $script_name = $query->script_name;

    print <<EOF;
<html><head><title>$TITLE</title></head>
<frameset cols="40,60">

<frame src="$script_name/query" name="query">
<frame src="$script_name/response" name="response">

</frameset>
EOF
    ;

   exit 0;
}
#------------------------------------------

sub print_query{
    $script_name = $query->script_name;

    print "<H1>Visibility</H1>\n";
    print $query->startform(-action=>"$script_name/response",
-TARGET=>"response");

print "<P><B><I><FONT COLOR=blue><FONT SIZE=-1> Type the coordinates of the points you what to check the visibily between:</FONT></FONT></I></B></P>";


    print "<P>POINT1: <BR>(coordinates)<BR>", 
    $query->textfield(-name=>'X1', 
			-default=>'115.81',
			-size=>20,
			-maxlength=>20);
    print "<BR>",
    $query->textfield(-name=>'Y1', 
 			-default=>'55.16',
			-size=>20,
			-maxlength=>20);
    print "<BR>",
    $query->textfield(-name=>'Z1', 
 			-default=>'4.91',
			-size=>20,
			-maxlength=>20);

    print "<P>POINT2: <BR>(coordinates)<BR>", 
    $query->textfield(-name=>'X2', 
			-default=>'235.30',
			-size=>20,
			-maxlength=>20);
    print "<BR>",
    $query->textfield(-name=>'Y2', 
 			-default=>'268.94',
			-size=>20,
			-maxlength=>20);
    print "<BR>",
    $query->textfield(-name=>'Z2', 
 			-default=>'17.95',
			-size=>20,
			-maxlength=>20);
    

    print "<BR><BR>",$query->submit (' Submit ');
    print $query->endform;

print qq{<P><A href="http://barley.itc.nl/VRML/START7.html" TARGET= "vrml" >back</A>};

}
#--------------------------------------------
sub print_response {

    $script_name= $query->script_name;
    print "<H1>Result</H1>\n";
    unless ($query->param) {
	print "<b>No points submitted yet.</b>";
	return;
    }

$x1 = $query->param('X1');
$y1 = $query->param('Y1');
$z1 = $query->param('Z1');
$x2 = $query->param('X2');
$y2 = $query->param('Y2');
$z2 = $query->param('Z2');

print "<P><B><FONT COLOR=red>POINT1: <BR> x1: $x1<BR> y1: $y1<BR> z1: $z1<BR><BR></FONT></B></P>";
print "<P><B><FONT COLOR=yellow>POINT2: <BR> x2: $x2<BR> y2: $y2<BR> z2: $z2<BR><BR></FONT></B></P>";


    print $query->startform;
    print $query->hidden(-name=>'X1',
                         -default=>$x1);
    print $query->hidden(-name=>'Y1',
                         -default=>$y1);
    print $query->hidden(-name=>'Z1',
                         -default=>$z1);
    print $query->hidden(-name=>'X2',
                         -default=>$x2);
    print $query->hidden(-name=>'Y2',
                         -default=>$y2);
    print $query->hidden(-name=>'Z2',
                         -default=>$z2);
    print "<P><B><I><FONT COLOR=blue> <FONT SIZE=2>Note: The points will be represented by small spheres respectively in red and yellow. The VRML document will be created faster without DTM. <BR><BR></FONT></I></B></P>";

    print $query->checkbox (-name=>'grid',
                            -checked=>'checked',
                            -value =>'ON',
                            -label =>'Grid');
    print "<BR>";
    print $query->checkbox (-name=>'dtm',
                            -checked =>'',
                            -value =>'ON',
                            -label =>'DTM');

    print "<BR><BR>";
    print $query->submit('Get the VRML document');
    print $query->endform;

  
}
#---------------------------------------------------------

sub query_database{


$dbh = DBI->connect ("DBI:mysql:$database:$hostname", $user,$password);

if ($order ne '') {

   $sth = $dbh->prepare("select $fields from $tables where $condition order by $order");
}
else {

  $sth = $dbh->prepare("select $fields from $tables where $condition ");
}

$sth->execute;

$num=0;

while (@field = $sth->fetchrow) {   
  $all[$num]=[@field];
  $num_rec[$num]=@field;
  $num++;
}

$sth->finish;

$dbh->disconnect; 

}
#--------------------------------------------------------
sub print_VRML {

$x1 = $query->param('X1');
$y1 = $query->param('Y1');
$z1 = $query->param('Z1');
$x2 = $query->param('X2');
$y2 = $query->param('Y2');
$z2 = $query->param('Z2');
$g  = $query->param('grid');
$dt = $query->param('dtm');

  &print_vrml_header;

  $fields = "fid,enoseqf,nid,xc,yc,zc,bidg";
  $tables = "bodyg,face,node";
  $condition = "fidb=fid and nidf=nid";
  $order = "fid, enoseqf";
          
  &query_database;
  &print_vrml_surface;

  $fields = "fid,enoseqf,nid,xc,yc,zc,sidg";
  $tables = "surfg,face,node";
  if ($dt ne 'ON'){  
     $condition = "sidg<19 and fids=fid and nidf=nid";
  }
  else  {
     $condition = "fids=fid and nidf=nid";
  }
  $order = "fid, enoseqf";

  &query_database;
  &print_vrml_surface;

  &print_line;
  &print_north;
  if($g eq 'ON'){ 
     &print_grid;
 }
  &print_vrml_end;
  return;
}
#----------------------------------------------------------
sub print_vrml_surface {

  $k=0; 
  $surface = $all[$k]->[6];

  while (($k<$num) && ($surface == ($all[$k]->[6]))) {#-start surface

    print <<EOF;
Shape {
   appearance Appearance {
        material Material {
                diffuseColor  0.20 0.40 0.60
                specularColor 0.80 0.80 0.80
        }
EOF
     ;

#--------print IndexFaceSet--------------------------------
    print <<EOF;
   }
   geometry IndexedFaceSet {
	convex FALSE
        coord Coordinate {
               point [
EOF
    ;
#----------------------------------------------------------

    $n_crd =0;
    $n_face = 0;
    $n[0] = 0;
    while (($k<$num) && (($all[$k]->[6])== $surface)) {
      $fid = $all[$k]->[0];
      $nodeinface=0; 
      while ($fid==$all[$k]->[0]) {
   
#------------------existing coordinates ?????-------------
        $exist = -1;
        $p=$n_crd;
  
        $i=0;
        while ($i<$p){
          if ($all[$k]->[1]==$n[$i]) {
            $exist=$i;
          }
          $i++;
        }
#-----------------------------------------------------------
        if ($exist == -1) { 
          $x[$n_crd] = $all[$k]->[3];
          $y[$n_crd] = $all[$k]->[4];
          $z[$n_crd] = $all[$k]->[5];
          $n[$n_crd] = $all[$k]->[2]; 
  
          $descr[$nodeinface]=$n_crd;
          $n_crd++;
    
        }
        else {
          $descr[$nodeinface]=$exist;
       
        }
    
        $nodeinface++;
        $k++;
   
      }

      $facedescr[$n_face]=[@descr];
      $nodedescr[$n_face]=$nodeinface;
 
      $n_face++;

    } #all the faces in a surface
#--------print coordinates----------------------

    $i=0;

    while ($i<$n_crd) {
      print "            $x[$i] $y[$i] $z[$i] \n";
      $i++;
    }  
    print <<EOF;
            ]
        }
        coordIndex [
         
EOF
    ;

#----------print description----------------------
    $i=0;
    while ($i<$n_face) {
  
      $j=0;
      print "      ";
      while ($j<$nodedescr[$i]) {
        print "$facedescr[$i]->[$j], ";
        $j++;
      }
      $i++;
      print " -1, \n";
    }
    print "       ]\n";   


    $surface = $all[$k]->[6];
 
    print <<EOF;
   } #for geometry
} #for shape
 
EOF
    ;

  } #--------end  surface----------------------------------

}
#----------------------------------------------------------

sub print_line  {

   
   print " Shape {\n ";
   print "   appearance  Appearance{\n";
   print "         material Material {\n";
   print "              emissiveColor  1.0 0.30 0.20\n";
   print "         }\n";
   print "   }\n";
   print "   geometry IndexedLineSet {\n";
   print "         coord Coordinate {\n";
   print "              point [\n";
   print "               $x1 $y1 $z1,\n";
   print "               $x2 $y2 $z2,\n"; 
   print "              ]\n";
   print "         }\n";
   print "         coordIndex [\n";
   print "                0, 1, -1\n";
   print "         ]\n";
   print "    }\n";
   print " }\n";
   
   print "Transform {\n";
   print "     translation $x1 $y1 $z1\n";
   print "     children[\n";
   print " Shape {\n ";
   print "   appearance  Appearance{\n";
   print "         material Material {\n";
   print "              diffuseColor  1.0 0.30 0.20\n";
   print "         }\n";
   print "   }\n";
   print "   geometry Sphere {\n";
   print "         radius 1.0\n";
   print "    }\n";
   print " }\n";
   print "]}\n";
   
   print "Transform {\n";
   print "     translation $x2 $y2 $z2\n";
   print "     children[\n";
   print " Shape {\n ";
   print "   appearance  Appearance{\n";
   print "         material Material {\n";
   print "              diffuseColor  1.0 1.0 0.0\n";
   print "         }\n";
   print "   }\n";
   print "   geometry Sphere {\n";
   print "         radius 1.0\n";
   print "    }\n";
   print " }\n";
   print "]}\n";

}
#--------------------------------------------------------
sub print_north {

$dbh = DBI->connect ("DBI:mysql:$database:$hostname", $user,$password);

$sth = $dbh->prepare("select min(xc) from node");
$sth->execute;
$xmin=$sth->fetchrow;
$sth->finish;

$sth = $dbh->prepare("select min(yc) from node");
$sth->execute;
$ymin=$sth->fetchrow;
$sth->finish;

$sth = $dbh->prepare("select min(zc) from node");
$sth->execute;
$zmin=$sth->fetchrow;
$sth->finish;


$dbh->disconnect; 

   print "Transform {\n";
   print "     translation $xmin $ymin $zmin\n";
   print "     children[\n";

   print " Shape {\n ";
   print "   appearance  Appearance{\n";
   print "         material Material {\n";
   print "              diffuseColor  0.0 0.0 1.0\n";
   print "         }\n";
   print "   }\n";
   print "   geometry Cylinder {\n";
   print "         height 60.0\n";
   print "         radius 1.0\n";
   print "    }\n";
   print " }\n";

   print "Transform {\n";
   print "     rotation 0 0 1 -1.571\n";
   print "     translation 30 -30 0\n";
   print "     children[\n";


   print " Shape {\n ";
   print "   appearance  Appearance{\n";
   print "         material Material {\n";
   print "              diffuseColor  0.0 1.0 0.0\n";
   print "         }\n";
   print "   }\n";
   print "   geometry Cylinder {\n";
   print "         height 60.0\n";
   print "         radius 1.0\n";
   print "    }\n";
   print " }\n";
   print "]}\n";

   print "]}\n";
 
}
#---------------------------------------------------------   
sub print_grid {
$dbh = DBI->connect ("DBI:mysql:$database:$hostname", $user,$password);

$sth = $dbh->prepare("select max(xc) from node");
$sth->execute;
$xmax=$sth->fetchrow;
$sth->finish;

$sth = $dbh->prepare("select max(yc) from node");
$sth->execute;
$ymax=$sth->fetchrow;
$sth->finish;

$sth = $dbh->prepare("select max(zc) from surfg, face, node where sidg=19 and fids=fid and nidf=nid");
$sth->execute;
$zmax=$sth->fetchrow;
$sth->finish;

$dbh->disconnect; 

$i=-400;

while ($i<$xmax) {
  if ($i>$xmin) {

   print " Shape {\n ";
   print "   appearance  Appearance{\n";
   print "         material Material {\n";
   print "              emissiveColor  0.0 0.0 1.0\n";
   print "         }\n";
   print "   }\n";
   print "   geometry IndexedLineSet {\n";
   print "         coord Coordinate {\n";
   print "              point [\n";
   print "               $i $ymin $zmax,\n";
   print "               $i $ymax $zmax,\n"; 
   print "              ]\n";
   print "         }\n";
   print "         coordIndex [\n";
   print "                0, 1, -1\n";
   print "         ]\n";
   print "    }\n";
   print " }\n";
  }
  $i=$i+100;
}

$i= -400;

while ($i<$ymax) {
  if ($i>$ymin) {

   print " Shape {\n ";
   print "   appearance  Appearance{\n";
   print "         material Material {\n";
   print "              emissiveColor  0.0 1.0 0.0\n";
   print "         }\n";
   print "   }\n";
   print "   geometry IndexedLineSet {\n";
   print "         coord Coordinate {\n";
   print "              point [\n";
   print "               $xmin $i $zmax,\n";
   print "               $xmax $i $zmax,\n"; 
   print "              ]\n";
   print "         }\n";
   print "         coordIndex [\n";
   print "                0, 1, -1\n";
   print "         ]\n";
   print "    }\n";
   print " }\n";
  }
  $i=$i+100;
}


}
#---------------------------------------------------------
sub print_vrml_header {
  print <<EOF;
#VRML V2.0 utf8
#Sisi Zlatanova June'98
Group{
    children[

Background {
    skyColor [
        0.0 0.2 0.7,
        0.0 0.5 1.0,
        1.0 1.0 1.0,
    ]
   skyAngle [ 1.009, 1.571 ]
},


Viewpoint {
	position    110  20  -210   
	orientation 0 1 0 3.90
               fieldOfView 0.79
               description "ITC - old buildings"
},

Viewpoint {
	position    270  15  -0   
	orientation 0 1 0 0.60
               description "ITC from South"
},

PointLight {
        location 90 80 -230
        radius   1000.0
},

NavigationInfo{
            speed 1.0
            headlight TRUE
},
Transform {
        rotation 1 0 0 -1.571
        children[
EOF
  ;
} #end print_vrml_header
#---------------------------------------------------------------
sub print_vrml_end {

  print <<EOF;

]} # for transform

]} # for Group

EOF
  ;
} #end print_vrml_end
#---------------------------------------------------------------



