package GroupsManager;

use strict;
use warnings;

use DBI;
use Digest::MD5 qw(md5 md5_hex md5_base64);
use Data::Dumper;

use lib qw(Core);

use Database;
use MembersManager;

use Configuration;

my $groups_manager = undef;


### ATTENTION! email_domain has @ sign in order to distinct values from internet domain
###            it's only for avoiding confusion about email address of http server and
###            its http address but you have to remember that it is expected for email
###            domain to contain @ sign!

### GROUP TYPES:  0 - human; 1 - http server; 2 - email server; 3 - extended; 

### METHODS (last update 05/24/2010 M. Wojciechowski):
#   get_id (gets id of the group)
#   set_id (sets id of the group)
#   exist (returns 1 if the record with given id exists)
#   is_blocked (returns 1 if the group was blocked by the organizers)
#   get_id_by_name (returns id of the group by its name)
#   get_server_group_id_by_request_email (returns id of the group by its request email)
#   get_server_group_id_by_response_email (returns id of the group by its request email)
#   get_http_server_group_id_by_name (returns id of the group by its name if it is contained
#				      in the $subject parameter)
#   get_id_by_code (returns id of the group by its code)
#   get_code_by_name (returns code of the group by its name)
#   get_id_by_pin (returns id of the group by its pin)
#   generate_pin (generates pin for group on random)
#   get_curator_email_by_id (gets email of person who created the group)
#   is_server (returns 1 if group is email or http server)
#   is_http_server (returns 1 if group is http server)
#   is_extended (returns 1 if group is extended)
#   groupname_exist (returns 1 if group with given name exists)
#   info (returns data about the group)
#   name (returns name - uses info method)
#   code (returns code - uses info method)
#   info_server (returns data about server)
#   generate_group_code (generates code for group on random)
#   add (adds new record into the groups table)
#   add_server (adds new record into the servers table)
#   add_observer (adds new record into the observers table)
#   update (updates group data)
#   rename (changes name of the group)
#   do_block (blocks the group)
#   do_unblock (unblocks the group)
#   edit_server (updates server data)
#   edit_http_server (updates http server data)
#   edit_http_server_domain (updates http server domain)
#   distribution_servers (lists all servers for target distribution)
#   is_qa_server (returns 1 if server is used for QUALITY ASSESSMENT)
#   is_pure_qa_server (returns 1 if server is used only for QUALITY ASSESSMENT)
#   all_groups (list all registered groups (with info))
#   servers (list all registered servers (with info))
#   delete (removes group with all registered servers)
#   exists_server_connected_with_email(checks if the email is somehow registered in the system)
######################################################

sub new {
    my ($class) = @_;
    
    return $groups_manager if(defined($groups_manager));
    
    my $self = {
        _id => undef,
        _database => Database->new($CONFIG->{HOSTNAME}, $CONFIG->{PORT}, $CONFIG->{DATABASE}, $CONFIG->{USERNAME}, $CONFIG->{PASSWORD})
    };
    
    $groups_manager = bless $self, $class;
    return $groups_manager;
}

sub get_id {
    my ($self) = @_;
    
    return $self->{_id};
}

sub set_id {
    my ($self, $id) = @_;
    
    $self->{_id} = (defined($id) && (scalar($id) > 0)) ? scalar($id) : undef;
    
    return;
}

sub exist {
    my ($self, $id) = @_;
    
    my $result = 0;
    
    my $query = sprintf("SELECT COUNT(id) FROM casp13.groups 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;
    }
    #print $query;
    return $result;
}

sub is_blocked {
    my ($self, $id) = @_;
    
    my $result = 1;
    
    my $query = sprintf("SELECT is_blocked FROM casp13.groups WHERE (id = %d)", $id);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
        ($result) = $sth->fetchrow_array();
    }
    
    return ($result == 1) ? 1 : 0;
}

sub get_id_by_name {
    my ($self, $name) = @_;
    
    my $result = 0;
    
    my $query = sprintf("SELECT id FROM casp13.groups WHERE (UPPER(name) = '%s')", uc($name));
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
        ($result) = $sth->fetchrow_array();
    }
    
    return $result;
}

sub get_server_group_id_by_request_email {
    my ($self, $email) = @_;
    
    my $result = 0;
    
    my $query = sprintf("SELECT group_id FROM casp13.servers WHERE (UPPER(request_email) = '%s')", uc($email));
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
        ($result) = $sth->fetchrow_array();
    }
    
    return $result;
}

# get all group ids by either request or response e-mail
sub get_all_server_group_ids_by_email{
    my ($self, $email) = @_;

    my @result = ();

    my $query = sprintf("SELECT group_id FROM casp13.servers WHERE (UPPER(request_email) = '%s') OR (UPPER(response_email) = '%s')", uc($email), uc($email));
    my $sth = $self->{_database}->query($query);

    if(defined($sth) && ($sth->rows() > 0)) {
	while(my ($id) = $sth->fetchrow_array()){
		push(@result,$id);
	}
    }

    return @result;

}


sub get_http_server_group_id_by_name {
    my ($self, $subject) = @_;
    
    my $result = 0;
    my $query = sprintf("SELECT id FROM casp13.groups WHERE type = 1 AND '%s' LIKE '%' || UPPER(name) || '%'", uc($subject));
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
        ($result) = $sth->fetchrow_array();
    }
    
    return $result;
}

sub get_server_group_id_by_response_email {
    my ($self, $email) = @_;
    
    my $result = 0;
    
    my $query = sprintf("SELECT group_id FROM casp13.servers WHERE (UPPER(response_email) = '%s')", uc($email));
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
        ($result) = $sth->fetchrow_array();
    }
    
    return $result;
}

sub get_id_by_code {
    my ($self, $code) = @_;
    
    my $result = 0;
    if (defined($code) && ($code=~/^\d+$/)){
     my $query = sprintf("SELECT id FROM casp13.groups WHERE (code = %d)", $code);
     my $sth = $self->{_database}->query($query);
    
     if(defined($sth) && ($sth->rows() > 0)) {
        ($result) = $sth->fetchrow_array();
     }
    }
    return $result;
}

sub get_code_by_name {
    my ($self, $name) = @_;
    
    my $result = 0;
    
    my $query = sprintf("SELECT code FROM casp13.groups WHERE (name = '%s')", $name);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
        ($result) = $sth->fetchrow_array();
    }
    
    return $result;
}

