sub SINGLE {
    require "$Libdir/util.pl";
    &RECHECK($in{'site'});
}

sub TRACEROUTE {
  my $ip = $in{'site'} || return;
  my $output = "";

  if ($DEMO) {
    local($/); undef $/;
    open(F, "<$TracerouteDemo");
    $output = <F>;
    close(F);

  } else {
    my $cmd = $Traceroutecmd . " " . $ip . " 2>&1";
    $output = `$cmd`;
  }

  return "<small><pre>".$output."</pre></small>\n";
}

sub FULLPORT {
    my $quick  = shift;    
    my $ip     = $in{'site'} || return;
    my $p      = $quick ?"" : " -p 1-65535";
    my $cmd    = $Nmapcmd . " --min_rtt_timeout 100 -O -I -sT".$p." ".$ip." 2>/dev/null";
    my $output = ""
    ;
    if ($DEMO) {
      local(*F);
      local($/); undef $/;
      if ($quick) { open(F, "<$QuickPortDemo"); }
      else {        open(F, "<$FullPortDemo");  }
      $output = <F>;
      close(F);

    } else {
      $output = `$cmd`;
    }

    return "<small><pre>".$output."</pre></small>\n";
}

sub QUICKPORT {
    return &FULLPORT(1);
}

sub HISTORY {
    return &DisplayHistory($in{'site'});
}

sub UPDATEINFO {
    &SaveStoredInfo($in{'site'});
    return;
}

sub DisplayStoredInfo {
    my(%site) = @_;
    my($ip) = $site{'ip'};
    return unless $DisplayCustInfo;
    my($i, $s, $k);
    my @out = ();

    my $output = "<form method=\"post\" action=\"".$nPULSEurl."\">".
        "<input type=hidden name=a value=\"detail\">".
        "<input type=hidden name=s value=\"updateinfo\">".
        "<input type=hidden name=site value=\"".$ip."\">".
        "<input type=hidden name=os value=\"".$site{'os'}."\">".
        "<input type=hidden name=icon value=\"".$site{'icon'}."\">".
        "<input type=hidden name=returnurl value=\"".$in{'returnurl'}."\">\n".
        "<p style=\"".$Fss."\"><strong>Information</strong><br>".
        "<table border=0 cellspacing=0 cellpadding=0>\n";

    foreach $s (sort keys %site) {
      next unless $s =~ /_\d/;
      ($k, $i) = $s =~ /^(.*)_(\d+)$/;
      $out[$i] = "<tr><td align=\"right\"><span style=\"".$Fss."\"><nobr>".$k.
                    ":</nobr></span></td><td><input type=text name=\"".$s.
                    "\" size=20 style=\"border-width:0 0 1 0;background-color:transparent;".
                    $Fxs.";color:white\" value=\"".$site{$s}."\"></td></tr>\n";
    }

    $output .= join("\n",@out)."</table></p>\n<center><input type=submit style=\"".
               $Fxs."\" value=\"Update\"><input type=reset style=\"".$Fxs.
               "\" value=\"Reset\"></center>\n</form>\n";
    return $output;
}


