#!/usr/bin/perl
package sdevCodeCurationPage;

#######################################################################
##### Author :	Shuai Weng
##### Date   :  August 2000
##### Description : This package contains all necessary methods for dictyBase
#####               curators to enter, update or delete code info 
#####               in oracle database. 
#####              
#######################################################################
use strict;
use DBI;
use CGI qw/:all :html3/;
use CGI::Carp qw(fatalsToBrowser);
use lib "/usr/local/dicty/www_dictybase/db/lib/common";
use Login qw (ConnectToDatabase);
use TextUtil qw (DeleteUnwantedChar);
use lib "/usr/local/dicty/www_dictybase/db/lib/dictyBase";
use dictyBaseCentralMod qw(:formatPage :getInfo);
use lib "/usr/local/dicty/www_dictybase/db/lib/dictyBase/Objects";
use ConfigURLdictyBase;
use Delete_log;
use Update_log;
use Code;

#######################################################################
#################### global variables #################################
#######################################################################

my $dbh;
my $dblink; 
my $configUrl;

#######################################################################
sub new {      ############ constructor ###############################
#######################################################################
       
	my ($self, %args) = @_;

	$self = {};
	bless $self;

      	$self->{'_database'} = $args{'database'};
	$self->{'_help'}     = defined($args{'help'}) ? 
	                       $args{'help'} : "";
	$self->{'_title'}    = defined($args{'title'}) ? 
	                       $args{'title'} : "Code Curation Page";
	$self->{'_user'}     = defined($args{'user'}) ? $args{'user'} : "";
	$dbh = &ConnectToDatabase($self->database);
    	return $self;
}

sub help { $_[0]->{_help} }
sub database { $_[0]->{_database} }
sub title { $_[0]->{_title} }
sub user { $_[0]->{_user} }

######################################################################
sub DESTROY {   ############ destructor ##############################
######################################################################
    	if (defined $dbh) {
		$dbh->disconnect;
    	}
}

######################################################################
sub start{
######################################################################

    	my ($self) = @_;
	$configUrl = ConfigURLdictyBase->new;	
	$dblink = $configUrl->dblink($self->database);
	if (!$self->user) {
	    print "location: ", $configUrl->dictyBaseCGIRoot, "$dblink/curatorLogin\n";
	    print "Content-type: text/html\n\n";
	    exit;
	}
	my ($dbuser, $dbpasswd) = &getUsernamePassword(uc($self->user), 
						       $self->database);
	if (!$dbuser || !$dbpasswd) {
	    print "location: ", $configUrl->dictyBaseCGIRoot, "$dblink/curatorLogin\n";
	    print "Content-type: text/html\n\n";
	    exit;
	}
	if (param('commit')) {
	    $dbh->disconnect;
	    $dbh = &ConnectToDatabase($self->database, $dbuser, $dbpasswd);
	    $self->commitInfo;
	}
	elsif (param('type') =~ /edit/i) {
	    $self->editInfo;
        }
	elsif (param('type') =~ /delete/i) {
	    $self->deleteInfo;
        }
	elsif (param('type') =~ /new/i) {
	    $self->enterInfo;
        }
        else {
	    $self->displayInfo;
        }
}