sub get_id_by_pin {
    my ($self, $pin) = @_;
    
    my $result = 0;
    
    my $query = sprintf("SELECT id FROM casp13.groups WHERE (pin = '%s')", $pin);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
        ($result) = $sth->fetchrow_array();
    }
    
    return $result;
}

sub get_curator_email_by_id {
    my ($self, $id) = @_;
    
    my $result = 0;
    
    my $query = sprintf("SELECT contact FROM casp13.servers WHERE (group_id = %d)", $id);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
        ($result) = $sth->fetchrow_array();
    }
    
    return $result;
}

sub is_server {
    my ($self, $id) = @_;
    
    my $result = 0;
    
    my $query = sprintf("SELECT type FROM casp13.groups WHERE (id = %d)", $id);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
        ($result) = $sth->fetchrow_array();
    }
    # 3 - extended;  0 - human;  1 - http server; 2 - email server 
    return ($result == 0 || $result == 3) ? 0 : 1;
}

sub is_http_server {
    my ($self, $id) = @_;
    
    my $result = 0;
    
    my $query = sprintf("SELECT type FROM casp13.groups WHERE (id = %d)", $id);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
        ($result) = $sth->fetchrow_array();
    }
    # 3 - extended;  0 - human;  1 - http server; 2 - email server 
    return ($result == 1) ? 1 : 0;
}

sub is_extended {
    my ($self, $id) = @_;
    
    my $result = 0;
    
    my $query = sprintf("SELECT type FROM casp13.groups WHERE (id = %d)", $id);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
        ($result) = $sth->fetchrow_array();
    }
    # 3 - extended;  
    return ($result == 3) ? 1 : 0;
}

sub is_casprol {
    my ($self, $id) = @_;

    my $result = 0;

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

    if(defined($sth) && ($sth->rows() > 0)) {
        ($result) = $sth->fetchrow_array();
    }
      
    return $result;

}


sub is_capri {
    my ($self, $id) = @_;

    my $result = 0;

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

    if(defined($sth) && ($sth->rows() > 0)) {
        ($result) = $sth->fetchrow_array();
    }

    return $result;

}


sub groupname_exist {
    my ($self, $name) = @_;

    my $result = ($self->get_id_by_name($name) > 0) ? 1 : 0;
    
    return $result;
}

sub name {
    my ($self, $id) = @_;
    
    my %group_info = $self->info($id);
    
    my $result = $group_info{GROUPNAME};
    
    return $result;
}

sub code {
    my ($self, $id) = @_;
    
    my %group_info = $self->info($id);
    
    my $result = $group_info{CODE};
    
    return $result;
}

sub info {
    my ($self, $id) = @_;

    my %result = (
        GROUPNAME => '',
        CODE => '',
        TYPE => '',
        DATE => '',
        PIN => '',
        IS_BLOCKED => '',
        
        TS_OUTPUT => '',
        AL_OUTPUT => '',
        DP_OUTPUT => '',
        DR_OUTPUT => '',        
        FN_OUTPUT => '',
        RR_OUTPUT => '',
        QA_OUTPUT => '',
	TC_OUTPUT => '',
	TR_OUTPUT => '',
	TA_OUTPUT => '',
        TBM_OUTPUT => '',
        FM_OUTPUT => '',
	IS_CAPRI => '',
        ATTEND_COUNT => '',
    );
    
    return %result if(! $self->exist($id));
    
    my $query = sprintf("SELECT name, code, type, date, pin, is_blocked, ts_output, al_output, dp_output, dr_output, fn_output, rr_output, qa_output, tbm_output, fm_output, attend_count, is_capri, tc_output, tr_output, ta_output
    FROM casp13.groups WHERE (id = %d)", $id);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
        ($result{GROUPNAME}, $result{CODE}, $result{TYPE}, $result{DATE}, $result{PIN}, $result{IS_BLOCKED}, 
         $result{TS_OUTPUT}, $result{AL_OUTPUT}, $result{DP_OUTPUT}, $result{DR_OUTPUT}, $result{FN_OUTPUT},
         $result{RR_OUTPUT}, $result{QA_OUTPUT}, $result{TBM_OUTPUT}, $result{FM_OUTPUT}, $result{ATTEND_COUNT},
	 $result{IS_CAPRI},
	 $result{TC_OUTPUT},
	 $result{TR_OUTPUT},
	 $result{TA_OUTPUT}
	) = $sth->fetchrow_array();
        
        $result{DATE} = substr($result{DATE}, 0, 10);
    }
    
    return %result;
}

sub get_selected {
	my ($self, $g) = @_;
	my @selected_groups = ();
	my @groups = @{$g};
	my $groups_count = scalar(@groups);
	for(my $i = 0; $i < $groups_count; $i++) {
		my $font_color = 'black';

		if($i == 0) {$font_color = 'violet'; }
		elsif($i == 1) { $font_color = 'aqua'; }
		elsif($i == 2) { $font_color = 'grey'; }

		my %group_info = $groups_manager->info($groups[$i]);
		if (defined($group_info{CODE})&& ($group_info{CODE} ne "")){
		 push(@selected_groups, {
			GROUP => $groups[$i],
			NAME => $group_info{GROUPNAME},
			CODE => sprintf('%03d', $group_info{CODE}),
			FONT_COLOR => $font_color,
			SELECTED_INDEX => $i,
		  });
	        }
	}
	return @selected_groups;
}

