package GUI::Graph;
use System;
use TO;
use Grid;
use TO::Applet;
use GUI;
use Cache;
use Grouping;
use GUI::Grouping;
#use Html::Tree;
use State;
use strict 'vars';
use GUI::Instr;
use GUI::EventLog;
use Catalog;
use Scheduler;
use Modules;

use vars qw( $CACHE);

sub frame {
  my($q) = @_;
  my $renv  = System->get_renv();
  my $ruser = System->get_ruser();
  my $window = $ruser->{window} || $renv->{window};

  if ($ruser->{access} eq "Y") {
    require GUI::TopoList;
    GUI::TopoList::list_frame($q);
    return;
  }
  if ($window eq "S") {
     print <<EOF;
<frameset cols=130,* border=0>
   <frame src=$Http::WEBPROC?GO=GUI::Index::run name=tree scrolling=auto  marginheight=1 marginwidth=2>
   <frame src=/topoWelcome.html name=main scrolling=no  marginheight=1 marginwidth=1>
</frameset>
EOF
  } elsif ($window eq "B") {
     print <<EOF;
<frameset cols=130,*,29% border=0>
   <frame src=$Http::WEBPROC?GO=GUI::Index::run name=tree scrolling=auto  marginheight=1 marginwidth=2>
   <frame src=/topoWelcome.html name=main scrolling=no  marginheight=1 marginwidth=1>
   <frame src=/graph_help.html name=details scrolling=auto >
</frameset>
EOF
  } else { # no frame
     GUI::Graph::run3($q);
  }
}



sub f2 {
  my($q) = @_;

  my $p = ($q->{topo}) ? "topo=$q->{topo}":"stopo=$q->{stopo}";
  $p .= "&key=$q->{key}&name=$q->{name}";
  print "<frameset cols=*,33% border=1>
   <frame src=$Http::WEBPROC?GO=GUI::Graph::run3&$p name=left scrolling=no  marginheight=1 marginwidth=1>
   <frame src=javascript:return() name=details scrolling=auto >
 </frameset>
  ";
}


sub get_focusOn {
  my($q) = @_;
  my($type, $id, $comp) = split(/\:/, $q->{enc});
  $q->{FILTER} = "$type:$id";
  delete($q->{enc});
  &run3($q);
}

sub run3 {
  my($q) = @_;
  my($ck, $in, $title2, $title, $type);
  my $deny = Roles->verifyRole($q, "admin");
  my $G = Labels->read();
  my $L = Labels->read('GUI::Graph')->section('topo');

  print Html->body(undef, {nocenter => 1});
  print "
   <script>
    function win2(t) {
      var b = '$Http::WEBPROC?GO=GUI::Index::search&LINKH=$q->{LINKH}&target=graph&topo=' + t;
      var O = window.open(b,'hist','menubar=no,resizable=yes,scrollbars=yes,width=400,height=600');
      O.focus();
    }
    </script>
   "; 
  my($renv) = System->get_renv();

  my($select_host, $filter) = GUI->topoPage($q);

  if ($q->{CE} == 1) { # clear that State file
     my($renv) = System->get_renv();
     State->clearAllComponents(0);  # reset the green only
     State->clearAllLinks(0);
     State->write();
  }

  my $clear;
  if (!$deny) {
     $clear = "<a href=$Http::WEBPROC?GO=GUI::Graph::run3&topo=$q->{topo}&CE=1
     onclick=\"return confirm('$L->{clear_all}')\">$L->{clear}</a> |";
  } 
  $clear .=  " <a href=javascript:win2('$q->{topo}')>$L->{search}</a> ";

  my $ruser = System->get_ruser();
  my $window = $ruser->{window} || $renv->{window};
  my $extra = "<form>
    <input type=hidden name=LINKH value=$q->{LINKH}>
    <input type=hidden name=GO value=GUI::Graph::run3>
    <b> $L->{host}:</b>$select_host <b>$L->{filter}:</b>$filter 
    <input type=submit name=ACTION value=GO>
        ";
  print Html->header2("monitor.topo", "100%", undef, undef, { right => $clear, middle => $extra, noTitle => ($window eq "B")} );

  print &genApplet($q);
  #print "</form>";

}


# $out =  GUI::Graph::genApplet({  topo   => $k,  email => 1, offy => 30, HIST => 1,
#                                [ width=> 600, height => 400, zoom  => 3 ] } );