#######################################################################
sub displayInfo {
#######################################################################
        my ($self) = shift;

	&printStartPage($self->database, $self->title, $self->help);

	my $colHeader = param('colHeader');
	if (!$colHeader) { $colHeader = "CODE_NO"; } 

 	$self->printTopForm($colHeader);

	my $filterBy = param('filterBy');
	my $start = param('start');
	if (!$start) { $start = 1;}
	my $user = $self->user;
	my $deleteGif = $configUrl->dictyBaseImages."delete.gif";
	my $editGif = $configUrl->dictyBaseImages."edit.gif";
	my $newGif = $configUrl->dictyBaseImages."new.gif";
	my ($i, $stop, $end);
	my @tabRows;
	my $arrayRef = Code->GetCodeDetail(dbh=>$dbh,
					   colHeader=>$colHeader,
					   filterBy=>$filterBy);
	foreach my $rowRef (@$arrayRef) {

	    $i++;
	    if ($i < $start) { next; }
	    if ($i >= $start + 50) { 
		if (!$stop) {$stop = $i-1;}
		next;
	    }
	    my ($codeNo, $tabNm, $colNm, $codeVal, $desc, $dateCreated, 
		$createdBy) = @$rowRef;

	    $desc = $desc || br;
	    my $images = a({-href=>url."?user=$user&codeNo=$codeNo&type=delete"},img({-src=>"$deleteGif",-width=>"20",-height=>"20",border=>"0",-alt=>'Delete'})).a({-href=>url."?user=$user&codeNo=$codeNo&type=edit"},img({-src=>"$editGif",-width=>"20",-height=>"20",border=>"0",-alt=>'Edit'})).a({-href=>url."?user=$user&codeNo=$codeNo&type=new"},img({-src=>"$newGif",-width=>"20",-height=>"20",border=>"0",-alt=>'New'}));
	    push(@tabRows, Tr({-align=>'CENTER'},td({-width=>'10%'},$images).td({-width=>'8%',-align=>'CENTER'},font({-size=>'2'},$codeNo)).td({-width=>'15%',-align=>'CENTER'},font({-size=>'2'},$tabNm)).td({-width=>'15%',-align=>'CENTER'},font({-size=>'2'},$colNm)).td({-width=>'8%',-align=>'CENTER'},font({-size=>'2'},$codeVal)).td({-width=>'15%',-align=>'CENTER'},font({-size=>'2'},$desc)).td({-width=>'8%',-align=>'CENTER'},font({-size=>'2'},$dateCreated)).td({-width=>'8%',-align=>'CENTER'},font({-size=>'2'},$createdBy))));
	    
	}
	$end = $i;
	if (!$stop) { $stop = $end;}
	$self->printPrevNext($start, $stop, $end, $colHeader, $filterBy);
	print table({-width=>'90%',-border=>1,-cellspacing=>1,-align=>'CENTER',-bordercolor=>'#BBBBEE',-bordercolordark=>'#0000FF',-bordercolorlight=>'#FFFFFF'},
		    $self->tableHeader,
		    @tabRows
	);
	$self->printPrevNext($start, $stop, $end, $colHeader, $filterBy);

	&printEndPage;
}


#######################################################################
sub enterInfo {
#######################################################################
        my ($self) = shift;

	&printStartPage($self->database, $self->title, $self->help);

	my $code = Code->new(dbh=>$dbh,
			     code_no=>param('codeNo'));
        print p, b(font({-size=>'+2'},"Enter the new code value and description below.")),p;
		
	print 
	    startform,
	    hidden('user', $self->user),
	    hidden('tabNm', $code->tab_name),
	    hidden('colNm', $code->col_name),
 	    hidden('type', 'new');
	$self->printEntryBox($code->tab_name, $code->col_name);
	print p,
	    submit('commit', 'Submit'),
	    endform;      

	&printEndPage;
}


#######################################################################
sub editInfo {
#######################################################################
        my ($self) = shift;

	&printStartPage($self->database, $self->title, $self->help);
	my $code = Code->new(dbh=>$dbh,
			     code_no=>param('codeNo'));
	print p, b(font({-size=>'+2'},"Edit the code value and/or description below.")),p;
	
	print 
	    startform;
	$self->printEntryBox($code->tab_name, $code->col_name, 
			     $code->code_value, $code->description);
	$self->printLogBox("Update log comments");
	print p,
	    hidden('codeNo', param('codeNo')),
	    hidden('user', $self->user),
 	    hidden('type', 'edit'),
	    submit('commit', 'Submit'),
	    endform;   

	&printEndPage;
}


#######################################################################
sub deleteInfo {
#######################################################################
        my ($self) = shift;

	&printStartPage($self->database, $self->title, $self->help);
	my $code = Code->new(dbh=>$dbh,
			     code_no=>param('codeNo'));
	print p, b(font({-size=>'+2'},"Click 'Delete' to delete this code from the database.")), p; 
      
	print 
	    startform,
	    hidden('user', $self->user),
	    hidden('codeNo', param('codeNo')),
 	    hidden('type', 'delete');
	$self->printEntryBox($code->tab_name, $code->col_name, 
			     $code->code_value, $code->description,
			     "delete");
	$self->printLogBox("Delete log comments");
	print p,
	    submit('commit', 'Submit'),
	    endform;  
	&printEndPage;
}

