package RRResultsManager;
use strict;
use warnings;

use DBI;
use Digest::MD5 qw(md5 md5_hex md5_base64);
use lib qw(Core);
use Database;
use Configuration;
use LocalConfiguration;
use BO;
our @ISA = qw(BO);

my $casp_schema = "\L$LOCAL_CONFIG->{CASP_VERSION}";

sub new {
    my ($class) = @_;
    my $self = $class->SUPER::new("$casp_schema.rr_results");
    bless $self, $class;
    return $self;
}	

sub is_table_column{
my ($self, $column_name) = @_;
my $result = 0;
if(	$column_name eq 'id' ||
	$column_name eq 'group_id' ||
        $column_name eq 'target_id' ||
        $column_name eq 'domain_id' ||
        $column_name eq 'domain_index' ||
        $column_name eq 'model_index' ||
	$column_name eq 'range' ||
	$column_name eq 'checksize' ||
	$column_name eq 'acc' ||
        $column_name eq 'zacc' ||
        $column_name eq 'zacc_wo' ||
	$column_name eq 'cov' ||
        $column_name eq 'zcov' ||
        $column_name eq 'zcov_wo' ||
	$column_name eq 'imp' ||
        $column_name eq 'zimp' ||
        $column_name eq 'zimp_wo' ||
        $column_name eq 'xd' ||
        $column_name eq 'zxd' ||
        $column_name eq 'zxd_wo'){
		$result = 1;
	}
return $result;
}

sub get_new_model{
    my $self = @_;
    my %model = (
        id => '',
        group_id => undef,
#       predictions_id => '',
        target_id => undef,
        domain_id => undef,
        model_index => undef,
        range => undef,
        checksize => undef,
        acc => '',
        zacc => '',
        zacc_wo => '',
        cov => '',
        zcov => '',
        zcov_wo => '',
        imp => '',
        zimp => '',
        zimp_wo => '',
        xd => '',
        zxd => '',
        zxd_wo => '',

        GROUP_CODE => undef,
        TARGET_NAME => undef,
        domain_index => 0, # value '0' corresponds to the whole target
	number_targ_conts => undef # number of contacts in target
    );
return \%model;
}

sub exist {
    my ($self, $id) = @_;
    my $result = 0;

    my $query = sprintf("SELECT COUNT(id) FROM $casp_schema.rr_results WHERE (id = %d)", $id);
    my $sth = $self->{_database}->query($query);

    if(defined($sth) && ($sth->rows() > 0)) {
        my ($count) = $sth->fetchrow_array();
        $result = ($count == 1) ? 1 : 0;
    }
    return $result;
}

sub exist_by_parameters{
    my ($self, $refmodel) = @_;
    $refmodel = $self->complete_model_parameters($refmodel);
    my %model = %{$refmodel};
    my $result = 0;

    my $query= sprintf(" SELECT re.id FROM $casp_schema.rr_results re join $casp_schema.targets t on re.target_id=t.id join $casp_schema.groups g on re.group_id=g.id WHERE (t.name=\'%s\' AND re.domain_index=%d AND re.range=\'%s\' AND re.checksize=%f AND re.model_index=%d AND g.code=%d)",$model{TARGET_NAME},$model{domain_index},$model{range}, $model{checksize}, $model{model_index},$model{GROUP_CODE});
    my $sth = $self->{_database}->query($query);
    my $refRows = $sth->fetchall_arrayref();
    my @rows = @{$refRows};
    if(scalar(@rows) == 0){
        return 0;
    }elsif(scalar(@rows) == 1){
        my @row1 = @{$rows[0]};
        return $row1[0];
    }else{
        my $message = sprintf("target: %s, domain_index: %d, group_code: %d, model: %d, range: %s, checksize: %s", $model{TARGET_NAME},$model{domain_index},$model{GROUP_CODE},$model{model_index},$model{range},$model{checksize});
        die("$message\n") ;
    }
}