sub genApplet {
  my($q) = @_;
  my($o1);

  
  my ($out2, $running) = TO::Applet->genAppletData($q, 1); # returns <parms ...
  return if (!$out2);

  my $current = $q->{topo};

  my($applet, $parm1, $parm2);
  my($code, $off, $offx);
  my($renv) = System->get_renv();
  my($ruser) = System->get_ruser();
  my $window = $ruser->{window} || $renv->{window};
  my $L = Labels->read('GUI::Graph')->section('topo');
  my $isC = 1 if ($q->{SYSTEM} || $ruser->{isCustomer});

  my $browser = $Http::httpua =~ /Win/ ? "window" : "sun";

  if ($q->{email}) {
    $code = "http://nscc.central:8080/CC/Topo2/";
    $off = 70;
    $offx = 30;
  } else {
    $code = "Topo";
    $off = $q->{offy} || 45;
    $offx = 6;
  }
  if ($window eq "N") {
   $offx += 15;
   $off += 80;
  }
  my $zoom = $q->{zoom}  + 0;
  my $archive = "archive=topo21.jar";

  if ($q->{height} && $q->{width}) {
    $applet = "<applet  CODE=VertexApplet.class codebase=$code $archive height=$q->{height}  width=$q->{width}>";

  } else {
    $applet = System->appletHeader("code=VertexApplet.class codebase=$code $archive", $offx, $off);
  }
  #$applet = "<applet  CODE=VertexApplet.class codebase=$code $archive height=600  width=500>";

  if ($q->{email}) {
    $parm1 = "";

  } elsif ($q->{HIST}) {
   $parm1 =<<EOF;
   <param name=url value="GO=GUI::Graph::topos&get_topo=$current&FILTER=$q->{FILTER}">
   <param name=graphicsButton value=0>
EOF

  } else {
   my $LNK = "<param name=showLinkHandle value=1>" if ($q->{LINKH});

   my $details = "details";
   my $wdetails = "javascript:var O=window.open('\$1','gr_s','menubar=no,resizable=yes,scrollbars=yes,width=500,height=650');O.focus()";
   if ($window  eq "S") {  # Small or Big
      $details = $wdetails;
   } elsif ($window eq "N") {
      $details = "_self";
   }
   $parm1 =<<EOF;
  <param name=url value="GO=GUI::Graph::get_topos&topo=$current&FILTER=$q->{FILTER}">
  <param name=urlRefresh value="GO=GUI::Graph::get_topos&topo=$current">
  <param name=timeRefresh value="10000">
  <param name=webproc  value="$Http::WEBPROC">
  <param name=userPassword value="peer:peer">
  <param name=isCustomer value="$isC">
  <param name=graphicsButton value=1>
  <param name=circle value="$q->{key}">
  $LNK
  <param name=drop1 value="$L->{drop1}|$details|gu|GO=GUI::Graph::get_report&topo=$current">
  <param name=drop2 value="$L->{drop2}|$details|hasu|GO=GUI::Graph::get_report&topo=$current">
  <param name=drop3 value="$L->{drop3}|main|hsau|GO=GUI::Graph::run3&topo=$current&FILTER=$q->{FILTER}">
  <param name=drop4 value="$L->{drop4}|$details|hsau|GO=GUI::Graph::get_gr_style&topo=$current">
  <param name=drop5 value="$L->{drop5}|$details|gu|GO=GUI::Graph::get_report&Roption=2&topo=$current">
  <param name=drop6 value="$L->{drop6}|$details|gu|GO=GUI::Test::get_test&TAB=1&topo=$current">
  <param name=drop7 value="$L->{drop7}|_self|gu|GO=GUI::Graph::get_focusOn&topo=$current">
  <param name=drop8 value="$L->{drop8}|$wdetails|g|GO=GUI::Graph::get_details&topo=$current">
  <param name=ldrop1 value="$L->{ldrop1}|$details|h|GO=GUI::Graph::get_fibrelog&topo=$current">
  <param name=ldrop2 value="$L->{ldrop2}|$details||GO=GUI::Test::get_testlink&topo=$current">

  <param name=adrop1 value="$L->{adrop1}|$details||GO=GUI::Graph::displayList&topo=$current&FILTER=$q->{FILTER}">
  <param name=browser value="$browser">
EOF
   }
   if (index($Http::httpua, "Netscape/7.") >= 0) {
       $out2 = "";
   }

   return "$applet $parm1 $out2 </applet></form>";
#  <Xparam name=saveURL value="/?PUT=GUI::Graph::topos&topo=$current&FILTER=$q->{FILTER}">
#  <Xparam name=ldrop2 value="Clear Error|t|r,h|GO=GUI::Graph::get_clearlog&topo=$current">

}

sub updateGroup {
  my($q) = @_;
  print "Update Group";
}