########################################################################
sub commitInfo {
########################################################################
    my ($self) = shift;
    &printStartPage($self->database, $self->title, $self->help);
    ##################

    if (param('type') =~ /edit/i) {
	$self->DoUpdate;
    }
    elsif (param('type') =~ /delete/i) {
	$self->DoDelete;
    }
    elsif (param('type') =~ /new/i) {
	$self->DoInsert;
    }
    ##################
    print p, b("Return to ".a({-href=>$configUrl->dictyBaseCGIRoot."$dblink/curatorLogin?user=".$self->user}, "dictyBase Curator Central")), br;
    ##################

    ##################
    &printEndPage;
    ##################         
}

#######################################################################
sub DoUpdate {
#######################################################################
    my ($self) = @_;

    my $codeVal = param('codeVal');
    my $desc = param('desc');
    my $log = param('log');
    &DeleteUnwantedChar(\$codeVal);
    &DeleteUnwantedChar(\$desc);
    &DeleteUnwantedChar(\$log);

    my $code = Code->new(dbh=>$dbh,
			 code_no=>param('codeNo'));

    my $codeValDB = $code->code_value;
    my $descDB = $code->description; 

    my (@oldVal, @newVal, @colNm);
    if ($codeVal ne $codeValDB) {
	$code->updateCode_value($codeVal);
	push(@oldVal, $codeValDB);
	push(@newVal, $codeVal);
	push(@colNm, "CODE_VALUE");
    }
    if ($desc ne $descDB) {
	$code->updateDescription($desc);
	push(@oldVal, $descDB);
	push(@newVal, $desc);
	push(@colNm, "DESCRIPTION");
    }
    if (@colNm) {
	eval { $code->enterUpdates; };
	if ($@) {
	    print "An error occurred: $@",br;
	    $dbh->rollback;
	}
	else {
	    $dbh->commit;
	    print "The code_value for code_no = ".param('codeNo')." has been updated.",p;
	    if ($log) {
		for (my $i = 0; $i <= $#colNm; $i++) {
		    my $ulog = Update_log->new(dbh=>$dbh,
					       tab_name=>'CODE',
					       col_name=>$colNm[$i],
					       primary_key=>param('codeNo'),
					       old_value=>$oldVal[$i],
					       new_value=>$newVal[$i]);
		    $ulog->updateDescription($log);
		    eval { $ulog->enterUpdates($self->user);};
		    if ($@) {
			print "An error occurred when updating update_log table.$@", br;
			$dbh->rollback;
		    }
		    else {
			$dbh->commit;
			print "The update log comment for updating $colNm[$i] has been inserted into update_log table.",p;
		    }
		}
	    }
	}
    }
}

#######################################################################
sub DoDelete {
#######################################################################
    my ($self) = @_;

    my $log = param('log');
    &DeleteUnwantedChar(\$log);
    ##################
    my $code = Code->new(dbh=>$dbh,
			 code_no=>param('codeNo'));
 
    my $tabNm = $code->tab_name;
    my $colNm = $code->col_name;
    my $codeVal = $code->code_value;
    my $found = Code->IsCodeInUse(dbh=>$dbh,
	 			  tab_name=>$tabNm,
				  col_name=>$colNm,
				  code_value=>$codeVal);
    if ($found) {
	print "Cannot delete this code because it is currently being used<br>";
	return;
    }
    my $deletedRow = $code->getRow;
    eval { $code->delete; };
    if ($@) {
	print "An error occurred when deleting the entry in code table: $@",br;
	$dbh->rollback;
    }
    else {
	$dbh->commit;
        print "The code entry for code_no = ".param('codeNo')." has been deleted from code table.", p;
	if ($log) {
	    my $dlog = Delete_log->new(dbh=>$dbh,
				       tab_name=>'CODE',
	    			       deleted_row=>$deletedRow);
	    
	    $dlog->updateDescription($log);
	    eval { $dlog->enterUpdates($self->user); };
	    if ($@) {
	    	print "An error occurred when updating the delete_log table: $@", br;
	    	$dbh->rollback;
	    }
	    else {
	    	$dbh->commit;
	    	print "The delete log has been inserted into delete_log table.", br;
	    }
	}
    }
}