sub info_server {
    my ($self, $id) = @_;
    my %result = (
        GROUPNAME => '',
        CODE => '',
        TYPE => '',
        DATE => '',
        PIN => '',
        IS_BLOCKED => '',
        
        TS_OUTPUT => '',
        AL_OUTPUT => '',
        DP_OUTPUT => '',
        DR_OUTPUT => '',        
        FN_OUTPUT => '',
        RR_OUTPUT => '',
        QA_OUTPUT => '',
        TBM_OUTPUT => '',
        FM_OUTPUT => '',
	TC_OUTPUT => '',
	TR_OUTPUT => '',
	TA_OUTPUT => '',
	IS_CAPRI => '',
        ATTEND_COUNT => '',
        
        REQUEST_URL => '',
        REQUEST_CGI => '',
        REQUEST_EMAIL => '',
        RESPONSE_EMAIL => '',
        REQUEST_METHOD => '',
        
        TARGET_NAME_KEY => '',
        SEQUENCE_KEY => '',
        TARBALL_KEY => '', # for QA predictions
	ADDFILE_KEY => '', # for assissted predictions (Tc,  )
	MULTIMER_MODE => '', # for Assemly predictions
	STOICHIOMETRY_KEY => '', # for Assembly predictions (for other it is just ignored)
        EMAIL_KEY => '',
        OTHER => '',
        CONTACT_PERSON => '',
        EMAIL => '',
        
        SEQUENCE_FORMAT => '',
        
        QA_SERVER_TYPE => '',
        META_SERVER_TYPE => '',
        METHODS_GLOBAL => '',
        METHODS_LOCAL => '',
	EMAIL_DOMAIN => '',
    );
    
    return %result if(! $self->exist($id));
    
    my $query = sprintf("SELECT g.name, g.code, g.type, g.date, g.pin, g.is_blocked, g.ts_output, g.al_output, g.dp_output, g.dr_output, g.fn_output, g.rr_output, g.qa_output, g.tbm_output, g.fm_output, g.attend_count, s.request_url, s.request_cgi, s.sequence_format, s.request_method, s.request_email, s.response_email, s.target_name_key, s.sequence_key, s.tarball_key, s.email_key, s.other_parameters, s.contact_person, s.contact, s.qa_server_type, s.meta_server_type, s.methods_global, s.methods_local, s.email_domain, g.is_capri,
	g.tc_output, g.tr_output, g.ta_output, s.addfile_key, s.multimer_mode, s.stoichiometry_key
	FROM casp13.groups g JOIN casp13.servers s ON g.id = s.group_id WHERE (g.id = %d)", $id);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
        ($result{GROUPNAME}, $result{CODE}, $result{TYPE}, $result{DATE}, $result{PIN}, $result{IS_BLOCKED}, $result{TS_OUTPUT}, $result{AL_OUTPUT}, $result{DP_OUTPUT}, $result{DR_OUTPUT}, $result{FN_OUTPUT}, $result{RR_OUTPUT}, $result{QA_OUTPUT}, $result{TBM_OUTPUT}, $result{FM_OUTPUT}, $result{ATTEND_COUNT}, $result{REQUEST_URL}, $result{REQUEST_CGI}, $result{SEQUENCE_FORMAT}, $result{REQUEST_METHOD}, $result{REQUEST_EMAIL}, $result{RESPONSE_EMAIL}, $result{TARGET_NAME_KEY}, $result{SEQUENCE_KEY}, $result{TARBALL_KEY}, $result{EMAIL_KEY}, $result{OTHER}, $result{CONTACT_PERSON}, $result{EMAIL}, $result{QA_SERVER_TYPE}, $result{META_SERVER_TYPE}, $result{METHODS_GLOBAL}, $result{METHODS_LOCAL}, $result{EMAIL_DOMAIN}, $result{IS_CAPRI}, $result{TC_OUTPUT}, $result{TR_OUTPUT}, $result{TA_OUTPUT}, $result{ADDFILE_KEY}, $result{MULTIMER_MODE}, $result{STOICHIOMETRY_KEY}) = $sth->fetchrow_array();
        
        $result{DATE} = substr($result{DATE}, 0, 10);
    }
    
    return %result;
}

sub generate_group_code {
	my ($self) = @_;
	
	my $result = 0;
	
	my $current_code = int(rand(500));
	
	my $query = sprintf("SELECT id FROM casp13.groups WHERE (code = %d) LIMIT 1", $current_code);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
		$result = $self->generate_group_code();
	} else {
		$result = $current_code;
	}
	
	return $result;
}

sub generate_pin {
	my ($self) = @_;
	
	my $result = 0;
	
	my $current_pin = sprintf("%04d-%04d-%04d", int(rand(9999)), int(rand(9999)), int(rand(9999)));
	
	my $query = sprintf("SELECT id FROM casp13.groups WHERE (pin = '%s') LIMIT 1", $current_pin);
	my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
		$result = $self->generate_pin();
	} else {
		$result = $current_pin;
	}
	
	return $result;
}

sub add {
    my ($self, $predictor_id, $name, $code, $type, $pin,
        $attend_count, $ts_output, $al_output, $dp_output, $dr_output, $fn_output, $rr_output, $qa_output, $tbm_output, $fm_output, $is_capri,
	$tc_output, $tr_output, $ta_output) = @_;

    if (! defined($is_capri) || $is_capri == 0){
	$is_capri = 0;
    } else {
	$is_capri = 1;
    }

    if (! defined($tc_output) || $tc_output == 0){
        $tc_output = 0;
    } else {
        $tc_output = 1;
    }

    if (! defined($tr_output) || $tr_output == 0){
        $tr_output = 0;
    } else {
        $tr_output = 1;
    }

    if (! defined($ta_output) || $ta_output == 0){
        $ta_output = 0;
    } else {
        $ta_output = 1;
    }

    my $result = 0;
    
    my $query = sprintf("INSERT INTO casp13.groups (name, code, type, pin,
                        attend_count, ts_output, al_output, dp_output, dr_output, fn_output, rr_output, qa_output, tbm_output, fm_output, is_capri,
			tc_output, tr_output, ta_output                        
                        ) VALUES ('%s', %d, %d, '%s', 
			'%s', %d, %d, %d, %d, %d, %d, %d, %d, %d, %d,
			%d, %d, %d
			)",
                        $name, $code, $type, $pin,
                        $attend_count, $ts_output, $al_output, $dp_output, $dr_output, $fn_output, $rr_output, $qa_output, $tbm_output, $fm_output,
			$is_capri,
			$tc_output, $tr_output, $ta_output
                        );
    
    my $sth = $self->{_database}->query($query);
    
    my $group_id = 0;

    if(defined($sth)) {
        my $query = sprintf("SELECT MAX(id) FROM casp13.groups");
        my $sth = $self->{_database}->query($query);
        # add logger
        ($group_id) = $sth->fetchrow_array();
    }
    
    if($group_id > 0) {
        my $query = sprintf("INSERT INTO casp13.groups_predictors_relations (predictors_id, groups_id, roles_id) VALUES (%d, %d, %d)", $predictor_id, $group_id, 1);
        my $sth = $self->{_database}->query($query);
        
        if(defined($sth)) {
            my $query = sprintf("SELECT MAX(id) FROM casp13.groups_predictors_relations");
            my $sth = $self->{_database}->query($query);
            
            # add logger
            ($result) = $sth->fetchrow_array();
        }
    }
    return $result;
}