sub displayList {
  my($q) = @_;
  my($x);
  my @L = split(/\|/, $q->{enc});
  print "\n<body bgcolor=#E0E0E0><center>";
#foreach my $x (keys %$q) {print "$x=$q->{$x}<br>"}
  my(@F) = split(/\:/, $q->{FILTER});
  my $G = Labels->read();
  my $L = Labels->read('GUI::Graph')->section('group');

  if ($q->{ACTION_group}) {
     if (!$q->{groupid}) {
        print "<b><font color=red>$L->{err_not_blank}";
     } else {
       my $g1;
       if ($q->{newgroup}) {
          Grouping->addCategory($q->{topo}, $q->{newgroup}, $q->{newgroup});
          $g1 = "$q->{topo}:$q->{newgroup}";
       } else {
          $g1 = $q->{grouping};
       }
       foreach my $n (@L) {
          Grouping->setGroup($g1, $n, $q->{groupid}, $q->{color}, $q->{style}, $q->{desc});
       }
       Grouping->save();  
       my $cnt = $#L +1;
       print "<b>$cnt " . $L->expand('info1', $q->{grouping}. ":" . $q->{groupid});
     }
  }

  my $host = $q->{topo};
  my $to = TO->readTopo($host);
  if ($L[0] =~ /^Xroup:/) {
     &updateGroup($L[0]);
     return;
  }

  my $out = "
  <table border=0 width=100%><tr><td><b><font color=navy>".
   $L->expand('info2', ($#L+1)) . " </table>";

  $out .= "<table border=1 cellspacing=0 cellpadding=1 width=100% bgcolor=white>
    <tr bgcolor=#CCCCFF><td><b>$L->{type}<td><b>$L->{name}</td>";
  my $cnt;
  foreach my $n (@L) {
     if (substr($n,0,6) eq "group:") {
       $cnt++;
       my $n1 = substr($n,6); $n1 =~ s/\:/ /;
       $out .= "<tr><td>&nbsp;group</td><td>&nbsp;$n1";
       
     } else {
       my $node = $to->nodeByName($n);
       next if (!$node);
       my $name = $node->boxName();    
       my $type = $node->type();
       $cnt++;
       $out .= "<tr><td>&nbsp;$type</td><td>&nbsp;$name " . $node->{info}{sw_ipAddr};
     }
  }
  if ($cnt == 0) {
     print "&nbsp;<p><center><font color=red><b>$L->{err_cannot_group}";
     return;
  } else {
    print $out;
  }
  print "</table>";
  if ($#L < 0) {
    print "<tr><td><center><b>$L->{err_no_dev}</td>";
    return;
  }
  my $gl = Grouping->groupList($host);

  my ( $sel, $sel1, $sel2);
  if ($#$gl >= 0) {
     $sel  = "$L->{grouping}: </td><td><select name=grouping>";
     foreach my $x (@$gl) {
       $sel .= "<option value=\"$x->{host}:$x->{group}\">$x->{group}";
     }
     $sel .= "</select></td>";
  } else {
     $sel1 = "<tr><td bgcolor=#CCCCFF align=right>$L->{new_grouping}: </td><td><input type=text name=newgroup size=20>";
  }

  my($desc, $styl, $color) = &get_styles([]);
  my $curr_gr = "<tr><td colspan=2 bgcolor=#666699><font color=white><b>&nbsp;$F[2]</td>" if ($F[2]);

  print "
  <table border=0><tr><td></table>
  <table border=1 cellpadding=0 cellspacing=0 width=100% bgcolor=white>
      $curr_gr
    <tr><td align=right bgcolor=#CCCCFF>
   <form>
   <input type=hidden name=GO value=GUI::Graph::displayList>
   <input type=hidden name=enc value=\"$q->{enc}\">
   <input type=hidden name=topo value=\"$q->{topo}\">
      $sel
      $sel1 
    <tr><td align=right bgcolor=#CCCCFF>$L->{group_id}: </td>
        <td> <input type=text name=groupid size=20></td>
    <tr><td align=right bgcolor=#CCCCFF>$L->{icon}: </td>
        <td> $styl</td>
    <tr><td align=right bgcolor=#CCCCFF>$L->{color}: </td>
        <td> $color</td>
    <tr><td align=right bgcolor=#CCCCFF>$L->{desc}: </td>
        <td><input type=text name=desc size=20></td>
    $sel2
    <tr><td></td>
    </table>
    <input type=submit name=ACTION_group value=\"$L->{submit_group}\">
  </form>
  ";
  
  
}

sub get_styles {
  my($map) = @_;
  my $styl = "<select name=style>";
  foreach my $st0 (@GUI::Grouping::GROUP_TYPE) {
     my($f1, $f2) = split(/\=/, $st0);
     my $ck = $f1 eq $map->[1]?  "selected": "";
     $styl .= "<option value=\"$f1\" $ck>$f2</option>";
  }
  $styl .= "</select>";

  my $color = "<select name=color>";
  foreach my $st0 (@Grouping::COLORS) {
     my($f1, $f2) = split(/\=/, $st0);
     my $ck = $f1 eq $map->[2]?  "selected": "";
     $color .= "<option value=\"$f1\" $ck>$f2</option>";
  }
  $color .= "</select>";
  return ("<input type=text name=desc size=20 value=\"$map->[0]\">" , $styl, $color);
}


#
# call-back from applet
#
sub get_topos {
  my($q) = @_;
  my($l, @LOG);
  print "HTTP/1.0 200 OK\n\n";    
  my ($o1,$running) = TO::Applet->genAppletData($q);
  print $o1;
  
}

sub get_topos0 {
  print "
s0|v|s,Ancor,2-4/6-8,8,F0F0F0|switch:100000c0dd008855=switchA,Ancor,()|126|8|||||||diskinfo|otherinfo
00|e|s||s0,2|s0,4
00|e|s||s0,6|s0,8
s1|v|s,Ancor,6-8,8,F0F0F0|switch:100000c0dd008855,Ancor,()|126|108|||||||diskinfo|otherinfo
00|e|s||s1,6|s1,8
u0|v|u,Hub|u:H0|226|328|||||encInfo|portinfo|diskInfo|encinfo
00|e|f||u0,0|s0,8
00|e|f||u0,1|a2,1
00|e|f||u0,2|a0,1
u1|v|u,Hub|u:H1|229|219|||||encInfo|portinfo|diskInfo|encinfo
00|e|f||u1,0|s1,8
00|e|f||u1,1|a0,0
00|e|f||u1,2|a2,0
h0|v|h,Sun,8|host:nscc-test,host|10|86||-1,,-1,,-1,,-1,|||encInfo| /pci\@6_4000/pci\@2/SUNW_qlc\@4, /devices/pci\@6_4000/pci\@2/SUNW_qlc\@5, /devices/pci\@6_4000/pci\@3/SUNW_qlc\@4,/devices/pci\@6_4000/pci\@3/SUNW_qlc\@5, /devices/pci\@6_4000/pci\@4/SUNW_qlc\@4, /devices/pci\@6_4000/pci\@4/SUNW_qlc\@5, /devices/pci\@6_2000/pci\@1/SUNW_qlc\@4, /devices/pci\@6_2000/pci\@1/SUNW_qlc\@5|diskInfo|otherInfo
00|e|f||h0,1|s0,6
00|e|f||h0,3|s1,6
00|e|f||h0,7|s0,2
a0|v|a,A5K,2,11,f/r,FBP,Fan/BackPlane/Power,D0D0F0|a5k:508002000008a328=e,A5200,()|343|167||||||||
00|e|f||u1,1|a0,1
00|e|f||u0,2|a0,2
a1|v|a,T3,2,9,1/2,LMPV,Lun/Midplane/Power/Volume,F0C0C0|t3:21312312-1232133=diag230,PGroup,()|333|20||||||||
00|e|f||h0,5|a1,1
";
}


sub NUget_clearlog {
  my($q) = @_;

  my(@nodes) = split(/\//, $q->{link});

  my $State  = State->read($q->{topo});

  $State->clearLink("$nodes[0]|$nodes[1]");
  $State->clearLink("$nodes[1]|$nodes[0]");

  
  State->write();
  &get_topos($q);
  
}


sub get_fibrelog {
  my($q) = @_;
  my($node0, $node1, @nodes);
  print "\n<body bgcolor=#F0F0F0>";
 # foreach my $x (keys %$q) { print "$x=$q->{$x}<br>"; }

  if ($q->{link}) {
    (@nodes) = split(/\//, $q->{link});
  } else {  # start and end has port# too big for storage nodes (t3/a5k), still need link
    $nodes[0] = $q->{start};
    $nodes[1] = $q->{end};
  }

  #$nodes[0] = $q->{start};
  #$nodes[1] = $q->{end};

  if ($nodes[0] gt $nodes[1]) {
     $node0 = $nodes[1];
     $node1 = $nodes[0];
  } else {
     $node0 = $nodes[0];
     $node1 = $nodes[1];
  }

  print "<table border=0><tr><td></table>";
  print Html->header("Link Errors");
  &call($q, $node0, $node1);
  print "<table border=0><tr><td></table>";
  &call($q, $node1, $node0);
  print "<center><b><form><input type=hidden name=GO value=GUI::Graph::clearLink>
         <input type=hidden name=start value=\"$nodes[0]\">
         <input type=hidden name=end value=\"$nodes[1]\">
         <input type=submit name=ACTION value=\"Clear Link Errors\">
         </form>";
}

sub clearLink {
  my($q) = @_;

  my $State  = State->read();
  my $s = $q->{start};
  my $e = $q->{end};

  $State->clearLink("$s|$e");
  $State->clearLink("$e|$s");
  
  State->write();
  print "\n<body bgcolor=#F0F0F0>";
  print "<table border=0><tr><td></table>";
  print Html->header("Link Errors");

  print "<table border=1 cellspacing=0 bgcolor=white width=100%>
    <tr><td align=right bgcolor=#CCCCFF>Node1:</td>
        <td>$s</td>
    <tr><td align=right bgcolor=#CCCCFF>Node2:</td>
        <td>$e</td>
    </table>
    &nbsp;<br><b>Link cleared!";
}

sub call {
  my($q, $node0, $node1) = @_;
  my($x);

  my(@b1) = split(/:/, $node0);
  my(@b2) = split(/:/, $node1);

  my($type1) = $b1[0];
  my($type2) = $b2[0];
  $type1 = "switch" if ($type1 eq "brocade");
  $type2 = "switch" if ($type2 eq "brocade");
  my($name1) = $b1[1];
  my($name2) = $b2[1];
  my($port1) = "Port." . $b1[2];
  my($port2) = "Port." . $b2[2];
  my $LB = Labels->read('GUI::Graph')->section('call');

  my $L     = State->read($q->{topo});
  my $links = $L->links();

  my $ln      = $links->{"$node0|$node1"};
  my $v       = $ln->[1];
  my $actions = $ln->[2];
  my $host    = $ln->[4];
  my $detec   = $host;
  my $ii      = index($host,".");
  $detec      = substr($host, 0, $ii) if ($ii > 0);
  my $linkevent = "san.LinkEvent." . ($v =~ /ITW/? "ITW":"CRC");
  my $ev      = Grid->getInfo($linkevent, "$type1|$type2");

  my ($pc, $ra);
  if ($ev) {
    $pc      = $ev->{cause};
    $ra      = $ev->{action};
  }

  if ($v) {
    print "<table border=0 cellpadding=2 cellspacing=0 width=100% bgcolor=white>
    <tr bgcolor=#666699><td>
     <table border=0 cellspacing=0 width=100%>
       <tr><td><font color=white><b>$type1 -> $type2</td>
       <td align=right><font color=white> $detec</table></td>
    ";
    $v =~ s/Origin:/<br><font color=navy><b>Origin<\/b><\/font>:/;
    $v =~ s/Destination:/<br><font color=navy><b>Destination<\/b><\/font>:/;

    print "<tr><td>$v<br>&nbsp;";

    if ($pc || $ra) {
    print " <tr><td bgcolor=#CCCCFF><b>$LB->{probable}</td>
      <tr><td>$pc<br>
      <tr><td></td>
      <tr><td bgcolor=#CCCCFF><b>$LB->{recomm}</td>
      <tr><td>$ra<br>&nbsp;";
    } else {
      print "<tr><td>&nbsp;</td>";
    }

    print "</table>\n";

    print "<table  border=0 cellpadding=2 cellspacing=0 width=100% bgcolor=white>
";
    my $log ; # = State->linkLog($host, "$node0|$node1");
    if ($log) {
     my @x = split(/\n/, $log);
     my $lt = "(last 10)" if ($#x > 10);
     $log =~ s/\n/<br>/g;
     print 
"<tr><td bgcolor=#E0E0E0><b>$LB->{log} $lt:</td>
<tr><td><small>" . $log;
    }
    print "</table>";
  }
}

sub put_get_topos {
  my($q, $post_data) = @_;
#open(O, ">>/tmp/xx2");
#foreach my $x (keys %$q) {
#   print O "$x=$q->{$x}\n";
#}
#close(O);
  TO::put_topo_xy($q, $post_data);
}


sub get_eventLog {
  my($q) = @_;
  my($renv, $devs, $hosts,$notifs) = PDM::ConfigFile->read;

  my($type, $key, $comp) = split(/:/, $q->{enc});
  my($filter1);
  my($host) = "host_local";
  my($found) = 0;

  my $ci = Catalog->deviceRead($type, Catalog::Key, $key);

  if (!$ci) {
    print "No entry in config file for $q->{enc}";
    return;
  }
  $host = $ci->[Catalog::Host];
  $q->{"host_$host"} = 1;
  $q->{filter1}  = $key;

  $q->{category} = $type;
  $q->{BACK}     = 0;
  GUI::EventLog::display($q);

}

sub readState {
  my($Comps, $Links, $name) = @_;
  my($info, $link_err, $gif);
  foreach my $k (keys %$Comps) {
     if (substr($k,0,length($name)) eq $name) {
         next if ($Comps->{$k}[0] <= 0);
         my $sub = substr($k,length($name) + 1);
         $gif = $Comps->{$k}[0] if ($Comps->{$k}[0] > $gif);
         $info .= "-$Comps->{$k}[1]<br>";
      }
  }
  foreach my $k (keys %$Links) {
     if (substr($k,0,length($name)) eq $name) {
        $link_err = $Links->{$k}[0] if ($Links->{$k}[0] > $link_err);
     }
  }
  return ($info, $link_err, $gif);
}

sub compare {
  my($n, $key) = @_;
  if ($n eq $key) {  
     return (1,"");
  } elsif (substr($n,0,length($key)+1) eq "$key.") {
     return (1, substr($n,length($key)+1));
  }
  return 0;
}

sub grouping {
  my($q) = @_;
  my($type, $host0, $key0, $comp) = split(/:/, $q->{enc});
  my($k1, $k2) = split(/\./, $key0, 2);

  my $EDIT = $q->{EDIT};
   my $key = "$host0:$key0";
   my $to = TO->readTopo($q->{topo});
   my $out;
   my $menu = &gr_menu($q);
   my $title = $EDIT ? "Group Edit" : "Group Members";
   my $G = Labels->read();
   my $LB = Labels->read('GUI::Graph')->section('grouping');

   my($h1, $cat1, $rest) = Grouping->keyParts($key);
   my $FILTER_ID = "$h1:$cat1";
   my $G = Grouping->read($FILTER_ID)->members();   

   my $style = Grouping->getMap("$host0:$k1", $k2);

   $q->{new_id} =~ s/[^\w\.]//g;
   if ($q->{ACTION} eq "Move" && !$q->{new_id}) {
      print "<font color=red><b>$LB->{err_noid}<br>";

   } elsif ($q->{ACTION_release} || $q->{ACTION_move}) {
      my $cnt=0;
      my $map = Grouping->getMap("$host0:$k1");
      foreach my $n (keys %$q) {
          if (substr($n,0,3) eq "ck_") {
             my $name = substr($n,3);
             if ($q->{ACTION_release}) {
                delete($G->{$name});
             } else {
                $G->{$name} = "$FILTER_ID.$q->{new_id}";
                $map->{"$FILTER_ID.$q->{new_id}"} = [$q->{desc}, $q->{style}, $q->{color}];
             }
             $cnt++;
          }
      }
      Grouping->save() if ($cnt > 0);
   }

   $out = "\n<body bgcolor=#F0F0F0 marginwidth=2 leftmargin=1  marginheight=4 link=blue vlink=blue>
     <table border=0 cellspacing=0 cellpadding=3 width=100%>
        <tr><td>
          <form><input type=hidden name=GO value=GUI::Graph::grouping>
          <input type=hidden name=topo value=\"$q->{topo}\">
          <input type=hidden name=enc value=\"$q->{enc}\">
          <input type=hidden name=EDIT value=\"$q->{EDIT}\">
          <b><font color=navy>$title</td><td align=right>$menu</td>
     </table>
     <table border=0 cellpadding=2 cellspacing=0 width=100% bgcolor=#666699>
       <tr><td><b><font color=white>&nbsp;<b>$key0
     </table>
     <table border=1 cellpadding=1 cellspacing=0 width=100% bgcolor=white>
    ";


   my $State = State->read();
   my $Comps = $State->components();
   my $Links = $State->links();
   my @Map = ('al_ok3','al_alert3','al_crit3','al_down3');
   my (@L2, @L, @S1a, @S1b, @S2, @S3, @S31);

   if ($style->[1] eq "rack") {
     foreach my $node (sort keys %$G) {
       my ($rc,$rest) = &compare($G->{$node}, $key);
       if ($rc) {
         my $n = $to->nodeByName($node);
         next if (!$n);
	 my $type = $n->type();
         if ($type eq "host") {
            push(@L, [$n, $rest]);
         } else {
           push(@L2, $n->ipAddr() . "|$node|$rest");
         }
       }
     }
     foreach my $el (sort @L2) {
        my($ip, $node, $rest) = split(/\|/, $el);
        my $n = $to->nodeByName($node);
        my $type = $n->type();
        if ($type eq "switch") {
           my $ip = $n->{info}{sw_ipAddr};
           if (substr($ip, -2) eq "32" || substr($ip,-2) eq "33") {
             push(@S1b, [$n, $rest]);
           } else {
             push(@S1a, [$n, $rest]);
           }
        } elsif (substr($ip, -2) >= 50) {
           push(@S31, [$n, $rest]);
        } elsif (substr($ip, -2) >= 40) {
           push(@S3, [$n, $rest]);
        } else {
           push(@S2, [$n, $rest]);
        }
     }
     push(@L, @S1a, @S2, @S1b, (reverse @S3));
     if ($#S31 >= 0) {
        push(@L, (reverse @S31));
     }

   } else {
     foreach my $node (sort keys %$G) {
        my ($rc, $rest) = &compare($G->{$node}, $key);
        if ($rc) {
          my $n = $to->nodeByName($node);
          next if (!$n);
          push(@L, [$n, $rest]);
        }
      }
   }
   my ($link_err0, $link_err, $last, $bg); $bg = "bgcolor=#F0F0F0";
   foreach my $n0 (@L) {
        my $n = $n0->[0];
        my $rest = $n0->[1];

        my $name = $n->name();
        my $type = $n->type();
        my $url;
        my $t1 = ($type eq "host" && $style->[1] eq "rack") ? "sp" : $type;
        if ($type eq "host") {
           $url =  $n->boxName();
        } else {
           $url = "<a href=$Http::WEBPROC?GO=GUI::Graph::get_report&topo=$q->{topo}&enc=$name>" .  $n->boxName() . "</a>";
        }
        my $gif = 0;
        my $info;
        if ($EDIT) {
          $out .= "<tr><td><center>$t1<td >&nbsp;$url $rest<td><center><input type=checkbox name=ck_$name>";
        } else {
          ($info, $link_err0, $gif) = &readState($Comps, $Links, $name);
          $link_err = $link_err0 if ($link_err0 > $link_err);
          if ($last ne $t1) {
             $bg = ($bg) ? "": "bgcolor=#F0F0F0";
             $last = $t1;
          }
          $out .= "<tr $bg><td><center><img src=/gif/" .  $Map[$gif] . ".gif vspace=1 hspace=1><b>".
               "<td ><center>$t1<td >&nbsp;$url $rest";
          $out .= "<tr><td><td colspan=2><small>$info" if ($info);
        }
        $out .= "</td>";
   }
   $out .= "</table>";

   my($desc, $styl, $color) = &get_styles([]);

   if ($link_err && !$EDIT) {
      $out .= "<table border=1 cellspacing=0 width=100% bgcolor=white>
      <tr><td>&nbsp;<img src=/gif/".$Map[$link_err].".gif><b>&nbsp;Found Link Error(s)</table>";
   }
   if ($EDIT) {
      $out .= "<table border=0><tr><td></table><table border=1 width=100% bgcolor=white cellspacing=0>
       <tr><td  bgcolor=#666699><font color=white><b>Release selected devices (Ungroup)</td>
       <tr><td>
                <b><center><input type=submit name=ACTION value=Release>
       <tr><td></td>
       <tr><td></td>
       <tr><td bgcolor=#666699><font color=white><b>Move selected devices to new $k1-ID:<center>
       <tr><td><center>
           <table border=0 cellspacing=1 width=100% cellpadding=0 bgcolor=#F0F0F0>
             <tr><td align=right bgcolor=#CCCCFF>$LB->{current}:</td><td><b>&nbsp;$k2</td>
             <tr><td align=right bgcolor=#CCCCFF>$LB->{new_id}:</td><td><input type=text name=new_id size=20></td>
             <tr><td align=right bgcolor=#CCCCFF>$LB->{style}:</td><td>$styl</td>
             <tr><td align=right bgcolor=#CCCCFF>$LB->{color}:</td><td>$color</td>
             <tr><td align=right bgcolor=#CCCCFF>$LB->{desc}:</td><td><input type=text name=desc size=20></td>
           </table><b>
              <input type=submit name=ACTION_move value=$LB->{submit_move}>
       </table>&nbsp;<p>";
   }

   print $out;
}

sub gr_menu {
  my($q) = @_;

  my $LB = Labels->read('GUI::Graph')->section('gr_menu');

  my $m1 = "<a href=$Http::WEBPROC?GO=GUI::Graph::grouping&enc=$q->{enc}&topo=$q->{topo}>$LB->{members}</a>";
  my $s1 = "<a href=$Http::WEBPROC?GO=GUI::Graph::get_gr_style&enc=$q->{enc}&topo=$q->{topo}>$LB->{style}</a></b>";
  my $e1 = "<a href=$Http::WEBPROC?GO=GUI::Graph::grouping&enc=$q->{enc}&topo=$q->{topo}&EDIT=1>$LB->{edit}</a>";
  return "[ $m1 | $s1 | $e1 ]";
}

sub get_gr_style {
  my($q) = @_;
  my($type, $host0, $key, $comp) = split(/:/, $q->{enc});
  print "\n<body bgcolor=#F0F0F0 marginheight=4 marginwidth=2>";
  my $LB = Labels->read('GUI::Graph')->section('get_gr_style');

  my($k1, $k2) = split(/\./, $key, 2);

  if ($q->{ACTION_change}) {
     Grouping->updateId("$host0:$k1","$host0:$key", $q->{desc}, $q->{style}, $q->{color});
     Grouping->save();  
     print "$LB->{style_changed}<br>";

  } elsif ($q->{ACTION_move}) {
      my $G = Grouping->read("$host0:$k1");
      my $M =  $G->members();
      my $old = "$host0:$key";
      my $new = $q->{group_id}; 
      $new =~ s/[^\w\.]//g;
      if (!$new) {
         print "<font color=red><b>$LB->{err_new_id}</b>";
      } else {
        my $cnt=0;
        foreach my $el (keys %$M) {
           if ($M->{$el} eq $old) {
             $cnt++;
             $M->{$el} = "$host0:$k1.$new";
           }
        }
        print $LB->expand('moved', $cnt, $k1.$new) . "<br>\n";
        $k2 = $new;
        Grouping->save() if ($cnt);
      }
  }
  my $map = Grouping->getMap("$host0:$k1");
  $map = $map->{"$host0:$key"};
  my ($menu) = &gr_menu($q);

  my($desc, $styl, $color) = &get_styles($map);
  my $out .= "
     <table border=0 cellspacing=0 cellpadding=3 width=100%>
        <tr><td><b><font color=navy>$LB->{label}</td><td align=right>$menu</td>
     </table>
  <table border=1 cellspacing=0 width=100% bgcolor=white>
  <tr><td colspan=2 bgcolor=#666699>
      <form><input type=hidden name=GO value=GUI::Graph::get_gr_style>
      <input type=hidden name=enc value=\"$q->{enc}\">
      <input type=hidden name=topo value=\"$q->{topo}\">
      <font color=white><b>&nbsp;$key</td>
      <tr><td bgcolor=#CCCCFF align=right>$LB->{icon}: </td><td>$styl</td>
      <tr><td bgcolor=#CCCCFF align=right>$LB->{color}: </td><td>$color</td>
      <tr><td bgcolor=#CCCCFF align=right>$LB->{desc}: </td><td>$desc</td>
      <tr><td colspan=2><center>
           <input type=submit name=ACTION_change value=$LB->{submit_change}>
      </table></form>

  <table border=1 cellspacing=0 width=100% bgcolor=white>
  <tr><td colspan=2 bgcolor=#666699>
      <form><input type=hidden name=GO value=GUI::Graph::get_gr_style>
      <input type=hidden name=enc value=\"$q->{enc}\">
      <input type=hidden name=topo value=\"$q->{topo}\">
      <font color=white><b>" .
      $LB->expand('move_to', $k1-ID) . "</td>
      <tr><td bgcolor=#CCCCFF align=right>$LB->{current_id}: </td>
          <td>&nbsp;$k2</td>
      <tr><td bgcolor=#CCCCFF align=right>$LB->{new_id}: </td>
          <td><input type=text size=20 name=group_id></td>
      <tr><td colspan=2><center><input type=submit name=ACTION_move value=$LB->{submit_move}>
      </table></form>
   ";
   print $out;

}
  

sub get_report {
  my($q) = @_;
  my($l, $host0);
  #print "\n";
# foreach my $x (keys %$q) {print "$x=$q->{$x}<br>"}

  my($type, $key, $comp) = split(/:/, $q->{enc});

  if ($type eq "group") {
     &grouping($q);
     return;
  }

  my($renv) = System->get_renv();
  $q->{file} = "$type:$key";
  my $found = 0;

  my $host = Report->findReportHost($q->{file});

  $q->{host} = $host;
  $q->{Doption} = 4;
  GUI::Instr::rStart($q);
}

sub get_details {
  my($q) = @_;
  my($renv, $devs, $hosts,$notifs) = PDM::ConfigFile->read;
require Data::Dumper;
  my $LB = Labels->read('GUI::Graph')->section('get_details');

  my($to) = TO->readTopo($q->{topo});

  my($type, $key, $comp) = split(/:/, $q->{enc});

  print "\n<header><title>Storage A.D.E.</title></head><body bgcolor=white>";
  print "<table border=1 cellspacing=0 cellpadding=2 width=100%>
   <tr bgcolor=#666699><td><font color=white><b>$LB->{system_review}: $q->{enc}</td>
   </table><pre><small>";
  my($node)  = $to->nodeByName("$type:$key");
  $Data::Dumper::Indent = 1;

  print Data::Dumper::Dumper($node);
  if ($type eq "switch") {
    print "\nSAN-Zones: ";
    print substr(Data::Dumper::Dumper($to->[5]),7);
  }

}


$CACHE =undef;


sub log2 {
  my($l) = @_;
  open(OO, ">>/tmp/log2"); print OO $l . "\n"; close(OO);
}

sub get_clear {
  my($q) = @_;
  my($type, $name, $comp) = split(/:/, $q->{enc});
  my($u, $unit, $d);

  my($State) = State->read($q->{topo});

  if ($comp eq "e") {  # enclosure
    $State->clear($q->{enc});
 
  } else {
    if ($type eq "a3500fc") {
       if ($comp eq "s1") {
          $State->clear("$type:$name:controller.a");
       } elsif ($comp eq "s2") {
          $State->clear("$type:$name:controller.b");
  
       } elsif (substr($comp, 0, 1) eq "d") {
          my($no) = substr($comp,1);
  
          $State->clear("$type:$name:disk.$no");
       }

    } elsif ($type eq "a5k") {
       if ($comp eq "s1") {
          $State->clear("$type:$name:interface_board.A");
          $State->clear("$type:$name:interface_board.A.gbic0");
          $State->clear("$type:$name:interface_board.A.gbic1");
       } elsif ($comp eq "s2") {
          $State->clear("$type:$name:interface_board.B");
          $State->clear("$type:$name:interface_board.B.gbic0");
          $State->clear("$type:$name:interface_board.B.gbic1");
  
       } elsif (substr($comp, 0, 1) eq "d") {
          if (substr($comp, 1,1) eq "f") {
            $u = "disk_front";
          } else {
            $u = "disk_rear";
          }
          my($no) = substr($comp,2);
  
          $State->clear("a5k:$name:$u.$no");
       }
  
    } elsif ($type eq "switch") {

       my $key = "switch:$name:port." . substr($comp,1);
       &log2("enc=$q->{enc}, key=$key ");

       $State->clear($key);
  
    } elsif ($type eq "t3") {
       if ($comp eq "s1") {
          $State->clear("$type:$name:controller.u1ctr");
       } elsif ($comp eq "s2") {
          $State->clear("$type:$name:controller.u2ctr");
  
       } elsif (substr($comp,0,1) eq "d") {
          $unit = substr($comp,1,1);
          $d = substr($comp,2) + 1;
          $State->clear("$type:$name:disk.u${unit}d$d");
  
       } elsif (substr($comp,0,1) eq "L") {
          $State->clear("$type:$name:loopcard.u1l1");
          $State->clear("$type:$name:loopcard.u1l2");
          $State->clear("$type:$name:loopcard.u2l1");
          $State->clear("$type:$name:loopcard.u2l2");
  
       } elsif (substr($comp,0,1) eq "M") {
          $State->clear("$type:$name:midplane.u1mpn");
          $State->clear("$type:$name:midplane.u2mpn");
  
       } elsif (substr($comp,0,1) eq "P") {
          $State->clear("$type:$name:power.u1pcu1");
          $State->clear("$type:$name:power.u1pcu2");
          $State->clear("$type:$name:power.u2pcu1");
          $State->clear("$type:$name:power.u2pcu2");
  
       } elsif (substr($comp,0,1) eq "V") {
          $State->clear("$type:$name:volume.u1vol1");
          $State->clear("$type:$name:volume.u1vol2");
          $State->clear("$type:$name:volume.u2vol1");
          $State->clear("$type:$name:volume.u2vol2");
       }
  
    }
  }
  State->write();
  &get_topos($q);
  #
}

sub topo {
  my($q) = @_;

  eval {
   TO->readTopo($q->{topo}); # get objects in globals
   &topoApplet();
  };
  print "$@";

}




1;