sub add{
    my ($self, $refmodel) = @_;
    $refmodel = $self->complete_model_parameters($refmodel);
    my %model = %{$refmodel};

    my $result = 0;

    my $column_names = '';
    my $column_values = '';
    my $values_count = 0;

    while ( my ($key, $value) = each(%model) ) {
        if($key eq 'id' || !defined($value) || $value eq '') {
                #print "NE---$key---------->$value<----------\n";
        }else{
                if($self->is_table_column($key)==1) {
                        $column_names .= sprintf(" %s%s ",($values_count == 0)?'':',', $key);
                        $column_values .= sprintf(" %s\'%s\' ",($values_count == 0)?'':',', $value);;
                        $values_count++;
                }
        }
    }

    my $query = sprintf("INSERT INTO $casp_schema.rr_results ( %s ) VALUES ( %s )", $column_names, $column_values);

        my $tmp = $query;

    my $sth = $self->{_database}->query($query);
    if(defined($sth)) {
        my $query = sprintf("SELECT MAX(id) FROM $casp_schema.rr_results");
        my $sth = $self->{_database}->query($query);
        # add logger
        ($result) = $sth->fetchrow_array();
    }
       # print "---------------------ADD: $result";
        if ($result == 0) {
        print "\n" . $tmp . "\n";
        }

    return $result;
}

sub delete {
    my ($self, $id) = @_;
    my $result = 0;
    return $result if(! $self->exist($id));
    my $query = sprintf("DELETE FROM $casp_schema.rr_results WHERE (id = %d)", $id);
    my $sth = $self->{_database}->query($query);
    if(defined($sth)) {
        $result = defined($sth) ? 1 : 0;
    }
    return $result;
}

sub delete_results_for_all_domains_for_target {
    my ($self,$target) = @_;
    my $where;
    if($target =~ m/^[TR][0-9]{4}$/ || $target =~ m/^[TR][Rracspx][0-9]{3}$/ ){
	$where = sprintf(" target_id in (select id from $casp_schema.targets t where t.name=\'%s\' ) and domain_index<>0 ", $target);
    }else{
	return;
    }
    my $query = sprintf("DELETE FROM $casp_schema.rr_results WHERE %s ", $where );
    #print $query."\n";
    #return;
    my $result = 0;
    my $sth = $self->{_database}->query($query);
    if(defined($sth)) {
        $result = defined($sth) ? 1 : 0;
    }
    return $result;
}


sub complete_model_parameters{
    my ($self, $refmodel) = @_;
    my %model = %{$refmodel};
    if(defined($model{GROUP_CODE}) && !defined($model{group_id})){
        $model{group_id} = $self->fetch_group_id_by_group_code($model{GROUP_CODE});
    }
    if(!defined($model{GROUP_CODE}) && defined($model{group_id})){
        $model{GROUP_CODE} = $self->fetch_group_code_by_group_id($model{group_id});
    }
    if(defined($model{TARGET_NAME}) && !defined($model{target_id})){
        $model{target_id}=$self->fetch_target_id_by_target_name($model{TARGET_NAME});
    }
    if(!defined($model{TARGET_NAME}) && defined($model{target_id})){
        $model{TARGET_NAME} = $self->fetch_target_name_by_target_id($model{target_id});
    }
    if(defined($model{TARGET_NAME}) && 0!=$model{domain_index} && !defined($model{domain_id})){
        $model{domain_id}=$self->fetch_domain_id_by_target_name_and_index($model{TARGET_NAME},$model{domain_index});
    }
    return \%model;
}

sub fetch_target_name_by_target_id{
    my ($self,$target_id) = @_;
    my $query = sprintf("SELECT name FROM $casp_schema.targets WHERE (id=%d)", $target_id);
    my $sth = $self->{_database}->query($query);
    my $refRows = $sth->fetchall_arrayref();
    my @rows = @{$refRows};
    if(scalar(@rows)!= 1){
        die"Query:$query\n$casp_schema.targets contains not unique value of target id\n";
    }
    my @row1 = @{$rows[0]};
    return $row1[0];
}

