package QAResultsManager;
use strict;
use warnings;


use DBI;
use Digest::MD5 qw(md5 md5_hex md5_base64);
use DateTime;
use lib qw(Core);
use Database;
use PDBUtils;
use Configuration;
use LocalConfiguration;
use ResultsManager;
#use TargetsManager
my $r_m = new ResultsManager();
use CGI qw(:all);
use BO;
our @ISA = qw(BO);
sub new {
    my ($class) = @_;
    my $self = $class->SUPER::new("casp13.qa_results");
    
    bless $self, $class;	
    return $self;    
}

sub get_new_model {
    my ($self) = @_;    
    my %model = (
########################### system        
	id => '',
	results_id => '',
        qa_analysis_id => '',
	ts_predictions_id => '',
########################## file name
        TARGET => '',	
	MODEL=> '',
	PFRMAT=> '',
	PARENT=> '',	
####################### 
################# SUMMARY
	mqas_score => '',
	distances => '',
	mean => '',
	deviation => '',
	pearson => '',
	fisher_zprime => '',
	differences => '',
	res_count => '',
	INDEX => 0
    );
    return %model;
}

sub is_table_column {
my ($self, $colunm_name) = @_;
my $result = 0;
if(	$colunm_name eq 'id' ||
	$colunm_name eq 'results_id' ||   
	$colunm_name eq 'qa_analysis_id' ||
	$colunm_name eq 'ts_predictions_id' ||
	########################### results	
	################# SUMMARY
	$colunm_name eq 'mqas_score' ||
	$colunm_name eq 'distances' ||	
	$colunm_name eq 'mean' ||
	$colunm_name eq 'deviation' ||
	$colunm_name eq 'pearson' ||
	$colunm_name eq 'fisher_zprime' ||
	$colunm_name eq 'differences' ||
	$colunm_name eq 'res_count'
	
  ) {
	$result = 1;
	}
    return $result;
}

sub exist_by_parameters {
    my ($self, %model) = @_;
    my $result = 0;
    my $query = sprintf("SELECT qr.id FROM %s qr JOIN casp13.results re ON (re.id = qr.results_id)
	JOIN casp13.predictions pr ON (pr.id = re.predictions_id)
	JOIN casp13.groups gr ON (gr.id = pr.groups_id)
	JOIN casp13.qa_analysis qa ON (qa.id = qr.qa_analysis_id)
	WHERE pr.target=\'%s\' and pr.model=\'%s\' and pr.pfrmat=\'%s\' and gr.code=\'%s\'  and  qa.id=\'%s\' and qr.results_id=\'%s\'",
	$self->{_table}, $model{TARGET}, $model{MODEL}, $model{PFRMAT}, $model{CODE}, $model{qa_analysis_id}, $model{results_id});
    my $sth = $self->{_database}->query($query);
    #print $query ."\n";    
    if(defined($sth) && ($sth->rows() > 0)) {
        my ($id) = $sth->fetchrow_array();
	$result = $id;
    }    
    return $result;
}