sub add_server {
    my ($self, $predictor_id, $name, $code, $type, $pin,
        $attend_count, $ts_output, $al_output, $dp_output, $dr_output, $fn_output, $rr_output, $qa_output, $tbm_output, $fm_output,
        $request_url, $request_email, $email, $contact_person, $target_name_key, $sequence_key, $email_key, $other_parameters,
        $tarball_key, $qa_server_type, $meta_server_type, $methods_global, $methods_local, $email_domain, $request_cgi, $request_method, $sequence_format, 
	$is_capri,
	$tc_output, $tr_output, $ta_output, $addfile_key, $multimer_mode, $stoichiometry_key
        ) = @_;
    

	if ($email_domain ne '') {
		my $index_of_at = index($email_domain, "\@");
		if ($index_of_at < 0) {
			$email_domain = "\@" . $email_domain;
		}
	}

	if (! defined($is_capri) || $is_capri == 0){
        	$is_capri = 0;
	} else {
	        $is_capri = 1;
	}

        if (! defined($tc_output) || $tc_output == 0){
                $tc_output = 0;
        } else {
                $tc_output = 1;
        }

        if (! defined($tr_output) || $tr_output == 0){
                $tr_output = 0;
        } else { 
                $tr_output = 1;
        }

        if (! defined($ta_output) || $ta_output == 0){
                $ta_output = 0;
        } else { 
                $ta_output = 1;
        }

    my $result = $self->add($predictor_id, $name, $code, $type, $pin,
       $attend_count, $ts_output, $al_output, $dp_output, $dr_output, $fn_output, $rr_output, $qa_output, $tbm_output, $fm_output, $is_capri, $tc_output, $tr_output, $ta_output);
    
    my $group_id = 0;
    if($result > 0) {
        my $query = sprintf("SELECT MAX(id) FROM casp13.groups");
        my $sth = $self->{_database}->query($query);        
        # add logger
        ($group_id) = $sth->fetchrow_array();
    }
    
    if($group_id > 0) {
        my $query = sprintf("INSERT INTO casp13.servers (group_id, request_url, request_cgi, request_email, contact, contact_person, target_name_key, sequence_key, email_key, other_parameters,
        tarball_key, qa_server_type, meta_server_type, methods_global, methods_local, email_domain, request_method, sequence_format, addfile_key, multimer_mode, stoichiometry_key)
		 VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', %d, '%s')",        
        $group_id, $request_url, $request_cgi, $request_email, $email, $contact_person, $target_name_key, $sequence_key, $email_key, $other_parameters,
        $tarball_key, $qa_server_type, $meta_server_type, $methods_global, $methods_local, $email_domain, $request_method, $sequence_format, $addfile_key, $multimer_mode, $stoichiometry_key
        );
         
        my $sth = $self->{_database}->query($query);
        if(!defined($sth)) {
            $result = 0;
        }         
    }        
    return $result;
}

sub exists_server_connected_with_email {
	my ($self, $sender_email) = @_;
	my $result = 0;

	my $actual_email = $sender_email;
	my $index_of_at = index($actual_email, "\@");
	my $email_domain = substr $actual_email, $index_of_at;

	if ($email_domain ne '') {
		my $index_of_at = index($email_domain, "\@");
		if ($index_of_at < 0) {
			$email_domain = "\@" . $email_domain;
		}
	}
	my $query = sprintf("SELECT COUNT(id) FROM casp13.servers WHERE (UPPER(email_domain) SIMILAR TO '%%%s%%' or UPPER(contact) = '%s' or UPPER(response_email) = '%s' or UPPER(request_email) = '%s' or UPPER(server_email) = '%s')", uc($email_domain), uc($sender_email), uc($sender_email), uc($sender_email), uc($sender_email));
	my $sth = $self->{_database}->query($query);
    
	if(defined($sth) && ($sth->rows() > 0)) {
        	my ($count) = $sth->fetchrow_array();
        
        	$result = ($count > 0) ? 1 : 0;
	}
	return $result;
}

sub add_observer {
    
    my ($self, $predictor_id, $account_name, $attend_count) = @_;
    my $result = 0;
    my $query = sprintf("INSERT INTO casp13.observers (id, account_name, attend_count) VALUES (%d, '%s', %d)",        
     $predictor_id, $account_name, $attend_count
     );
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth)) {
        
        $result = 1;
    }         
    
    return $result;
}


sub add_crosslinker {

    my ($self, $account_id, $account_name, $predictor_id, $no_prots, $min_ug, $remarks, $attend_count) = @_;
    # check if exist
    my $query = sprintf("SELECT account_id FROM casp13.crosslinkers WHERE account_id = %d " , $account_id);
    my $sth = $self->{_database}->query($query);
    my $record_exist = 0;
    if (defined($sth) && ($sth->rows() > 0)){
	$record_exist = 1;
    }
 
    if ($record_exist == 0){ # if doesn't exist: INSERT
      my $result1 = 0;
      my $query1 = sprintf("INSERT INTO casp13.crosslinkers (account_id, account_name, predictors_id, no_prots, min_ug, remarks, attend_count) VALUES (%d, '%s', %d, %d, '%s', '%s', %d)",
       $account_id, $account_name, $predictor_id, $no_prots, $min_ug, $remarks, $attend_count
       );
      my $sth1 = $self->{_database}->query($query1);
      if(defined($sth1)) {
        $result1 = 1;
      }
      return $result1;
    } else { # if record exist : UPDATE
      my $result2 = 0;
      my $query2 = sprintf("UPDATE casp13.crosslinkers SET (account_name, predictors_id, no_prots, min_ug, remarks, attend_count)=('%s', %d, %d, '%s', '%s', %d) WHERE account_id=%d ",
         $account_name, $predictor_id, $no_prots, $min_ug, $remarks, $attend_count, $account_id
      );
      my $sth2 = $self->{_database}->query($query2);
      if(defined($sth2)) {
        $result2 = 1;
      }
      return $result2;
    }

}


sub update {
    my ($self, $id, $name, $code, $type, $url, $pin) = @_;
    
    my $result = 0;
    
    return $result if(! $self->exist($id));
    
    my $query = sprintf("UPDATE casp13.groups SET name = '%s', code = %d, type = %d, url = '%s', pin = '%s' WHERE (id = %d)", $name, $code, $type, $url, $pin, $id);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth)) {
        # add logger
        $result = 1;
    }
    
    return $result;
}