sub fetch_target_id_by_target_name{
    my ($self,$target_name) = @_;
    my $query = sprintf("SELECT id FROM $casp_schema.targets WHERE (name=\'%s\')", $target_name);
    my $sth = $self->{_database}->query($query);
    my $refRows = $sth->fetchall_arrayref();
    my @rows = @{$refRows};
    if(scalar(@rows)!= 1){
        die"Query:$query\n$casp_schema.targets contains not unique value of 'name' field\n";
    }
    my @row1 = @{$rows[0]};
    return $row1[0];
}


sub fetch_group_code_by_group_id{
    my ($self,$group_id) = @_;
    my $query = sprintf("SELECT code FROM $casp_schema.groups WHERE (id=%d)", $group_id);
    my $sth = $self->{_database}->query($query);
    my $refRows = $sth->fetchall_arrayref();
    my @rows = @{$refRows};
    if(scalar(@rows)!= 1){
        die"Query:$query\n$casp_schema.groups contains not unique value of 'code' field\n";
    }
    my @row1 = @{$rows[0]};
    return $row1[0];
}


sub fetch_group_id_by_group_code{
    my ($self,$group_code) = @_;
    my $query = sprintf("SELECT id FROM $casp_schema.groups WHERE (code=%d)", $group_code);
    my $sth = $self->{_database}->query($query);
    my $refRows = $sth->fetchall_arrayref();
    my @rows = @{$refRows};
    if(scalar(@rows)!= 1){
        die"Query:$query\n$casp_schema.groups contains not unique value of 'code' field\n";
    }
    my @row1 = @{$rows[0]};
    return $row1[0];
}

sub fetch_domain_id_by_target_name_and_index{
    my ($self, $target_name, $index) = @_;
    my $query = sprintf("SELECT d.id FROM $casp_schema.domains d join $casp_schema.targets t on t.id=d.targets_id WHERE (t.name='%s' AND d.index=%d)", $target_name, $index);
    my $sth = $self->{_database}->query($query);
    my $refRows = $sth->fetchall_arrayref();
    my @rows = @{$refRows};
    if(scalar(@rows)!= 1){
        die"Query:$query\n$casp_schema.domains contains not unique value of 'id' field\n";
    }
    my @row1 = @{$rows[0]};
    return $row1[0];
}


sub fetch_domain_index_by_domain_id{
    my ($self, $domain_id) = @_;
    my $query = sprintf("SELECT index FROM $casp_schema.domains  WHERE (id=%d )", $domain_id);
    my $sth = $self->{_database}->query($query);
    my $refRows = $sth->fetchall_arrayref();
    my @rows = @{$refRows};
    if(scalar(@rows)!= 1){
        die"Query:$query\n$casp_schema.domains contains not unique value of 'id' field\n";
    }
    my @row1 = @{$rows[0]};
    return $row1[0];
}

sub fetch_domain_name_by_domain_id{
    my ($self, $domain_id) = @_;
    my $query = sprintf("SELECT t.name, d.index FROM $casp_schema.domains d join $casp_schema.targets t on t.id=d.targets_id WHERE (d.id=%d )", $domain_id);
    my $sth = $self->{_database}->query($query);
    my $refRows = $sth->fetchall_arrayref();
    my @rows = @{$refRows};
    if(scalar(@rows)!= 1){
        die"Query:$query\n$casp_schema.domains contains not unique combination of values of 'target_name' and 'index' fields\n";
    }
    my @row1 = @{$rows[0]};
    return $row1[0]."-D".$row1[1];
}



