#!/usr/bin/env perl
use strict;
use lib $ENV{ 'MAIN_CONF'}  ;
use main_config ;
my %commands = () ;

if ( @ARGV <= 0 ) { push ( @{$commands{'help'}}, ' ' ) ; } 
else { (%commands) = main_config::get_commands ( @ARGV ) ; }

my $conf_file ;
if ( -f "main_config.data" )
{    $conf_file = "main_config.data" ; }
else
{    $conf_file = join ('', $ENV{"MAIN_CONF"}, "main_config.data" ) ; }

my %my_main = main_config::read_main_config_file ( $conf_file ) ; 

#####################################################################

if ( !exists( $my_main{"ANAL_CENTER_BY"} ) ) { push ( @{$my_main{"ANAL_CENTER_BY"}}, "BOND" ) } ; 
if ( !exists( $my_main{"ANAL_CENTER_CUTOFF"} ) ) { push ( @{$my_main{"ANAL_CENTER_CUTOFF"}}, 3.0 ) } ; 
if ( !exists( $my_main{"ANAL_CENTER_TOP"} ) ) { push ( @{$my_main{"ANAL_CENTER_TOP"}}, 50 ) } ; 
if ( !exists( $my_main{"ANAL_CENTER_TASK"} ) ) { push ( @{$my_main{"ANAL_CENTER_TASK"}}, "NONE" ) } ; 
if ( !exists( $my_main{"ANAL_CENTER_FIELD"} ) ) { push ( @{$my_main{"ANAL_CENTER_FIELD"}}, "AVERAGE" ) } ; 
if ( !exists( $my_main{"ANAL_CENTER_MAP"} ) ) { push ( @{$my_main{"ANAL_CENTER_MAP"}}, 2 ) } ; 
if ( !exists( $my_main{"ANAL_CENTER_SELECTION"} ) ) { push ( @{$my_main{"ANAL_CENTER_SELECTION"}}, ".n all" ) } ; 

######################################################

my $MACRO_FILE = "anal_center_list.cmds" ;
my $PDB_FILE = "atom_list.pdb" ;
my $FL_ATOM_FILE = "NONE" ;
my $PROC_ERROR = "FALSE" ;
my $doit = "FALSE" ;

my $keyword ; 
foreach $keyword ( sort keys (%commands) ) 
{
    if ( $keyword eq 'h' || substr($keyword, 0,4) eq "help" ) { goto HELP }
    if ( $keyword eq 'o' || substr($keyword, 0,6) eq "output" ) { goto OUTPUT }
    if ( $keyword eq 'a' || substr($keyword, 0,4) eq "atom" ) { goto ATOM }
    if ( $keyword eq 'b' || substr($keyword, 0,2) eq "by" ) { goto BY }
    if ( $keyword eq 'c' || substr($keyword, 0,6) eq "cutoff" ) { goto CUTOFF }
    if ( $keyword eq 'f' || substr($keyword, 0,5) eq "field" ) { goto FIELD }
    if ( $keyword eq 'm' || substr($keyword, 0,3) eq "map" ) { goto MAP }
    if ( $keyword eq 't' || substr($keyword, 0,3) eq "top" ) { goto TOP }
    if ( $keyword eq 's' || substr($keyword, 0,9) eq "selection" ) { goto SELECTION }
    if ( $keyword eq 'k' || substr($keyword, 0,4) eq "task" ) { goto TASK }
    if ( substr($keyword, 0,4) eq "doit" ) { $doit = "TRUE" ; next ; }
    print "unknown option >$keyword<\n" ; $PROC_ERROR = "TRUE" ;

HELP:
    print << "END_OF_TEXT" ;
  -h|--help)      prints this message with available options and current status 
  -o|--output)    set file name of the created macro [$MACRO_FILE]
  -b|--by)        by [GEO_BOND/GEO_ANGLE/PACK/PACK_SYM/ENE_DENS/ENE_VDW/ENE_MAIN_CHAIN/B-VALUE/LOW_MAP_PEAKS/HIGH_MAP_PEAKS/ION_LIST/SELECTION/FILE] [@{$my_main{"ANAL_CENTER_BY"}}]
  -f|--field)     validation field to be examined [AVERAGE/RMS/MIN/MAX] [@{$my_main{"ANAL_CENTER_FIELD"}}]
  -c|--cutoff)    sigma cutoff value for the list creation [@{$my_main{"ANAL_CENTER_CUTOFF"}}]
  -t|--top)       the top violators [@{$my_main{"ANAL_CENTER_TOP"}}]
  -m|--map)       map for analysis [1/2/3/4/5/6/7/8/9/10] [@{$my_main{"ANAL_CENTER_MAP"}}]
  -a|--atom)      atom list PDB file [$PDB_FILE] 
  -s|--selection) atom selection [@{$my_main{"ANAL_CENTER_SELECTION"}}]
  -k|--task)      task [NONE/MINIMIZE/FIT_SIDE/AUTO_FIT/MY_TASK] [@{$my_main{"ANAL_CENTER_TASK"}}]
     --doit)     create the macro "$MACRO_FILE"
