#!/usr/local/bin/perl5
# -*- perl -*-
use P4CGI ;
use strict ;
#
#####################################################################
##
##  CONFIGURATION INFORMATION 
##  All config info should be in $configFile (see init() in P4CGI.pm)
##
#####################################################################
##
##  CHange Browser
##
#####################################################################

# Set back references
my $homepage="index.cgi";
my $backtohome="Back to Home" ;

# Various vars
my $fspec ;
my $pending ;
my $status = "" ;
my $type = "" ;
my $user = "";

# Get file spec argument
my $filespec = P4CGI::cgi()->param("FSPC") ;
$filespec = "//..." unless defined $filespec ;

# Get label argument
my $label = P4CGI::cgi()->param("LABEL") ;
if(defined $label and $label eq "-") { $label = undef ; } ;

# Get spec of files to exclude from list of changes
my $exfiles = P4CGI::cgi()->param("EXFSPC") ;
if(defined $exfiles and $exfiles eq "-") { $exfiles = undef ; } ;

# Get label to exclude
my $exlabel = P4CGI::cgi()->param("EXLABEL") ;
if(defined $exlabel and $exlabel eq "-") { $exlabel = undef ; } ;

# Get status
$status = P4CGI::cgi()->param("STATUS") ;
unless(defined $status) { $status = "submitted" ; } ;

# Get branch status and name
my $branch = P4CGI::cgi()->param("BRANCH") ;
if(defined $branch) {
  $fspec = P4CGI::cgi()->param("BR") ;
  $type = " branch" ;
}

# Get user 
my $ta ; # (throwaway)
$user = P4CGI::cgi()->param("USER") ;
($user,$ta) = split / /,$user ;

# Set title 
my $title = "Change History" ;

# Get max changes to show
my $maxchanges = P4CGI::cgi()->param("MAXCH") ;
my $changeoffset ;
my $choffstr="" ;
if(defined $maxchanges && $maxchanges =~ /^\d+$/) {
    # Get offset of first change
    $changeoffset = P4CGI::cgi()->param("CHOFFSET") ;
    if(defined $changeoffset) {
	$choffstr="\@$changeoffset" ;
	$changeoffset = P4CGI::cgi()->param("CHOFFSETDISP") ;
    }
    else {
	$changeoffset = 0 ;
    }
    $maxchanges = "-m $maxchanges" ;
}
else {
    $maxchanges = "" ;
}

if(defined $label) {
    $choffstr="" ;
    if($filespec eq "//...") {
	$filespec .= "\@$label" ;
    }
    else {
	$filespec =~ s/ /@$label / ;
	$filespec .= "\@$label" ;
    }
}

# Get list of files in changes to exclude
my @exclude;
if(defined $exlabel) {
    if(defined $exfiles) {
	$exfiles .= "\@$exlabel" ;
    }
    else {
	$exfiles = "//...\@$exlabel" ;
    }
}
local *P4 ;
if(defined $exfiles) {
    &P4CGI::p4call(*P4,"changes \"$exfiles\"") ;
    while(<P4>) {
	/^Change (\d+)/ ;
	    push @exclude,$1 ;
    }
    close P4 ;	
    push @exclude,0 ;
}

# Save an unquoted copy of the filename
$fspec = $filespec unless defined $fspec ;

# Make filename quoted, for passing purposes
$filespec = "\"$filespec\"" ;

# Set title for pending chgs
if($status eq "pending") {
    $title = "Pending Changes" ;
    $filespec = "" ;
} ;

# Get the changes
&P4CGI::p4call(*P4,"changes -l $maxchanges -s $status $filespec$choffstr") ;

# Set excluded files
my $nextToExclude = shift @exclude ;
if(!defined $nextToExclude) { $nextToExclude = 0 ; } ;

# Get users, for form
my @allusers ;
my @p4users ;
&P4CGI::p4call(\@allusers, "users" );
while ( @allusers > 0 )
{
    my $usertemp = shift @allusers ;
    $usertemp =~ /(.*) <.* (\(.*\)) .*$/ ;
    my $username = "$1" . " " . "$2" ;
    push( @p4users, "$username" ) ;
}

# Print title and legend
print
    "",
    &P4CGI::start_page($title,
	&P4CGI::ul_list("<b>Change Number:</b> to see details of change"),
	    $homepage,$backtohome) ;

# Print specify-a-user-for-{pending-changes/branch-changes}-form
if ( $status eq "pending" ) {
print
    "",
    &P4CGI::cgi()->startform(-action => &P4CGI::CHB_URL(),
			     -method => "GET"),	
    &P4CGI::cgi()->hidden("-name","FSPC",
			  "-value","//..."),    
    &P4CGI::cgi()->hidden("-name","STATUS",
			  "-value","pending"),    
    "<b><i>View pending changes only for: </i></b>",
    &P4CGI::cgi()->popup_menu(-name  => "USER",
			      -value => \@p4users),
    &P4CGI::cgi()->submit(-name  => "Go",
			  -value => "Go"),
    &P4CGI::cgi()->endform() ;
print
    "<hr>" ;
}
elsif ( defined $branch ) {
  print
    "",
    &P4CGI::cgi()->startform(-action => &P4CGI::CHB_URL(),
			     -method => "GET"),	
    &P4CGI::cgi()->hidden("-name","FSPC",
			  "-value","$branch"),    
    &P4CGI::cgi()->hidden("-name","BRANCH",
			  "-value","YES"),    
    &P4CGI::cgi()->hidden("-name","BR",
			  "-value","$fspec"),    
    "<b><i>View branch changes only for: </i></b>",	
    &P4CGI::cgi()->popup_menu(-name  => "USER",
			      -value => \@p4users),
    &P4CGI::cgi()->submit(-name  => "Go",
			  -value => "Go"),
    &P4CGI::cgi()->endform() ;
  print
    "<hr>" ;
}
elsif ( defined $label ) {
  print
    "",
    &P4CGI::cgi()->startform(-action => &P4CGI::CHB_URL(),
			     -method => "GET"),	
    &P4CGI::cgi()->hidden("-name","LABEL",
			  "-value","$label"),    
    "<b><i>View changes on label only for: </i></b>",
    &P4CGI::cgi()->popup_menu(-name  => "USER",
			      -value => \@p4users),
    &P4CGI::cgi()->submit(-name  => "Go",
			  -value => "Go"),
    &P4CGI::cgi()->endform() ;
  print
    "<hr>" ;
}