sub rename {
    my ($self, $id, $name) = @_;
    
    my $result = 0;
    
    return $result if(! $self->exist($id));
    
    my $query = sprintf("UPDATE casp13.groups SET name = '%s' WHERE (id = %d)", $name, $id);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth)) {
        # add logger
        $result = 1;
    }
    
    return $result;
}

sub do_block {
    my ($self, $id) = @_;
    
    my $result = 0;
    
    return $result if(! $self->exist($id));
    
    my $query = sprintf("UPDATE casp13.groups SET is_blocked = 1 WHERE (id = %d)", $id);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth)) {
        $result = 1;
    }
    
    return $result;
}

sub do_unblock {
    my ($self, $id) = @_;
    
    my $result = 0;
    
    return $result if(! $self->exist($id));
    
    my $query = sprintf("UPDATE casp13.groups SET is_blocked = 0 WHERE (id = %d)", $id);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth)) {
        $result = 1;
    }
    
    return $result;
}

sub edit_group {
    my ($self, $id, $name, $attend_count,
    $ts_output, $al_output, $dp_output, $dr_output, $fn_output, $rr_output, $qa_output, $tbm_output, $fm_output, $is_capri, $tc_output, $tr_output, $ta_output) = @_;
    
    my $result = 0;
    
    return $result if(! $self->exist($id));

    if (! defined($is_capri) || $is_capri == 0){
        $is_capri = 0;
    } else {
        $is_capri = 1;
    }
    
    if (! defined($tc_output) || $tc_output == 0){
        $tc_output = 0;
    } else {
        $tc_output = 1;
    }

    if (! defined($tr_output) || $tr_output == 0){
        $tr_output = 0;
    } else {
        $tr_output = 1;
    }

    if (! defined($ta_output) || $ta_output == 0){
        $ta_output = 0;
    } else {
        $ta_output = 1;
    }

    my $query = sprintf("UPDATE casp13.groups SET name = '%s', attend_count='%s', ts_output='%s', al_output='%s', dp_output='%s', dr_output='%s', fn_output='%s', rr_output='%s', qa_output='%s', tbm_output='%s', fm_output='%s', is_capri='%s', tc_output='%s', tr_output='%s', ta_output='%s' WHERE (id = %d)"
                        , $name, $attend_count, $ts_output, $al_output, $dp_output, $dr_output, $fn_output, $rr_output, $qa_output, $tbm_output, $fm_output, $is_capri, $tc_output, $tr_output, $ta_output, $id);
    
    my $sth = $self->{_database}->query($query);    
    if(defined($sth)) {
        $result = 1;    
    }    
    return $result;
}

sub edit_server {
    my ($self, $id, $name, $attend_count,
    $ts_output, $al_output, $dp_output, $dr_output, $fn_output, $rr_output, $qa_output, $tbm_output, $fm_output,
    $request_url, $request_email, $email, $contact_person, $target_name_key, $sequence_key, $email_key, $other_parameters,
    $tarball_key, $qa_server_type, $meta_server_type, $methods_global, $methods_local, $is_capri,
    $tc_output, $tr_output, $ta_output, $addfile_key, $multimer_mode, $stoichiometry_key
	) = @_;
    
    if (! defined($is_capri) || $is_capri == 0){
        $is_capri = 0;
    } else {
        $is_capri = 1;
    }

    if (! defined($tc_output) || $tc_output == 0){
        $tc_output = 0;
    } else {
        $tc_output = 1;
    }

    if (! defined($tr_output) || $tr_output == 0){
        $tr_output = 0;
    } else {
        $tr_output = 1;
    }

    if (! defined($ta_output) || $ta_output == 0){
        $ta_output = 0;
    } else {
        $ta_output = 1;
    }

    my $result = 0;

    my $query = sprintf("UPDATE casp13.groups SET
    name = '%s', attend_count='%s', ts_output='%s', al_output='%s', dp_output='%s', dr_output='%s', fn_output='%s', rr_output='%s', qa_output='%s', tbm_output='%s', fm_output='%s', is_capri='%s', tc_output='%s', tr_output='%s', ta_output='%s'
 WHERE (id = %d)",
    $name, $attend_count, $ts_output, $al_output, $dp_output, $dr_output, $fn_output, $rr_output, $qa_output, $tbm_output, $fm_output, $is_capri, $tc_output, $tr_output, $ta_output, $id);
        
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth)) {
        my $query = sprintf("UPDATE casp13.servers SET
        request_url='%s', request_email='%s', contact='%s', contact_person='%s', target_name_key='%s', sequence_key='%s', email_key='%s', other_parameters='%s',
        tarball_key='%s', qa_server_type='%s', meta_server_type='%s', methods_global='%s', methods_local='%s', addfile_key='%s', multimer_mode=%d, stoichiometry_key='%s'
        WHERE (group_id = %d)",
        $request_url, $request_email, $email, $contact_person, $target_name_key, $sequence_key, $email_key, $other_parameters,
        $tarball_key, $qa_server_type, $meta_server_type, $methods_global, $methods_local,
	$addfile_key, $multimer_mode, $stoichiometry_key,
        $id);
        my $sth = $self->{_database}->query($query);
        if(defined($sth)) {
            # add logger
            $result = 1;
        }
    }
    
    return $result;
}