END_OF_TEXT
    exit;
OUTPUT: $MACRO_FILE = shift ( @{$commands{$keyword}} ) ; next ;
ATOM: $PDB_FILE = shift ( @{$commands{$keyword}} ) ; next ;
BY: @{$my_main{"ANAL_CENTER_BY"}} = shift ( @{$commands{$keyword}} ) ; next ;
CUTOFF: @{$my_main{"ANAL_CENTER_CUTOFF"}} = shift ( @{$commands{$keyword}} ) ; next ;
FIELD: @{$my_main{"ANAL_CENTER_FIELD"}} = shift ( @{$commands{$keyword}} ) ; next ;
MAP: @{$my_main{"ANAL_CENTER_MAP"}} = shift ( @{$commands{$keyword}} ) ; next ;
TOP: @{$my_main{"ANAL_CENTER_TOP"}} = shift ( @{$commands{$keyword}} ) ; next ;
SELECTION: @{$my_main{"ANAL_CENTER_SELECTION"}} = @{$commands{$keyword}} ; next ;
TASK: @{$my_main{"ANAL_CENTER_TASK"}} = shift ( @{$commands{$keyword}} ) ; next ;
}



if ( $PROC_ERROR eq "TRUE" ) { exit ; }

#######################################


$conf_file = "main_config.data" ; 
main_config::write_main_config_file ( $conf_file, %my_main ) ; 

if ( $doit eq "FALSE" )  { exit ; }

######################################

print "creating \"$MACRO_FILE\" \n" ;
if ( -f $MACRO_FILE ) 
{ 
    my $back = join ('', $MACRO_FILE, ".old" ) ; 
    system ( "mv  $MACRO_FILE $back" ) ; 
}
open ( MACRO,  "> $MACRO_FILE" ) || die "FILE OPEN ERROR: >$MACRO_FILE< \n" ;

my $TOP_COUNT =  ${$my_main{"ANAL_CENTER_TOP"}}[0] ;
my $CUT_OFF = $my_main{"ANAL_CENTER_CUTOFF"}[0] ;

if ( $my_main{"ANAL_CENTER_BY"}[0] eq "FILE" ) 
{

print MACRO << "END_OF_TEXT" ; 
subroutine char SEGMENTS
write over file $PDB_FILE sele active end coor pdb
close unit 66

shell "analize_file.pl -i $PDB_FILE  -r PDB -t $TOP_COUNT -o center_next.com --doit"

<?MAIN_CMDS_NEW:center_define_mode.cmds LIST

open uni 66 file center_next.com read
stream uni 66
return
END_OF_TEXT

}
if ( $my_main{"ANAL_CENTER_BY"}[0] eq "SELECTION" ) 
{

    my $SELECTION =  join(" ", @{$my_main{"ANAL_CENTER_SELECTION"}} ) ;
print MACRO << "END_OF_TEXT" ; 
subroutine char SEGMENTS
write over file $PDB_FILE sele $SELECTION end coor pdb
close unit 66

shell "analize_file.pl -i $PDB_FILE  -r PDB -t $TOP_COUNT -o center_next.com --doit"

<?MAIN_CMDS_NEW:center_define_mode.cmds LIST

open uni 66 file center_next.com read
stream uni 66
return
END_OF_TEXT

}