#######################################################################
sub DoInsert {
#######################################################################
    my ($self) = @_;
    my $tabNm = param('tabNm');
    my $colNm = param('colNm');
    my $codeVal = param('codeVal');
    my $desc = param('desc');
    &DeleteUnwantedChar(\$codeVal);
    &DeleteUnwantedChar(\$desc);

    eval { 
	Code->Insert(dbh=>$dbh,
		     literals=>{code_no=>'CGM_DDB.codeno_seq.nextval'},
		     binds=>{tab_name=>$tabNm,
			     col_name=>$colNm,
			     code_value=>$codeVal,
			     description=>$desc});
    };
    if ($@) {
	print "An error occurred: $@",br;
	$dbh->rollback;
    }
    else {
	$dbh->commit;
        print "The new code entry has been inserted into code table.", p;
    }
} 

#######################################################################
sub printPrevNext {
#######################################################################
    my ($self, $start, $stop, $end, $colHeader, $filterBy) = @_;
    my ($preStart, $nextStart);
    if ($end > $stop+1) {
	$nextStart = $stop+1;
    }
    if ($start > 1) {
	$preStart = $start - 50;
	if ($preStart < 1) { $preStart = 1;}
    }
    if (!$preStart && !$nextStart) { return;}
    print table({-width=>'96%',-border=>0,-cellspacing=>1,-align=>'CENTER',-bordercolor=>'#BBBBEE',-bordercolordark=>'#0000FF',-bordercolorlight=>'#FFFFFF'},
		$self->prevNext($preStart, $nextStart, $colHeader, $filterBy)
    );    
}

########################################################################
sub prevNext {
########################################################################
    my ($self, $preStart, $nextStart, $colHeader, $filterBy) = @_;
    my $user = $self->user;
    if ($preStart && !$nextStart) {
	return Tr(td({-align=>'LEFT'},a({-href=>url."?user=$user&start=$preStart&colHeader=$colHeader&filterBy=$filterBy"},img({-src=>$configUrl->dictyBaseImages.'arr_prev_uoi_l.gif',-width=>'55',-height=>'18',border=>'0',-alt=>'Prev'})))
		  );
    }
    elsif (!$preStart && $nextStart) {
	return Tr(td({-align=>'LEFT'},a({-href=>url."?user=$user&start=$nextStart&colHeader=$colHeader&filterBy=$filterBy"},img({-src=>$configUrl->dictyBaseImages.'arr_next_uic_r.gif',-width=>'55',-height=>"18",border=>"0",-alt=>'Next'})))
	   );
    }
    else {
	return Tr(td({-align=>'LEFT'},a({-href=>url."?user=$user&start=$preStart&colHeader=$colHeader&filterBy=$filterBy"},img({-src=>$configUrl->dictyBaseImages.'arr_prev_uoi_l.gif',-width=>'55',-height=>'18',border=>'0',-alt=>'Prev'})),a({-href=>url."?user=$user&start=$nextStart&colHeader=$colHeader&filterBy=$filterBy"},img({-src=>$configUrl->dictyBaseImages.'arr_next_uic_r.gif',-width=>'55',-height=>'18',border=>'0',-alt=>'Next'})))
	   );
    }
}

########################################################################
sub printTopForm {
########################################################################
    my ($self, $colHeader) = @_; 
    my %typeLabels = ('CODE_NO'=>'Code Number',
		      'TAB_NAME'=>'Table Name',
		      'COL_NAME'=>'Column Name',
		      'CODE_VALUE'=>'Code Value',
		      'DESCRIPTION'=>'Description',
		      'DATE_CREATED'=>'Date Created',
		      'CREATED_BY'=>'Created By');
    my @typeValues = qw/CODE_NO TAB_NAME COL_NAME CODE_VALUE DESCRIPTION DATE_CREATED CREATED_BY/;
    my $defaultType = "$colHeader";
    my $user = $self->user;

    ##########################
    print 
    startform;

    print table({-border=>1,-cellspacing=>1,-align=>'CENTER',-bordercolor=>"#BBBBEE",-bordercolordark=>"#0000FF",-bordercolorlight=>"#FFFFFF"},
                Tr({-align=>'CENTER'},[
                        th({-bgcolor=>"#CCCCCC",-width=>650},"Code Table Display",br)]),
                Tr({-align=>'LEFT'},
                [
                        td("List Sorted By Column Header: ",
                        popup_menu(-name=>'colHeader',
				   -size=>-1,
				   -"values"=>\@typeValues,
				   -default=>$defaultType,
				   -labels=>\%typeLabels
				   ),
                        'List filtered (on Sort Header):',
                        textfield(-name=>'filterBy',
                                  -size=>14,-override=>1),
                        hidden(-name=>'user', -value=>"$user"),
                        submit(-name=>'Re-list', -value=>'Re-list'))
                ])
        );
    print endform,br,br;
}