sub edit_http_server {
    my ($self, $id, $name, $attend_count,
    $ts_output, $al_output, $dp_output, $dr_output, $fn_output, $rr_output, $qa_output, $tbm_output, $fm_output,
    $request_url, $request_email, $email, $contact_person, $target_name_key, $sequence_key, $email_key, $other_parameters,
    $tarball_key, $qa_server_type, $meta_server_type, $methods_global, $methods_local, $email_domain, $request_cgi, $request_method, $sequence_format, $is_capri,
     $tc_output, $tr_output, $ta_output, $addfile_key, $multimer_mode, $stoichiometry_key) = @_;
    
    my $result = 0;
    
    return $result if(! $self->exist($id));
    
    return $result if(! $self->exist($id));
    
	if ($email_domain ne '') {
		my $index_of_at = index($email_domain, "\@");
		if ($index_of_at < 0) {
			$email_domain = "\@" . $email_domain;
		}
	}
    if (! defined($is_capri) || $is_capri == 0){
        $is_capri = 0;
    } else {
        $is_capri = 1;
    }

    if (! defined($tc_output) || $tc_output == 0){
        $tc_output = 0;
    } else {
        $tc_output = 1;
    }

    if (! defined($tr_output) || $tr_output == 0){
        $tr_output = 0;
    } else {
        $tr_output = 1;
    }

    if (! defined($ta_output) || $ta_output == 0){
        $ta_output = 0;
    } else {
        $ta_output = 1;
    }
    my $query = sprintf("UPDATE casp13.groups SET
    name = '%s', attend_count='%s', ts_output='%s', al_output='%s', dp_output='%s', dr_output='%s', fn_output='%s', rr_output='%s', qa_output='%s', tbm_output='%s', fm_output='%s', is_capri='%s', tc_output='%s', tr_output='%s', ta_output='%s' WHERE (id = %d)",
    $name, $attend_count, $ts_output, $al_output, $dp_output, $dr_output, $fn_output, $rr_output, $qa_output, $tbm_output, $fm_output, $is_capri, $tc_output, $tr_output, $ta_output,  $id);
        
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth)) {
        my $query = sprintf("UPDATE casp13.servers SET
        request_url='%s', request_email='%s', contact='%s', contact_person='%s', target_name_key='%s', sequence_key='%s', email_key='%s', other_parameters='%s',
        tarball_key='%s', qa_server_type='%s', meta_server_type='%s', methods_global='%s', methods_local='%s', email_domain='%s', request_method='%s', sequence_format='%s', request_cgi='%s',
	addfile_key='%s', multimer_mode=%d, stoichiometry_key='%s' 
        WHERE (group_id = %d)",
        $request_url, $request_email, $email, $contact_person, $target_name_key, $sequence_key, $email_key, $other_parameters,
        $tarball_key, $qa_server_type, $meta_server_type, $methods_global, $methods_local, $email_domain, $request_method, $sequence_format, $request_cgi,
	$addfile_key, $multimer_mode, $stoichiometry_key,
        $id);
        my $sth = $self->{_database}->query($query);
        if(defined($sth)) {
            # add logger
            $result = 1;
        }
    }
    
    return $result;
}

sub edit_server_simple {
    my ($self, $id, $request_method, $sequence_format, $request_url, $request_cgi, $request_email, $response_email, $target_name_key, $sequence_key, $tarball_key, $email_key, $other, $stoichiometry_key) = @_;
    
    my $result = 0;
    
    my $query = sprintf("UPDATE casp13.servers SET request_method = '%s', sequence_format = '%s', request_url = '%s', request_cgi = '%s', request_email = '%s', response_email = '%s', target_name_key = '%s', sequence_key = '%s', tarball_key = '%s', email_key = '%s', other_parameters = '%s', stoichiometry_key='%s' WHERE (group_id = %d)",
    quotemeta($request_method), quotemeta($sequence_format), quotemeta($request_url), quotemeta($request_cgi), quotemeta($request_email), quotemeta($response_email), quotemeta($target_name_key), quotemeta($sequence_key), quotemeta($tarball_key), quotemeta($email_key), quotemeta($other), $stoichiometry_key, $id);
    
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth)) {
        $result = 1;
    }
    
    return $result;
}

sub edit_http_server_domain {
    my ($self, $id, $new_domain) = @_;
    
    my $result = 0;
    
    	### TODO it should be changed so as to change email domain in above method
	### TODO (edit_server_simple)- it is a hot fix during CASP 9, I had to add 
	### TODO $email_domain parameter, but due to the fact that in perl there is no 
	### TODO null value I don't know if edit_sever_simple is used in other places than 
	### TODO group.cgi. 
	if ($new_domain ne '') {
		my $index_of_at = index($new_domain, "\@");
		if ($index_of_at < 0) {
			$new_domain = "\@" . $new_domain;
		}
	}

    my $query = sprintf("UPDATE casp13.servers SET email_domain = '%s' WHERE (group_id = %d)",
    quotemeta($new_domain), $id);
    
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth)) {
        $result = 1;
    }
    
    return $result;
}

sub is_pure_qa_server {
    my ($self, $group_id) = @_;
    
    my $result = 0;
    
	my $query = sprintf("SELECT id FROM casp13.groups WHERE (id = %d) AND (((ts_output + al_output + dp_output + dr_output + fn_output + rr_output + tc_output + tr_output + ta_output) = 0) AND (qa_output = 1)) LIMIT 1", $group_id);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
		$result = 1;
	}
    
    return $result;
}

sub is_qa_server {
    my ($self, $group_id) = @_;
    
    my $result = 0;
    
	my $query = sprintf("SELECT id FROM casp13.groups WHERE (id = %d) AND (qa_output = 1) LIMIT 1", $group_id);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
		$result = 1;
	}
    
    return $result;
}

sub is_tc_server {
    my ($self, $group_id) = @_;

    my $result = 0;

        my $query = sprintf("SELECT id FROM casp13.groups WHERE (id = %d) AND (tc_output = 1) LIMIT 1", $group_id);
    my $sth = $self->{_database}->query($query);

    if(defined($sth) && ($sth->rows() > 0)) {
                $result = 1;
        }
    
    return $result;
}

sub is_ta_server {
    my ($self, $group_id) = @_;

    my $result = 0;

        my $query = sprintf("SELECT id FROM casp13.groups WHERE (id = %d) AND (ta_output = 1) LIMIT 1", $group_id);
    my $sth = $self->{_database}->query($query);

    if(defined($sth) && ($sth->rows() > 0)) {
                $result = 1;
        }

    return $result;
}


sub delete {
    my ($self, $id) = @_;
    
    my $result = 0;
    
    return $result if(! $self->exist($id));
    
    my $is_server = $self->is_server($id);
    
    if($is_server) {
        my $query = sprintf("DELETE FROM casp13.servers WHERE (group_id = %d)", $id);
        my $sth = $self->{_database}->query($query);
        
        if(!defined($sth)) {
            return $result;
        }
    }
    
    my $query = sprintf("DELETE FROM casp13.groups WHERE (id = %d)", $id);
    my $sth = $self->{_database}->query($query);
        
    if(defined($sth)) {
        # add logger
        $result = defined($sth) ? 1 : 0;
    }
    
    return $result;
}