if ( $my_main{"ANAL_CENTER_BY"}[0] eq "LOW_MAP_PEAKS" || $my_main{"ANAL_CENTER_BY"}[0] eq "HIGH_MAP_PEAKS" ) 
{
my $macro_file = join ("", $ENV{"MAIN_CONF"}, "analize_file.pl" ) ; 
my $TOP_COUNT =  ${$my_main{"ANAL_CENTER_TOP"}}[0] ;
if ( $my_main{"ANAL_CENTER_BY"}[0] eq "LOW_MAP_PEAKS" ) 
{ 
    if ( $CUT_OFF > 0 ) { $CUT_OFF = - $CUT_OFF ; }
}
if ( $my_main{"ANAL_CENTER_BY"}[0] eq "HIGH_MAP_PEAKS" ) 
{ 
    if ( $CUT_OFF < 0 ) { $CUT_OFF = - $CUT_OFF ; }
}
my $MY_MAP = $my_main{"ANAL_CENTER_MAP"}[0] ;
print MACRO << "END_OF_TEXT" ; 
subroutine char SEGMENTS
!set vari MY_MACRO = $macro_file 
close unit 66

< MAIN_UTILS:gen_centers_from_map.com $MY_MAP $CUT_OFF
shell "analize_file.pl -i atom_center_list.pdb  -r PDB -t $TOP_COUNT -o center_next.com --doit"

<?MAIN_CMDS_NEW:center_define_mode.cmds LIST

open uni 66 file center_next.com read
stream uni 66
return
END_OF_TEXT


close ( MACRO ) ;

exit ;
}

if ( $my_main{"ANAL_CENTER_BY"}[0] eq "ION_LIST" ) 
{
my $macro_file = join ("", $ENV{"MAIN_CONF"}, "analize_file.pl" ) ; 
my $TOP_COUNT =  ${$my_main{"ANAL_CENTER_TOP"}}[0] ;

my $MY_MAP = $my_main{"ANAL_CENTER_MAP"}[0] ;
print MACRO << "END_OF_TEXT" ; 
subroutine char SEGMENTS
!set vari MY_MACRO = $macro_file 
close unit 66

< MAIN_UTILS:gen_ion_list_from_map.com $MY_MAP $CUT_OFF
shell "analize_file.pl -i atom_center_list.pdb  -r PDB -t $TOP_COUNT -o center_next.com --doit"

<?MAIN_CMDS_NEW:center_define_mode.cmds LIST

open uni 66 file center_next.com read
stream uni 66
return
END_OF_TEXT
close ( MACRO ) ;
exit ;
}



my $ANALYSIS_FILE = "validate.dat" ;
my $FIELD = $my_main{"ANAL_CENTER_FIELD"}[0] ;
my $TOP = $my_main{"ANAL_CENTER_TOP"}[0] ;
my $CUTOFF = $my_main{"ANAL_CENTER_CUTOFF"}[0] ;
my $TASK = $my_main{"ANAL_CENTER_TASK"}[0] ;

print MACRO << "END_OF_TEXT" ; 
subroutine char SEGMENTS
anal atom init
END_OF_TEXT