sub get_results_info {
    my ($self, %model) = @_;    
    my @results = ();
    my $query = sprintf("SELECT re.id, re.predictions_id, re.parent, re.alignment_4, re.gdt_ts_4, re.n1_4 FROM casp13.results re 
	JOIN casp13.predictions pr ON (pr.id = re.predictions_id)
	JOIN casp13.groups gr ON (gr.id = pr.groups_id) WHERE pr.target=\'%s\' and pr.model=\'%s\' and pr.pfrmat=\'%s\' and gr.code=\'%s\'  and  re.domain=0 and  pr.id=%s ",
	$model{TARGET}, $model{MODEL}, $model{PFRMAT}, $model{CODE}, $model{predictions_id});

    my $sth = $self->{_database}->query($query);
    #print $query . "\n";

    if(defined($sth) && ($sth->rows() > 0)) {
        my $index = 1;
        while(my($results_id, $ts_predictions_id, $parent, $alignment_4, $gdt_ts_4, $n1_4) = $sth->fetchrow_array()) {
	    push(@results, {
		INDEX => $index,
		RESULTS_ID => $results_id,
		TS_PREDICTIONS_ID => $ts_predictions_id, 
		PARENT => $parent,		
		distances => $alignment_4,
		gdt_ts_4 => $gdt_ts_4,
		n1_4=> $n1_4,
		}
	    );	
	    $index++;
        }
    }
    return @results;    
    
}
    
    
sub get_rows {
    my ($self, $params, $not_rount) = @_;
    my $field = $params->{field};
    my $order = $params->{order};	
    $field = (!defined($field) || ($field eq '')) ? 'gdt_ts_4' : $field;
    $order = (!defined($order) || ($order eq '')) ? 'DESC' : $order;

    #### DO MULTIPLE SORTING
    my $count_to_replace = 0;
	while ($field =~ s/, / $order,/ || $count_to_replace >20){
	$count_to_replace ++;
    }
    ####    
    my $domain = 0;
    my $sub_query = "";
    
    if(defined($params->{model}) && ($params->{model} ne '')) {
 	$sub_query .= sprintf(" and pr.model=\'%s\' ", $params->{model});	
    }
    
    if(defined($params->{id}) && ($params->{id} ne '')) {
 	$sub_query .= sprintf(" and qr.id=\'%s\' ", $params->{id});	
    }
    ## NOTE DOMAINS NOT IMPLEMENTED FOR REFINEMENT TARGETS
    if(defined($params->{target}) && ($params->{target} ne '')) {
	if ($params->{target} =~ /^(\S+)-D(\S+)/) { 
	    $sub_query .= sprintf(" and pr.target=\'%s\' ", $1);
	    $domain = $2;
	} else {
	    $sub_query .= sprintf(" and pr.target=\'%s\' ", $params->{target});	    
	}
    }
    my $sub_join = "";
    
    if(defined($params->{groups_id}) && ($params->{groups_id} ne '')) {
	$sub_query .= sprintf(" and qa_pr.groups_id=\'%s\' ", $params->{groups_id});

##### AK 2012 - check if this needs to be specified to ensure that models 2 are considered for stage 2
	$sub_query .= " and  qa_pr.pfrmat='QA' and  qa_pr.model=1 ";
	$sub_join.= "JOIN casp13.predictions qa_pr ON (qa.predictions_id = qa_pr.id)"	
    }
    
    
    if(defined($params->{qa}) && ($params->{qa} ne '')) {
	$sub_query .= sprintf(" and qa.id=\'%s\' ", $params->{qa});	
    }
    my $sub_limit = " LIMIT 1000 ";
    if(defined($params->{limit}) && ($params->{limit} ne '')) {
	$sub_limit = sprintf("LIMIT %s",  $params->{limit});
    }
    
    
    ## domain defenition
    ## NOTE DOMAINS NOT IMPLEMENTED FOR REFINEMENT TARGETS
##    
##    if(defined($params->{domain}) && ($params->{domain} ne '')) {	
##	$sub_query .= sprintf(" and rr.domain=\'%s\' ", $params->{domain});
##    } else{
##	$sub_query .= sprintf(" and rr.domain=\'%s\' ", $domain);
##    }
    
    my @results = ();
    my $query = sprintf("SELECT qr.id, qr.results_id, pr.id, pr.target, pr.pfrmat, gr.code, pr.model, re.parent, re.domain,
		re.gdt_ts_4, re.rmsd_5, re.alignment_4, re.n2_4,
		qr.mqas_score, qr.distances, qr.mean,  qr.deviation, qr.pearson, qr.fisher_zprime, qr.res_count, qr.differences
		FROM %s qr JOIN casp13.results re ON (re.id = qr.results_id)
		JOIN casp13.qa_analysis qa ON (qa.id = qr.qa_analysis_id)
		JOIN casp13.predictions pr ON (pr.id = re.predictions_id)
		%s
		JOIN casp13.groups gr ON (gr.id = pr.groups_id)
		WHERE 1=1 %s ORDER BY %s %s limit 2500 ", $self->{_table}, $sub_join, $sub_query, $field, $order);
		##JOIN casp13.submitted_sequences ss ON  (ss.id = tr.submitted_sequences_id)
		##JOIN casp13.targets tr ON  (tr.name = pr.target)
###print    
#    print "FROM QAResultsManager ::: $query\n";
    
    my $sth = $self->{_database}->query($query);  

    if(defined($sth) && ($sth->rows() > 0)) {
        my $index = 1;
        while(my($id, $results_id, $predictions_id, $target, $pfrmat, $code, $model, $parent, $domain,
		 $gdt_ts_4, $rmsd_5, $alignment_4, $n2_4,
		 $mqas_score, $distances, $mean,  $deviation, $pearson, $fisher_zprime, $res_count, $differences
		 ) = $sth->fetchrow_array()) {
	    push(@results, {
		INDEX => $index,
		ID => $id,
		RESULTS_ID => $results_id,
		PREDICTIONS_ID => $predictions_id,
		MODEL_NAME => $r_m->build_model_name($target, $pfrmat, $code, $model, $parent, $domain),
		FULL_TARGET => $r_m->build_full_target_name($target, 0),
		CODE => sprintf('%03d', $code),
		gdt_ts_4 => ((defined($not_rount) && $not_rount eq 1)?$gdt_ts_4:sprintf("%.2f", $gdt_ts_4)),		
		rmsd_5 => ((defined($not_rount) && $not_rount eq 1)?$rmsd_5:sprintf("%.2f", $rmsd_5)),		
		results_distances => $alignment_4,
		N2_4 => $n2_4,
		mqas_score => $mqas_score,
		distances => $distances,
		mean => ((defined($not_rount) && $not_rount eq 1)? $mean : sprintf("%.2f", $mean)),
		deviation => ((defined($not_rount) && $not_rount eq 1)?$deviation:sprintf("%.2f", $deviation)),
		pearson => ((defined($not_rount) && $not_rount eq 1)?$pearson:sprintf("%.3f", $pearson)),
		fisher_zprime => $fisher_zprime,
		res_count => $res_count, 
		differences => $differences
		}
	    );	
	    $index++;
        }
    }
    return @results;
}

#my $rt = new ResultsTargetRefinementManager(); 

1;