sub DisplayHistory {
    my $ip = shift;
	my $filename = &ip2file($ip) . ".hist";
    my $imgsrc    = "/images/" . $ip . $$ . ".jpg";
    my $graphfile = $Htmldir . $imgsrc;
    my $rmcmd = "rm -f " . $Htmldir . "/images/" . $ip . "*.jpg";

    my($time, $gx, $c, $ct, $t, $d, $div, $dtime);
    my(%gdata, %history);
    local(*IMG);
    my @data = ([],[],[],[]);

    return "History flag is turned off." unless $Keephistory;

    my $num = 0;
    my $warn = 0;
    my $ok  = 0;
    my $ctime = time;
    my $output = "";

    my %site = &ReadCurrentFile($ip);
    %history = &ReadHistoryFile($ip, $ctime - ($Maxhistorytime * 86400));

    foreach $time (sort {$a <=> $b} keys %history) {
      $gx = int(($ctime - $time)/86400);
      ($c, $ct, $t) = &colorStatus($history{$time}{'status'});
      ($dtime = scalar(localtime($time))) =~ s/:\d\d \d\d\d\d//;
      $output = $dtime." ".$t."\n".$output;
      $gdata{$gx}{$history{$time}{'status'}}++;

      $num++;
      $ok++   if $history{$time}{'status'} == $Stat_ok;
      $warn++ if $history{$time}{'status'} == $Stat_warn;
    }

    &Error("No recent historical data found in $filename.") unless $num;

    $output = "<pre>".$output."</pre>\n";

    foreach $d (sort {$b <=> $a} keys %gdata) {
      push(@{$data[0]},$d);
      $div = $gdata{$d}{$Stat_ok} + $gdata{$d}{$Stat_warn} + $gdata{$d}{$Stat_fail};
      if ($div) {
        push(@{$data[1]},($gdata{$d}{$Stat_ok}/$div)*100);
        push(@{$data[2]},($gdata{$d}{$Stat_fail}/$div)*100);
        push(@{$data[3]},($gdata{$d}{$Stat_warn}/$div)*100);
      } else {
        push(@{$data[1]},0);
        push(@{$data[2]},0);
        push(@{$data[3]},0);
      }
    }

    return "Uptime OK:".(int(($ok/$num)*1000)/10).
           "%, Warn:".(int((($warn)/$num)*1000)/10).
           "%, Fail:".(int((($num-$ok-$warn)/$num)*1000)/10).
           "%<br>".&genBarGraph($Maxhistorytime,\@data)."<br><small>".
           (($DEBUG || $AlwaysShowNums)?$output:"")."</small>";
}

sub DisplayDETAIL {
    my($ip, $output) = @_;
    my($c, $ct, $t, $td1, $td2, $td3, %buttons, $bg, $fg, $tx);
    my %ports = ();

    my %text = (
        hidetraceroute => "Hide Traceroute",
        traceroute     => "Perform Traceroute",
        hidequickport  => "Hide Port Scan",
        quickport      => "Perform Port Scan",
        hidefullport   => "Hide Full Port Scan",
        fullport       => "Perform Full Port Scan",
        history        => "Show Historical Info",
        hidehistory    => "Hide Historical Info",
        recheck        => "Recheck this Site Only",
        hiderecheck    => "Recheck this Site Only"
    );

    my(%site) = &ReadCurrentFile($ip);
    $site{'os'} =~ s/\|/<br>/g;
    print &Header($Myname,"","Detail for ".$site{'ip'});

    $td1 = "<td style=\"$Fsn\"><img width=32 height=32 align=\"left\" border=0 src=\"/images/".
           $site{'icon'}.".gif\"> ".$site{'name'}."<br>".
           ($site{'alias'}?"(".$site{'alias'}.")<br>":"").$site{'os'}."<br>".
           "<table border=1><tr>".
           "<td align=\"center\"><span style=\"$Fsn\">Port</span></td>".
           "<td align=\"center\"><span style=\"$Fsn\">Type</span></td>".
           "<td align=\"center\"><span style=\"$Fsn\">Status</span></td>".
           "</tr>\n";

    foreach (split(/,\s*/,$site{'ports'})) { $ports{$_} = 1; }
    foreach (split(/,\s*/,$site{'portlist'})) {
      ($bg, $fg, $tx) = exists $ports{$_} ? ($Color_ok, $Text_ok, "OK") : ($Color_fail, $Text_fail, "FAIL");
      
      $td1 .= "<tr><td align=\"right\"><span style=\"$Fss\">".$_."</span></td>".
              "<td><span style=\"$Fss\">".($Services{$_}?$Services{$_}:"unknown")."</span></td>".
              "<td style=\"background-color:$bg\"><span style=\"$Fss;color:$fg;background-color:$bg\">".$tx."</span></td></tr>\n";
    }

    ($c, $ct, $t) = &colorStatus($site{'status'});
    $td2 = "<td><div style=\"".$Fss.";color:".$ct.";background-color:".$c."\">".
           (($site{'status'} == $Stat_fail)?"Device is not responding":($site{'status'} == $Stat_warn)?"Device responding with errors":"Device responding ok")."</div>";
    $td3 = "<td><span style=\"background-color:#272727;border:1 solid white;\">".
           &DisplayStoredInfo(%site)."</span></td>\n" if $DisplayCustInfo;

    foreach (qw(traceroute quickport fullport history recheck)) {
      $buttons{$_} = "<a onMouseOver=\"s".$_.".src='images/s".$_."_on.gif'\"".
                     "   onMouseOut=\"s".$_.".src='images/s".$_.".gif'\"".
                     "   href=\"".$nPULSEurl."?a=detail&site=".$ip."&returnurl=".$in{'returnurl'};
      $buttons{$_} .= (($in{'s'} =~ /$_/i) ? "" : "&s=".$_) unless $_ eq 'recheck';
      $buttons{$_} .= "\"><img width=23 height=22 border=0 src=\"images/s".$_.".gif\" name=s".$_.">";
      $buttons{$_} .= ($in{'s'} =~ /$_/i) ? $text{'hide'.$_} : $text{$_};
      $buttons{$_} .= "</a>";
    }

    $td1 .= "</table>\n</td>\n";
    $td2 .= "<br><span style=\"$Fss\">".$buttons{traceroute}."<br>\n".
                                        $buttons{quickport}."<br>\n".
                                        $buttons{fullport}."<br>\n".
                                        $buttons{history}."<br>\n".
                                        $buttons{recheck}."</span></td>\n";
    print "<table cellspacing=4 width=\"100%\"><tr valign=\"top\">".$td1.$td2.$td3.
          "</tr></table>\n".$output.&Footer();
}