if ( $my_main{"ANAL_CENTER_BY"}[0] eq "GEO_BOND" ) 
{
#print MACRO << "END_OF_TEXT" ; 
#
# ener all off bond on angle on
# ener sele active end 
# anal sele active end force
#END_OF_TEXT

print MACRO "anal deviat bond sele active end \n" ;
print MACRO "open unit 65 file $ANALYSIS_FILE over_write\n" ;
print MACRO "show unit 65 anal sele active end\n" ;
print MACRO "clo unit 65\n" ;
print MACRO "ener chemistry ( all on ) dens on\n" ;

}
elsif ( $my_main{"ANAL_CENTER_BY"}[0] eq "GEO_ANGLE" ) 
{

print MACRO "anal deviat angle sele active end \n" ;
print MACRO "open unit 65 file $ANALYSIS_FILE over_write\n" ;
print MACRO "show unit 65 anal sele active end\n" ;
print MACRO "clo unit 65\n" ;

}
elsif ( $my_main{"ANAL_CENTER_BY"}[0] eq "PACK" ) 
{

print MACRO "anal sele active .a .n atom name H* end overlap $CUT_OFF \n" ;
print MACRO "open unit 65 file $ANALYSIS_FILE over_write\n" ;
print MACRO "show unit 65 anal sele active end\n" ;
print MACRO "clo unit 65\n" ;
}
elsif ( $my_main{"ANAL_CENTER_BY"}[0] eq "PACK_SYM" ) 
{
my $CMP = "NO" ;
if ( @{$my_main{"SG_NMOL"}}[0] > @{$my_main{"SG_NGROUP"}}[0] )
{
    my ( $IGR, $GROUP, $STRATEGY );
    for ( $IGR = 1; $IGR <= @{$my_main{"SG_NGROUP"}}[0] ; $IGR++ )
    {
	$GROUP= join ( '', "SG_GROUP" , $IGR ) ;
	$STRATEGY = join ( '', "SG_GROUP" , $IGR, "_STRATEGY" ) ;
	if ( $my_main{$STRATEGY}[0] eq "COMPOSIT" ) { $CMP = "YES" ; }
    }
}

if ( $CMP eq "YES" ) 
{
    print MACRO "dele atom sele segm name \#* end\n" ;

    my $MEMBER ; my $NN_GROUP=0 ;
    if ( @{$my_main{"SG_NMOL"}}[0] > @{$my_main{"SG_NGROUP"}}[0] )
    {
	my ( $IGR, $GROUP, $STRATEGY );
	for ( $IGR = 1; $IGR <= @{$my_main{"SG_NGROUP"}}[0] ; $IGR++ )
	{
	    $GROUP= join ( '', "SG_GROUP" , $IGR ) ;
	    $STRATEGY = join ( '', "SG_GROUP" , $IGR, "_STRATEGY" ) ;
	    if ( $my_main{$STRATEGY}[0] eq "COMPOSIT" ) 
	    { 
#	print " COMPOSIT groups: $IGR, <$GROUP> \n" ;
		
		my $LINE = join (" ", @{$my_main{$GROUP}} ) ;
		print MACRO " key out_gr  sele .n segm name $LINE end\n" ;
		foreach $MEMBER ( @{$my_main{$GROUP}} )
		{
#	print " groups: $IGR, <$GROUP> $MEMBER\n" ;
		    print MACRO  << "END_OF_TEXT"
! for segment $MEMBER

symm sele segm name $MEMBER .a .n atom name H* end \\
     around sele out_gr .o segm name $MEMBER end \\
     dist $CUT_OFF cut
rena segm \#WRK sele segm name \#* end
anal sele segm name WORK_SEGM .a .n atom name H* end \\
     sele segm name \#WRK end \\
     overlap $CUT_OFF 
rena segm \#OLD sele segm name \#WRK end

END_OF_TEXT
		}
	    }
	    else
	    { 
		my $LINE = join (" ", @{$my_main{$GROUP}} ) ;

print MACRO << "END_OF_TEXT"
dele atom sele segm name \#* end
symm sele segm name $LINE .a .n atom name H* end \\
     around sele segm name WORK_SEGM end \\
     dist $CUT_OFF cut
rena segm \#WRK sele segm name \#* end
anal sele segm name \#WRK end \\
     sele segm name WORK_SEGM .a .n atom name H* end \\
     overlap $CUT_OFF 
rena segm \#OLD sele segm name \#WRK end

END_OF_TEXT
	    }
	}
    }
    print MACRO " key out_gr drop\n" ;
}
else
{
print MACRO << "END_OF_TEXT"
dele atom sele segm name \#* end
symm sele segm name WORK_SEGM .a .n atom name H* end \\
     around sele segm name WORK_SEGM end \\
     dist $CUT_OFF cut
rena segm \#OLD sele segm name \#* end
anal sele segm name WORK_SEGM .a .n atom name H* end \\
     sele segm name \#OLD end \\
     overlap $CUT_OFF 
END_OF_TEXT
}


print MACRO << "END_OF_TEXT"
image group name PACK_OVERLAP
image sele segm name  \#OLD end col 90 bond
image sele segm name  \#OLD .a .n by bond all end col 90 atom cros

open unit 65 file $ANALYSIS_FILE over_write
show unit 65 anal sele active end
clo unit 65
END_OF_TEXT
}
elsif ( $my_main{"ANAL_CENTER_BY"}[0] eq "ENE_VDW" ) 
{

print MACRO " ener chem ( all off vdw on ) \n" ;
print MACRO " ener sele active end \n" ;
print MACRO " anal sele active end force\n" ;
print MACRO " open uni 65 file $ANALYSIS_FILE over_write\n" ;
print MACRO " show uni 65 anal sele active end\n" ;
print MACRO " clo uni 65\n" ;
print MACRO " ener chemistry ( all on ) dens on\n" ;

}
elsif ( $my_main{"ANAL_CENTER_BY"}[0] eq "ENE_DENS" ) 
{

print MACRO " ener all off density on \n" ;
print MACRO " ener density ( scale -1.0 linear ) \n" ;
print MACRO " ener sele active .a .n atom name H* end \n" ;
print MACRO " anal sele active .a .n atom name H* end energy resid 1\n" ;
#print MACRO " ener sele active end \n" ;
#print MACRO " anal sele active end energy resid 1\n" ;
print MACRO " open unit 65 file $ANALYSIS_FILE over_write\n" ;
print MACRO " show unit 65 anal sele active .a .n atom name H* .a weigh 0.01 100. end\n" ;
print MACRO " clo uni 65\n" ;
print MACRO " ener density ( scale 10.0 polynom 2 ) \n" ;
print MACRO " ener chemistry on dens on\n" ;

}
elsif ( $my_main{"ANAL_CENTER_BY"}[0] eq "ENE_MAIN_CHAIN" ) 
{

print MACRO " ener all off vdw on elec on\n" ;
#print MACRO " ener sele active end \n" ;
print MACRO " anal sele active .a atom name C N H CA CB O end energy resid 1 \n" ;
print MACRO " open uni 65 file $ANALYSIS_FILE over_write\n" ;
print MACRO " show uni 65 anal sele active .a atom name C N H CA CB O end\n" ;
print MACRO " clo uni 65\n" ;
print MACRO " ener chemistry on dens on\n" ;

}
elsif ( $my_main{"ANAL_CENTER_BY"}[0] eq "B-VALUE" ) 
{

print MACRO " anal sele active .a .n weigh -10. 0.01 end temperat\n" ;
print MACRO " open unit 65 file $ANALYSIS_FILE over_write\n" ;
print MACRO " show unit 65 anal sele active end\n" ;
print MACRO " clo uni 65\n" ;

}

my $macro_file = join ("", $ENV{"MAIN_CONF"}, "analize_file.pl" ) ;
#my $CENTER_BY =  $my_main{"ANAL_CENTER_BY"}[0] eq "B-VALUE" ;
my $CENTER_BY =  $my_main{"ANAL_CENTER_BY"}[0] ;
print MACRO << "END_OF_TEXT" ; 
set vari MY_MACRO = $macro_file 
shell "analize_file.pl -i $ANALYSIS_FILE -o center_next.com -t $TOP -f $FIELD -c $CUTOFF -s $TASK -b $CENTER_BY --doit"

<?MAIN_CMDS_NEW:center_define_mode.cmds VALIDATE 
END_OF_TEXT

print MACRO "close unit 66\n" ;
print MACRO "open uni 66 file center_next.com read\n" ;
print MACRO "stream uni 66\n" ;

print MACRO << "END_OF_TEXT" ; 
image cent calc sele atom numb NEXT_RESI end
image map over
return
END_OF_TEXT


close ( MACRO ) ;