sub get_targets{
    my ($self, $param) = @_;
    my $query = sprintf("select distinct t.id, t.name from $casp_schema.rr_results r join $casp_schema.targets t on r.target_id = t.id join $casp_schema.groups g on r.group_id = g.id where t.cancellation_status in (0,2) ");
    if (defined($param->{checksize}) && $param->{checksize} ne ''){
	if($query =~ m/where/){
	  $query .= " and ";
	} else {
	  $query .= " where ";
	}
	my $tmp = $param->{checksize}; $tmp =~ s/[a-zA-Z]*//;
	$query .= sprintf(" r.checksize = %.1f", $tmp );
    }

    if(defined($param->{range}) && $param->{range} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" r.range = '%s' ", $param->{range} );
    }

    if(defined($param->{domain_index}) && $param->{domain_index} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" r.domain_index = %d", $param->{domain_index} );
    }

    if(defined($param->{group_name}) && $param->{group_name} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.name = '%s' ", $param->{group_name} );
    }elsif(defined($param->{group_code}) && $param->{group_code} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.code = %d ", $param->{group_code} );
    }elsif(defined($param->{group_id}) && $param->{group_id} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.id = %d ", $param->{group_id} );
    }

    if(defined($param->{model_index}) && $param->{model_index} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" r.model_index = %d", $param->{model_index} );
    }


    $query .= " order by t.name";
    my $sth = $self->{_database}->query($query);
    
    my @results = ();

    if(defined($sth) && ($sth->rows() > 0)){
	while(my ($target_id,$target_name) = $sth->fetchrow_array()){
	   push(@results,{
		ID=>$target_id,
		NAME=>$target_name
	   });
	}
    }
    return @results;
}


sub get_domain_indexes{
    my ($self, $param) = @_;
    my $query = sprintf("select distinct r.domain_index from $casp_schema.rr_results r join $casp_schema.targets t on r.target_id = t.id join $casp_schema.groups g on r.group_id = g.id ");
    if (defined($param->{checksize}) && $param->{checksize} ne '' ){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        my $tmp = $param->{checksize}; $tmp =~ s/[a-zA-Z]*//;
        $query .= sprintf(" r.checksize = %.1f", $tmp );
    }


    if(defined($param->{range}) && $param->{range} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" r.range = '%s' ", $param->{range} );
    }

    if(defined($param->{target}) && $param->{target} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" t.name = '%s'", $param->{target} );
    }elsif(defined($param->{target_id}) && $param->{target_id} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" t.id = %d", $param->{target_id} );
    }else{}

    if(defined($param->{group_name}) && $param->{group_name} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.name = '%s' ", $param->{group_name} );
    }elsif(defined($param->{group_code}) && $param->{group_code} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.code = %d ", $param->{group_code} );
    }elsif(defined($param->{group_id}) && $param->{group_id} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.id = %d ", $param->{group_id} );
    }

    if(defined($param->{model_index}) && $param->{model_index} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" r.model_index = %d", $param->{model_index} );
    }


    $query .= " order by r.domain_index";
    my $sth = $self->{_database}->query($query);

    my @results = ();

    if(defined($sth) && ($sth->rows() > 0)){
        while(my ($domain_index) = $sth->fetchrow_array()){
           push(@results,{
                INDEX=>$domain_index
           });
        }
    }
    return @results;
}


sub get_groups{
    my ($self, $param) = @_;
    my $query = sprintf("select distinct g.id, g.name, g.code from $casp_schema.rr_results r join $casp_schema.targets t on r.target_id = t.id join $casp_schema.groups g on r.group_id = g.id ");
    if (defined($param->{checksize}) && $param->{checksize} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        my $tmp = $param->{checksize}; $tmp =~ s/[a-zA-Z]*//;
        $query .= sprintf(" r.checksize = %.1f", $tmp );
    }

    if(defined($param->{range}) && $param->{range} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" r.range = '%s' ", $param->{range} );
    }

    if(defined($param->{target}) && $param->{target} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" t.name = '%s'", $param->{target} );
    }elsif(defined($param->{target_id}) && $param->{target_id} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" t.id = %d", $param->{target_id} );
    }else{}

    if(defined($param->{domain_index}) && $param->{domain_index} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" r.domain_index = %d", $param->{domain_index} );
    }

    if(defined($param->{model_index}) && $param->{model_index} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" r.model_index = %d", $param->{model_index} );
    }

    $query .= " order by g.code";
    my $sth = $self->{_database}->query($query);

    my @results = ();

    if(defined($sth) && ($sth->rows() > 0)){
        while(my ($group_id, $group_name, $group_code) = $sth->fetchrow_array()){
           if ($group_code < 10){
                $group_code = "00".$group_code;
           }elsif($group_code < 100){
                $group_code = "0".$group_code;
           }

           push(@results,{
		ID=>$group_id,
                NAME=>$group_name,
		CODE=>$group_code
           });
        }
    }
    return @results;
}