########################################################################
sub tableHeader {
########################################################################

    return 
	Tr({-align=>'LEFT'},
	   th({-width=>'13%',-align=>'CENTER'},
	      font({-size=>'3'},strong(['Del/Edit/New']))),
	   th({-width=>'8%',-align=>'CENTER'},
	      font({-size=>'3'},strong(['Code Number']))),
	   th({-width=>'17%',-align=>'CENTER'},
	      font({-size=>'3'},strong(['Table Name']))),
	   th({-width=>'17%',-align=>'CENTER'},
	      font({-size=>'3'},strong(['Column Name']))),
	   th({-width=>'12%',-align=>'CENTER'},
	      font({-size=>'3'},strong(['Code Value']))),
	   th({-width=>'17%',-align=>'CENTER'},
	      font({-size=>'3'},strong(['Description']))),
	   th({-width=>'8%',-align=>'CENTER'},
	      font({-size=>'3'},strong(['Date Created']))),
	   th({-width=>'8%',-align=>'CENTER'},
	      font({-size=>'3'},strong(['Created By'])))
	   );

}

#######################################################################
sub printEntryBox{
########################################################################
    my ($self, $tabNm, $colNm, $codeVal, $desc, $delete) = @_;
    if ($delete) { $desc = $desc || br; }
    print table({-width=>650,-border=>1,-cellspacing=>1,-cellpadding=>"+3",-bordercolor=>'#BBBBEE',-bordercolordark=>'#0000FF',-bordercolorlight=>'#FFFFFF'},
 		Tr({-align=>'LEFT'},
 			th({-bgcolor=>'#CCCCCC'},"Table Name"),
			th({-bgcolor=>'#CCCCCC'},"Column Name"),
			th({-bgcolor=>'#CCCCCC'},"Code Value"),
			th({-bgcolor=>'#CCCCCC'},"Description")),
		$self->entryRow($tabNm, $colNm, $codeVal, $desc, $delete)
	);

}

######################################################################
sub entryRow {
######################################################################
    my ($self, $tabNm, $colNm, $codeVal, $desc, $delete) = @_;
    if ($delete) {
	return Tr({-align=>'LEFT'},
			td(font({-size=>"+1"},$tabNm)),		
			td(font({-size=>"+1"},$colNm)),		
			td(font({-size=>"+1"},$codeVal)),
		        td(font({-size=>"+1"},$desc))
		  );
    }
    else {
	return Tr({-align=>'LEFT'},
			td(font({-size=>"+1"},$tabNm)),		
			td(font({-size=>"+1"},$colNm)),		
			td(start_form(),
			   textfield(-name=>'codeVal',
				     -value=>"$codeVal",
		                     -size=>20)),		
			td(textfield(-name=>'desc',
				     -value=>"$desc",
				     -size=>40))
		  );
    }
}


######################################################################
sub printLogBox {
######################################################################
    my ($self, $text) = @_;

    print table({-width=>650,-border=>1,-cellspacing=>1,-cellpadding=>'+3',-bordercolor=>'#BBBBEE',-bordercolordark=>'#0000FF',-bordercolorlight=>"#FFFFFF"},
   		Tr({-align=>'CENTER'},
  		    th({-colspan=>4,-bgcolor=>"#CCCCCC"},
		       $text)),	
 		Tr({-align=>'LEFT'},
 		    td({-colspan=>4},start_form(),
 		       textarea(-name=>'log',
				-rows=>3,
				-columns=>65)))
 	);
}

########################################################################
sub err_report {
########################################################################
    my ($self, $err) = @_;
    
    &printStartPage($self->database, $self->title, $self->help);
	
    print b($err);
    
    &printEndPage;
    $dbh->disconnect;
    exit;
}

########################################################################
1;
########################################################################



