sub groups {
    my ($self, $id) = @_;
    
    my @groups = ();
    
    my $members_manager = new MembersManager();
    
    my $query = sprintf("SELECT g.id, g.name, g.type, g.pin, g.code, g.is_blocked, r.id, r.name FROM casp13.groups_predictors_relations gpr JOIN casp13.groups g ON (gpr.groups_id = g.id) JOIN casp13.predictors p ON (gpr.predictors_id = p.id) JOIN casp13.roles r ON (gpr.roles_id = r.id) WHERE (p.id = %d) ORDER BY g.date ASC", $id);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
        my $index = 1;
        while(my($group_id, $group_name, $type, $pin, $code, $is_blocked, $role_id, $role) = $sth->fetchrow_array()) {
            my @members = $members_manager->members($group_id);
            
            my $typename = 'Human';
            if($type == 1) {
               $typename = 'Server';
            }  elsif($type == 2) {
                $typename = 'Server-E';
            }  elsif($type == 3) {
                $typename = 'Extended';
            }
            
            push(@groups, {
                    ID => $group_id,
                    ROLE_ID => $role_id,
                    INDEX => $index,
                    NAME => $group_name,
                    TYPE => $type,
                    TYPENAME => $typename,
                    ROLE => $role,
                    PIN => $pin,
                    CODE => sprintf('%03d', $code),
                    IS_BLOCKED => $is_blocked,
                    MEMBERS => [@members]
            	}
            );
            $index++;
        }
    }
    
    return @groups;
}

sub servers {
    my ($self, $field, $order) = @_;
    
    $field = (!defined($field) || ($field eq '')) ? 'g.type' : $field;
    $order = (!defined($order) || ($order eq '')) ? 'ASC' : $order;
    
    my @servers = ();
    
    my $query = sprintf("SELECT g.id AS group_id, g.name, g.code, g.pin, g.type, g.is_blocked, s.request_url, s.request_cgi, s.sequence_format, s.request_email, s.request_method, s.email_key, s.sequence_key, s.target_name_key, s.tarball_key, s.other_parameters, s.contact, s.contact_person FROM casp13.groups g JOIN casp13.servers s ON s.group_id = g.id WHERE g.type = 1 OR g.type = 2 ORDER BY %s %s", $field, $order);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
        my $index = 1;
        while(my($group_id, $name, $code, $pin, $type, $is_blocked, $request_url, $request_cgi, $sequence_format, $request_email, $request_method, $email_key, $sequence_key, $target_name_key, $tarball_key, $other_parameters, $contact, $contact_person) = $sth->fetchrow_array()) {
            push(@servers, {
                    ID => $group_id,
                    NAME => $name,
                    INDEX => $index,
                    CODE => $code,
                    PIN => $pin,
                    TYPE => $type,
                    IS_BLOCKED => $is_blocked,
                    REQUEST_URL => $request_url,
                    REQUEST_CGI => $request_cgi,
                    SEQUENCE_FORMAT => $sequence_format,
                    REQUEST_EMAIL => $request_email,
                    REQUEST_METHOD => $request_method,
                    EMAIL_KEY => $email_key,
                    SEQUENCE_KEY => $sequence_key,
                    TARGET_NAME_KEY => $target_name_key,
                    TARBALL_KEY => $tarball_key,
                    OTHER_PARAMETERS => $other_parameters,
                    CONTACT => $contact,
                    CONTACT_PERSON => $contact_person
            	}
            );
            $index++;
        }
    }
    
    return @servers;
}