sub get_range{
    my ($self, $param) = @_;
    my $query = sprintf("select distinct r.range from $casp_schema.rr_results r  join $casp_schema.targets t on r.target_id = t.id join $casp_schema.groups g on r.group_id = g.id ");

    if (defined($param->{checksize}) && $param->{checksize} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        my $tmp = $param->{checksize}; $tmp =~ s/[a-zA-Z]*//;
        $query .= sprintf(" r.checksize = %.1f", $tmp );
    }

    if(defined($param->{group_name}) && $param->{group_name} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.name = '%s' ", $param->{group_name} );
    }elsif(defined($param->{group_code}) && $param->{group_code} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.code = %d ", $param->{group_code} );
    }elsif(defined($param->{group_id}) && $param->{group_id} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.id = %d ", $param->{group_id} );
    }

    if(defined($param->{target}) && $param->{target} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" t.name = '%s'", $param->{target} );
    }elsif(defined($param->{target_id}) && $param->{target_id} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" t.id = %d", $param->{target_id} );
    }else{}

    if(defined($param->{domain_index}) && $param->{domain_index} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" r.domain_index = %d", $param->{domain_index} );
    }

    if(defined($param->{model_index}) && $param->{model_index} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" r.model_index = %d", $param->{model_index} );
    }

    $query .= " order by r.range";
    my $sth = $self->{_database}->query($query);

    my @results = ();

    if(defined($sth) && ($sth->rows() > 0)){
        while(my ($range) = $sth->fetchrow_array()){
           push(@results,{
                NAME=>$range
           });
        }
    }
    return @results;
}

sub get_checksize{
    my ($self, $param) = @_;
    my $query = sprintf("select distinct r.checksize from $casp_schema.rr_results r join $casp_schema.targets t on r.target_id = t.id join $casp_schema.groups g on r.group_id = g.id ");

    if(defined($param->{group_name}) && $param->{group_name} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.name = '%s' ", $param->{group_name} );
    }elsif(defined($param->{group_code}) && $param->{group_code} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.code = %d ", $param->{group_code} );
    }elsif(defined($param->{group_id}) && $param->{group_id} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.id = %d ", $param->{group_id} );
    }

    if(defined($param->{target}) && $param->{target} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" t.name = '%s'", $param->{target} );
    }elsif(defined($param->{target_id}) && $param->{target_id} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" t.id = %d", $param->{target_id} );
    }else{}

    if(defined($param->{domain_index}) && $param->{domain_index} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" r.domain_index = %d", $param->{domain_index} );
    }

    if(defined($param->{model_index}) && $param->{model_index} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" r.model_index = %d", $param->{model_index} );
    }

    $query .= " order by r.checksize";
    my $sth = $self->{_database}->query($query);

    my @results = ();

    if(defined($sth) && ($sth->rows() > 0)){
        while(my ($checksize) = $sth->fetchrow_array()){
	  push(@results,{
                NAME=>$checksize
           });
        }
    }
    return @results;
}

sub get_model_indexes{
    my ($self, $param) = @_;
    my $query = sprintf("select distinct r.model_index from $casp_schema.rr_results r join $casp_schema.targets t on r.target_id = t.id join $casp_schema.groups g on r.group_id = g.id ");

    if(defined($param->{group_name}) && $param->{group_name} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.name = '%s' ", $param->{group_name} );
    }elsif(defined($param->{group_code}) && $param->{group_code} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.code = %d ", $param->{group_code} );
    }elsif(defined($param->{group_id}) && $param->{group_id} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.id = %d ", $param->{group_id} );
    }

    if(defined($param->{target}) && $param->{target} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" t.name = '%s'", $param->{target} );
    }elsif(defined($param->{target_id}) && $param->{target_id} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" t.id = %d", $param->{target_id} );
    }else{}

    if(defined($param->{domain_index}) && $param->{domain_index} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" r.domain_index = %d", $param->{domain_index} );
    }
    if(defined($param->{checksize}) && $param->{checksize} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" r.checksize = %.1f", $param->{checksize} );
    }

    $query .= " order by r.model_index";
    my $sth = $self->{_database}->query($query);

    my @results = ();

    if(defined($sth) && ($sth->rows() > 0)){
        while(my ($model_index) = $sth->fetchrow_array()){
           push(@results,{
                NAME=>$model_index
           });
        }
    }
    return @results;
}