# Print page...(ridiculous, but expeditious)
my $printed ;
if ( $status eq "pending" ) {
  if ( $user ) {
    print
	"<dt>",
	"<b>Pending changes for:</b> <font color=green>$user</font>" ;
    $printed = "true" ;
  }
  else {
    print
	"",
	"<b>Pending changes for:</b> <font color=green>all users</font>" ;
    $printed = "true" ;
  }
}
else {
  if ( $user ) {
    if ( $label ) {
      print
	"",
	"<b>Changes for label $label for:</b> <font color=green>$user</font>" ;
      $printed = "true" ;
    }
    elsif ( $branch ) {
      print
	"",
	"<b>Changes for branch $fspec for:</b> <font color=green>$user</font>" ;
      $printed = "true" ;
    }
    else {
      print
	"",
	"<b>Changes for:</b> <font color=green>$user</font>" ;
      $printed = "true" ;
    }
  }
  else {
    if ( !defined $label ) {
      print
	"<dt>",
	"<b>Changes for",
	"$type:</b> <font color=green>$fspec</font>" ;
      $printed = "true" ;
    }
  }
}

if( !defined $printed ) {
  if( defined $label ) {
    print
	"<dt>",
	"<b>Changes for label:</b> <font color=green>$label</font></b>" ;
  }
  if(defined $exfiles) {
    print
	"<dt>",
	"&nbsp;&nbsp;(excluding changes also found in
	 <font color=red>$exlabel</font>)" ;
  }
  if(defined $maxchanges && $maxchanges =~ /^\d+$/) {
    if(defined $changeoffset) {
	print
	    "<dt>",
	    "<b>Changes for",
	    "$type:</b> <font color=green>$fspec</font>
	    (offset:$changeoffset)" ;
    }
  }
}

# For change number and description
my ( $change, $misc ) ;

# Skip files to exclude
my $skipped=0 ;
my $skip;
print "<dl>" ;
my $displayed = 0 ;
my $lastch ;
while (<P4>) {
    $_ = &P4CGI::fixSpecChar($_) ;
    if(/^Change (\d+) (.*)$/) {	
	$skip="no" ;
	( $change, $misc ) = ($1,$2) ;
	$lastch = $change ;
	if ($change == $nextToExclude) {
	    $nextToExclude = shift @exclude ;
	    $skip="yes" ;
	    $skipped++ ;
	    next ;
	}
	$skipped=0 ;
	if ( $user ) {
	    if ( $misc =~ / by $user/ ) {
		if( $status eq "pending" ) { $pending="true" ; }
		print
		    "<dt>",
		    &P4CGI::ahref("-url",P4CGI::CHV_URL(),
		    "CH=$change", "<br>Change $change "),
		    "$misc<dd>\n" ;
		$displayed++ ;
	    }
	    else {
		next ;
	    }
	}
	else {
	print
	    "<dt>",
	    &P4CGI::ahref("-url",P4CGI::CHV_URL(),
	    "CH=$change", "<br>Change $change "),
	    "$misc<dd>\n" ;
	$displayed++ ;
	}
    }
    else {
	next if $skip eq "yes" ;
	chop ;
	next if $_ eq "" ;
	if ( $user) {
	    if ( $misc =~ / by $user/ ) {
		if( $status eq "pending" ) { $pending="true" ; }
		print
		    "",
		    "$_" ;
	    }
	    else {
		next ;
	    }
	}
	else {
	    print
		"",
		"$_" ;
	}
    }
    print
	"",
	"<br>" ;
}

close P4;

print "</dl>\n" ;

# Check for max changes
my $mc = P4CGI::cgi()->param("MAXCH") ;
if(defined $mc and ($mc == $displayed)) {
    $lastch-- ;
    $changeoffset += $mc ;
    print
	"",
	&P4CGI::ahref("-url",P4CGI::CHB_URL(),
		      "FSPC=".P4CGI::cgi()->param("FSPC"),
		      "STATUS=$status",
		      "CHOFFSET=$lastch",
		      "CHOFFSETDISP=$changeoffset",
		      "MAXCH=$mc",
		      "Next $mc changes") ;
}

# More printing...
if( ! $change && $status ne "pending" ) {
    $displayed = 1 ;
    print
	"",
	"<font color=red>No changes found for file $fspec</font>\n" ;
}

if ( $user ) {
  if ( $status eq "pending" ) {
    if( ! $pending ) {
	$displayed = 1 ;
	print
	"",
	"&nbsp;&nbsp;<font color=red>None</font>\n" ;
    }
  }
  else {
    if( $displayed == 0 ) {
	$displayed = 1 ;
	print
	    "",
	    "&nbsp;&nbsp;<font color=red>None</font>\n" ;
    }
  }

}
if( $displayed == 0 ) {
    print
	"",
	"&nbsp;&nbsp;<font color=red>None</font>\n" ;
}

# End the page
print
    "",
    &P4CGI::end_page();