sub genBarGraph {
    use strict;
    my ($xmax,$data) = @_;
    my (@yp);
    my (@colors) = qw(gbar rbar ybar);
    my ($j,$i,$maxh,$bar);

    my $xp = $data->[0];
    my $numsets = $#{$data};
    
    return unless $numsets > 0;

    
    foreach $i (1..$numsets) {
      $yp[$i-1] = $data->[$i];
    }

    my $out = '<table border=1 cellspacing=0 cellpadding=2><tr><td>'.
              '<table border=0 cellspacing=0 cellpadding=0><tr valign="bottom">'.
              '<td><img src=images/ytick.gif width=40 height=102></td>';
    my $dat = '';
    my $xaxis = '<tr valign="top" align="center"><td></td>';
    foreach $i (0..($xmax-1)) {
      $xaxis .= '<td><img src=images/xtick.gif width=19 height=3><br><small>'.($xmax-$i-1).'</small></td>';
      $bar = '';
      if ($i <= $#{$xp}) {
        my %yvals;
        foreach $j (0..$#yp) {
          $yvals{int($yp[$j]->[$i])} = $colors[$j];
        }

        $maxh = 0;
        foreach (sort {$a <=> $b} keys %yvals) {
          $bar = '<img src="images/'.$yvals{$_}.'.gif" width=19 height='.($_-$maxh).'><br>'.$bar if $_ > $maxh;
          $maxh += $_;
        }

        $bar = '<img src=images/bbar.gif width=19 height='.(100-$maxh).'><br>'.$bar if $maxh < 100;
        $dat .= '<td>'.$bar.'</td>';
      } else {
        $dat = '<td><img src=images/bbar.gif width=19 height=100><br></td>'.$dat;
      }
    }
    $out .= $dat.'</tr>'.$xaxis.'</tr><tr align="center"><td colspan='.$xmax.'>Past '.$xmax.' Days</td></tr>';
    $out .= '</table></td></tr></table>';
    return $out;
}
1;