sub get_results{
    my ($self, $param) = @_;
    my $field = $param->{field};
    my $order = $param->{order};
    $field = (!defined($field) || ($field eq '')) ? 'r.acc' : $field;
    $order = (!defined($order) || ($order eq '')) ? 'DESC' : $order;

    my $query = sprintf("select t.id, t.name, r.domain_index, g.id, g.name, g.code, g.type, r.range, r.checksize, r.model_index, r.acc, r.zacc, r.zacc_wo, r.cov, r.zcov, r.zcov_wo, r.imp, r.zimp, r.zimp_wo, r.xd, r.zxd, r.zxd_wo from $casp_schema.rr_results r join $casp_schema.targets t on r.target_id = t.id join $casp_schema.groups g on r.group_id = g.id ");

    if (defined($param->{checksize}) && $param->{checksize} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        my $tmp = $param->{checksize};  $tmp =~ s/[a-zA-Z]*//;
        $query .= sprintf(" r.checksize = %.1f", $tmp );
    }else{
	#return 0;
    }

    if(defined($param->{group_name}) && $param->{group_name} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.name = '%s' ", $param->{group_name} );
    }elsif(defined($param->{group_code}) && $param->{group_code} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.code = %d ", $param->{group_code} );
    }elsif(defined($param->{group_id}) && $param->{group_id} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" g.id = %d ", $param->{group_id} );
    }else{
	#return 0;
    }

    if(defined($param->{range}) && $param->{range} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" r.range = '%s' ", $param->{range} );
    }

    if(defined($param->{target}) && $param->{target} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" t.name = '%s'", $param->{target} );
    }elsif(defined($param->{target_id}) && $param->{target_id} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" t.id = %d", $param->{target_id} );
    }else{
	#return 0;
    }

    if(defined($param->{domain_index}) && $param->{domain_index} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" r.domain_index = %d", $param->{domain_index} );
    }
    
    if(defined($param->{model_index}) && $param->{model_index} ne ''){
        if($query =~ m/where/){
          $query .= " and ";
        } else {
          $query .= " where ";
        }
        $query .= sprintf(" r.model_index = %d", $param->{model_index} );
    }

    $query .= sprintf (" ORDER BY %s %s ", $field, $order);

    my $sth = $self->{_database}->query($query);

    my @results = ();

    if(defined($sth) && ($sth->rows() > 0)){
	my $index = 1;
        while(my ($target_id, $target, $domain_index, $group_id, $group_name, $group_code, $gr_type, $range, $checksize, $model_index, $acc, $zacc, $zacc_wo, $cov, $zcov, $zcov_wo, $imp, $zimp, $zimp_wo, $xd, $zxd, $zxd_wo) = $sth->fetchrow_array()){
           push(@results,{
		INDEX=>$index,
		ACC=>sprintf("%.2f",$acc),
		ZACC=>sprintf("%.2f",$zacc),
		ZACC_WO=>sprintf("%.2f",$zacc_wo),
		COV=>sprintf("%.2f",$cov),
		ZCOV=>sprintf("%.2f",$zcov),
		ZCOV_WO=>sprintf("%.2f",$zcov_wo),
		IMP=>sprintf("%.2f",$imp),
		ZIMP=>sprintf("%.2f",$zimp),
		ZIMP_WO=>sprintf("%.2f",$zimp_wo),
		XD=>sprintf("%.2f",$xd),
		ZXD=>sprintf("%.2f",$zxd),
		ZXD_WO=>sprintf("%.2f",$zxd_wo),
		MODEL_INDEX=>$model_index,
		TARGET_ID=>$target_id,
		TARGET=>$target,
		DOMAIN_INDEX=>$domain_index,
		GROUP_ID=>$group_id,
		GROUP_NAME=>$group_name,
		GROUP_CODE=>sprintf("%03d",$group_code),
		GROUP_TYPE=>$gr_type,
                RANGE=>$range,
		CHECKSIZE=>$checksize
           });
	   $index++;
        }
    }
    return @results;
}