sub all_groups {
    my ($self, $field, $order) = @_;
    
    $field = (!defined($field) || ($field eq '')) ? 'gr.date' : $field;
    $order = (!defined($order) || ($order eq '')) ? 'DESC' : $order;
    
    my @groups = ();
    
    my $members_manager = new MembersManager();

 #   my $sub_query = "";
 #   
 #   if(defined($params->{groups_id}) && ($params->{groups_id} ne '')) {
 #	$sub_query .= sprintf(" and gr.id=\'%s\' ", $params->{groups_id});	
 #   }


    
 	my $query = sprintf("SELECT gr.id, gr.name, gr.code, gr.type, gr.is_blocked, gr.pin, gr.date, gr.ts_output, gr.al_output, gr.dp_output, gr.dr_output, gr.fn_output, gr.rr_output, gr.qa_output, gr.tbm_output, gr.fm_output, s.contact, s.contact_person


        FROM casp13.groups gr LEFT JOIN casp13.servers s ON (gr.id = s.group_id) ORDER BY %s %s", $field, $order);
        
        
        #print "Content-Type: text/html; charset=ISO-8859-1\n\n";
        
        
        #print $query . "<br>";
        
    my $sth = $self->{_database}->query($query);
    if(defined($sth) && ($sth->rows() > 0)) {
        my $index = 1;
        while(my($group_id, $group_name, $code, $type, $is_blocked, $pin, $date, $ts_output, $al_output, $dp_output, $dr_output, $fn_output, $rr_output, $qa_output, $tbm_output, $fm_output, $contact, $contact_person,
                 #$predictions_count, $targets_count, $gdt_z_sum, $model1_count
                 ) = $sth->fetchrow_array()) {
            my $typename = 'Human';
            if($type == 1) {
               $typename = 'Server';
            }  elsif($type == 2) {
                $typename = 'Server-E';
            }
            
            my @members = $members_manager->members($group_id);
            
            push(@groups, {
                    ID => $group_id,
                    INDEX => $index,
                    NAME => $group_name,
                    CODE => $code,
                    CODE_FORMATED => sprintf('%03d', $code),
                    TYPE => $type,
                    TYPENAME => $typename,
                    PIN => $pin,
                    IS_BLOCKED => $is_blocked,
                    MEMBERS => [@members],
                    DATE => (defined($date) ? ((substr($date, 0, 10) . "<br>" . substr($date, 11, 8))) : '-'),
                    #PREDICTIONS => $predictions_count,
                    #TARGETS_COUNT => $targets_count,
                    #GDT_Z_SUM => $gdt_z_sum,
                    #MODEL1_COUNT =>$model1_count,
                    #GDT_Z_MEAN => (($model1_count>0)?($gdt_z_sum/$model1_count):0),

                    TS_OUTPUT => $ts_output,
                    AL_OUTPUT => $al_output,
                    DP_OUTPUT => $dp_output,
                    DR_OUTPUT => $dr_output,
                    FN_OUTPUT => $fn_output,
                    RR_OUTPUT => $rr_output,
                    QA_OUTPUT => $qa_output,
                    TBM_OUTPUT => $tbm_output,
                    FM_OUTPUT => $fm_output,
                    CONTACT => (!defined($contact) || ($contact eq '')) ? '-' : $contact, 
                    CONTACT_PERSON => (!defined($contact_person) || ($contact_person eq '')) ? '-' : $contact_person
            	}
            );
            $index++;
        }
    }
    
    return @groups;
}


sub distribution_servers {
    my ($self, $server_type, $field, $order, $target_name) = @_;
    
    $field = (!defined($field) || ($field eq '')) ? 'g.name' : $field;
    $order = (!defined($order) || ($order eq '')) ? 'DESC' : $order;
    
    my $server_type_query = '';
    
    if($server_type eq 'regular') {
        $server_type_query = ' AND ((g.ts_output + g.al_output + g.dp_output + g.dr_output + g.fn_output + g.rr_output) > 0)';
    } elsif($server_type =~ m/qa_only/ ) {
        $server_type_query = ' AND (g.qa_output = 1)';
    } elsif($server_type =~ m/^Tc/){ # contact-assissted which correspond to targets Tc, Tp, Ts, Tx
	$server_type_query = ' AND (g.tc_output = 1)';
    } elsif($server_type =~ m/^Ta/){ # assembly targets
	$server_type_query = ' AND (g.ta_output = 1)';
    } elsif($server_type =~ m/^TR/){ # refinement targets
        $server_type_query = ' AND (g.tr_output = 1)';
    }
    
    my @servers = ();
    
    my $query = sprintf("SELECT g.id AS group_id, g.name, g.code, g.pin, g.type, is_blocked, s.request_url, s.request_cgi, s.sequence_format, s.request_email, s.request_method, s.email_key, s.sequence_key, s.target_name_key, s.tarball_key, s.other_parameters, s.contact, s.contact_person, s.addfile_key, s.stoichiometry_key, s.multimer_mode, g.ta_output FROM casp13.groups g JOIN casp13.servers s ON s.group_id = g.id WHERE (g.is_blocked = 0) AND ((g.type = 1) OR (g.type = 2)) %s ORDER BY g.type ASC, %s %s", $server_type_query, $field, $order);
    my $sth = $self->{_database}->query($query);
    
    if(defined($sth) && ($sth->rows() > 0)) {
        my $index = 1;
        while(my($group_id, $name, $code, $pin, $type, $is_blocked, $request_url, $request_cgi, $sequence_format, $request_email, $request_method, $email_key, $sequence_key, $target_name_key, $tarball_key, $other_parameters, $contact, $contact_person, $addfile_key, $stoichiometry_key, $multimer_mode, $ta_output) = $sth->fetchrow_array()) {
            push(@servers, {
                    ID => $group_id,
                    NAME => $name,
                    INDEX => $index,
                    CODE => $code,
                    PIN => $pin,
                    TYPE => $type,
                    IS_BLOCKED => $is_blocked,
                    REQUEST_URL => $request_url,
                    REQUEST_CGI => $request_cgi,
                    SEQUENCE_FORMAT => $sequence_format,
                    REQUEST_EMAIL => $request_email,
                    REQUEST_METHOD => $request_method,
                    EMAIL_KEY => $email_key,
                    SEQUENCE_KEY => $sequence_key,
                    TARGET_NAME_KEY => $target_name_key,
                    TARBALL_KEY => $tarball_key,
		    ADDFILE_KEY => $addfile_key,
		    STOICHIOMETRY_KEY => $stoichiometry_key,
		    MULTIMER_MODE => $multimer_mode,
		    TA_OUTPUT => $ta_output, # if participate in assembly category
                    OTHER_PARAMETERS => $other_parameters,
                    CONTACT => $contact,
                    CONTACT_PERSON => $contact_person
            	}
            );
            $index++;
        }
    }
    #return @servers;
    # filter out servers for multimer targets
    my @results;
    if (defined($target_name) && $target_name =~ m/^(H|O)/){ # multimer targets
	my $index = 1; # renumerate indexes
	foreach my $s (@servers){
		if($s->{MULTIMER_MODE} == 0 && $s->{TA_OUTPUT} == 1){ # whole structure - all sequences required to submit
			$s->{INDEX} = $index;
			push @results, $s;
			$index++;
		}
	}
	return @results;
    } elsif (defined($target_name) && $target_name =~ m/^T.*s/){ # subunit of multimer target
	my $index = 1; # renumerate indexes
	foreach my $s (@servers){
                if($s->{TA_OUTPUT} == 0 || ($s->{MULTIMER_MODE} == 1 && $s->{TA_OUTPUT} == 1)){
			$s->{INDEX} = $index;
                        push @results, $s;
			$index++;
		}
        }
        return @results;
    }
    return @servers;
}


sub get_all_CAPRI_curators_emails {
    my ($self) = @_;

    my @emails = ();

    my $query = "SELECT DISTINCT a.email FROM casp13.groups g 
         JOIN casp13.groups_predictors_relations gpr ON g.id=gpr.groups_id
         JOIN casp13.predictors p ON gpr.predictors_id=p.id 
         JOIN accounts a ON a.id=p.accounts_id 
         WHERE gpr.roles_id=1 AND g.is_capri=1 ORDER BY a.email;" ;

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

    if(defined($sth) && ($sth->rows() > 0)) {
        while (my ($email) = $sth->fetchrow_array()){
                push (@emails, $email);
        }
    }

    return @emails;
}

# get group's leader by group_code
sub get_leader_by_group_code {
    my ($self, $gr_code) = @_;

    my $query = "SELECT a.email, pr.id AS predictors_id, gr.id AS groups_id 
		FROM casp13.groups gr 
		JOIN casp13.groups_predictors_relations gpr ON gpr.groups_id=gr.id 
		JOIN casp13.predictors pr ON pr.id=gpr.predictors_id JOIN accounts a on pr.accounts_id=a.id 
		WHERE gpr.roles_id=1 AND gr.code=$gr_code LIMIT 1 ";

    my $sth = $self->{_database}->query($query);
    my $result = undef;	
    if(defined($sth) && ($sth->rows() > 0)) {
        while (my ($email, $pr_id, $gr_id) = $sth->fetchrow_array()){
                $result = {_email => $email, 
			_predictors_id => $pr_id, 
			_groups_id => $gr_id};
        }
    }
    return $result;
}



1;