sub calc_zscore_for_target_domain{
    my ($self,$targ_name, $dom_index) = @_;
    my $targ_id = $self->fetch_target_id_by_target_name($targ_name);
    my $query = "SELECT $casp_schema.update_rr_temp_stat_for_target_domain($targ_id,$dom_index)";
    my $sth = $self->{_database}->query($query);
    
    $query = "SELECT $casp_schema.update_rr_results_z_score_for_target_domain($targ_id,$dom_index)";
    $sth = $self->{_database}->query($query);
}


sub get_summary_results {
    my ($self, $param) = @_;
    my $field = $param->{field};
    my $order = $param->{order};
    my $chksize = $param->{chksize};
    my $conts_range = $param->{conts_range};
    $field = (!defined($field) || ($field eq '')) ? 'sumZsum' : $field;
    $order = (!defined($order) || ($order eq '')) ? 'DESC' : $order;
    $chksize = (!defined($chksize) || ($chksize eq '')) ? '0.2' : $chksize;
    $conts_range = (!defined($conts_range) || ($conts_range eq '')) ? 'L' : $conts_range;
    my $subque = '';
    if ($param->{fm} ne 'on' ){
	$subque .=  ' and dci<>3 ';
    }
    if ($param->{tbmfm} ne 'on' ){
        $subque .=  ' and dci<>4 ';
    }
    if ($param->{tbm_hard} ne 'on' ){
        $subque .=  ' and dci<>1 ';
    }
    my $query = sprintf("select grp_name, avg(grp_code) as grp_code, avg(grp_type) as grp_type,count(*) as count, avg(acc) as avg_acc, avg(zacc_wo) as avg_zacc, avg(xd) as avg_xd, avg(zxd_wo) as avg_zxd,  avg(zxd_wo)+avg(zacc_wo) as sumZ, sum(zxd_wo)+sum(zacc_wo) as sumZsum from casp13.rr_groups_analysis where chksize=%s and conts_range='%s' and dci in (1,3,4) %s group by grp_name order by %s %s ", $chksize, $conts_range, $subque, $field, $order);
    my @results = ();
    my $sth = $self->{_database}->query($query);
    if(defined($sth) && ($sth->rows() > 0)){
        my $index = 1;
	while(my ($group_name, $group_code, $group_type, $count, $avg_acc, $avg_zacc, $avg_xd, $avg_zxd, $sumz, $sumZsum) = $sth->fetchrow_array()){
	   my $result = {
		INDEX => $index,
		GROUP_NAME => $group_name,
		GROUP_CODE => sprintf("%03d", int($group_code)),
		GROUP_TYPE => sprintf("%d", int($group_type)),
		COUNT => $count, # number of entries taking into account while averaging results
		AVG_ACC => sprintf("%.2f", $avg_acc),
		AVG_ZACC => sprintf("%.4f", $avg_zacc),
		AVG_XD => sprintf("%.2f", $avg_xd),
		AVG_ZXD => sprintf("%.4f", $avg_zxd),
		SUMZ => sprintf("%.4f", $sumz),
		SUM_ZACC => sprintf("%.4f", ($avg_zacc*$count)),
		SUM_ZXD => sprintf("%.4f", ($avg_zxd*$count)),
		SUM_SUM_Z =>sprintf("%.4f",$sumZsum)
	   };
	   push (@results, $result); 
	   $index++;
	}
    }
    return @results;
}

1;
