#!/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" ) } ; 
if ( !exists( $my_main{"ANAL_CENTER_GROUP"} ) ) { push ( @{$my_main{"ANAL_CENTER_GROUP"}}, "ACTIVE" ) } ; 

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

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 ( $keyword eq 'g' || substr($keyword, 0,5) eq "group" ) { goto GROUP }
    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/DENSITY/ENE_VDW/ENE_MAIN_CHAIN/CIS_PEPT/ROTAMER/PLANARITY/B-VALUE/LOW_MAP_PEAKS/HIGH_MAP_PEAKS/ION_LIST/ATOM_LIST/FILE] [@{$my_main{"ANAL_CENTER_BY"}}]
  -f|--field)     validation field to be examined [AVERAGE/RMS/MIN/MAX/BOTTOM/TOP] [@{$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] 
  -g|--group)     groups of selections [ACTIVE/WORK_SEGM/SELECTION] [@{$my_main{"ANAL_CENTER_GROUP"}}]
  -s|--selection) atom selection [@{$my_main{"ANAL_CENTER_SELECTION"}}]
  -k|--task)      additional task [NONE/MINIMIZE/FIT_SIDE/AUTO_FIT/PICK_ATOM/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 ;
GROUP: @{$my_main{"ANAL_CENTER_GROUP"}} = 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

}

my $MY_GROUP = $my_main{"ANAL_CENTER_GROUP"}[0] ;
my $SELECTION ; 

if ( $MY_GROUP eq "ACTIVE" ) 
{
    $SELECTION =  join(" ", "active .a .n atom name H*" ) ;
}
elsif ( $MY_GROUP eq "WORK_SEGM" )
{
    $SELECTION =  join(" ", "segm name WORK_SEGM .a .n atom name H* " ) ;
}
elsif ( $MY_GROUP eq "SELECTION" )
{
    $SELECTION =  join(" ", @{$my_main{"ANAL_CENTER_SELECTION"}} ) ;
}
else
{
    print "create_anal_center.pl> group for selection >$MY_GROUP< not recognized\n" ;
    exit ;
}


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

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
exit ;
}

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

    my $ANALYSIS_FILE = "validate.dat" ;
print MACRO " ener chem ( all off ) density on \n" ;
print MACRO " ener density ( scale -1.0 linear ) \n" ;
print MACRO " ener sele $SELECTION .a .n atom name H* end \n" ;
print MACRO " anal sele $SELECTION .a .n atom name H* end energy resid 1\n" ;
#print MACRO " ener sele $SELECTION end \n" ;
#print MACRO " anal sele $SELECTION end energy resid 1\n" ;
print MACRO " open unit 65 file $ANALYSIS_FILE over_write\n" ;
print MACRO " show unit 65 anal sele $SELECTION .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 ( all on ) dens on\n" ;
# set vari MY_MACRO = /stef/dus/MAIN/main/config/analize_file.pl 

print MACRO << "END_OF_TEXT" ; 
shell "analize_file.pl -i $ANALYSIS_FILE -o center_next.com -t 50 -f MIN -c 3 -k NONE -b DENSITY --doit"

<?MAIN_CMDS_NEW:center_define_mode.cmds VALIDATE 
close unit 66
open uni 66 file center_next.com read
stream uni 66
image cent sele atom numb NEXT_RESI end
image map over
return
END_OF_TEXT

close ( MACRO ) ;

exit ;
}

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
key MY_KEY sele $SELECTION end
< MAIN_UTILS:gen_centers_from_map.com $MY_MAP $CUT_OFF
shell "analize_file.pl -i atom_center_list.pdb  -r PEAKS -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 "CIS_PEPT" ) 
{

print MACRO << "END_OF_TEXT" ; 
make zt from ctab init sele $SELECTION end
calc inte sele $SELECTION end
write over file atom_center_list.pdb sele inte dihe -30. 30. .a atom name CA end coor pdb

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 "ROTAMER" ) 
{

print MACRO << "END_OF_TEXT" ; 
make zt from ctab init sele $SELECTION end
calc inte sele $SELECTION end
key rotmer sele .not. all end

key rotmer sele rotmer .o ( resi name ILE .a atom name CG1 CD1 .a inte dihe -30. 30. ) end
key rotmer sele rotmer .o ( resi name LEU .a atom name CG* CD* .a inte dihe -30. 30. ) end
key rotmer sele rotmer .o ( resi name CYS .a atom name SG* .a inte dihe -30. 30. ) end
key rotmer sele rotmer .o ( resi name VAL .a atom name CG2 .a inte dihe -30. 30. ) end
key rotmer sele rotmer .o ( resi name THR .a atom name CG2 .a inte dihe -30. 30. ) end
key rotmer sele rotmer .o ( resi name LYS .a atom name CG* CD* CE* NZ* .a inte dihe -30. 30. ) end
key rotmer sele rotmer .o ( resi name ARG .a atom name CG* CD* NE* .a inte dihe -30. 30. ) end
key rotmer sele rotmer .o ( resi name ASP ASN .a atom name CG* .a inte dihe -30. 30. ) end
key rotmer sele rotmer .o ( resi name ASN .a atom name ND2 .a inte dihe 150. 210. ) end
key rotmer sele rotmer .o ( resi name GLU GLN .a atom name CG* CD* .a inte dihe -30. 30. ) end
key rotmer sele rotmer .o ( resi name GLN .a atom name NE2 .a inte dihe 150. 210. ) end

key rotmer sele by resi rotmer .a atom name CA .a $SELECTION end 
show key rotmer
set vari II int atom sele rotmer end
close uni 66
if ( II .le. 0 ) then
return
end_if

write over file atom_center_list.pdb sele rotmer end coor pdb

!key rotmer drop

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_sel.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 ;
}
#print "anal by>", $my_main{"ANAL_CENTER_BY"}[0] , "<\n" ;

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 $SELECTION end 
# anal sele $SELECTION end force
#END_OF_TEXT

print MACRO "anal deviat bond sele $SELECTION end \n" ;
print MACRO "open unit 65 file $ANALYSIS_FILE over_write\n" ;
print MACRO "show unit 65 anal sele $SELECTION 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 $SELECTION end \n" ;
print MACRO "open unit 65 file $ANALYSIS_FILE over_write\n" ;
print MACRO "show unit 65 anal sele $SELECTION end\n" ;
print MACRO "clo unit 65\n" ;

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

#print MACRO "anal sele $SELECTION .a .n atom name H* end overlap $CUT_OFF \n" ;
print MACRO "anal sele $SELECTION end overlap $CUT_OFF \n" ;
print MACRO "open unit 65 file $ANALYSIS_FILE over_write\n" ;
print MACRO "show unit 65 anal sele $SELECTION end\n" ;
print MACRO "clo unit 65\n" ;
}
elsif ( $my_main{"ANAL_CENTER_BY"}[0] eq "PACK_SYM" ) 
{
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 
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 $SELECTION end
clo unit 65
END_OF_TEXT
}
elsif ( $my_main{"ANAL_CENTER_BY"}[0] eq "ENE_DENS" ) 
{

print MACRO " ener chem ( all off ) density on \n" ;
print MACRO " ener density ( scale -1.0 linear ) \n" ;
print MACRO " ener sele $SELECTION .a .n atom name H* end \n" ;
print MACRO " anal sele $SELECTION .a .n atom name H* end energy resid 1\n" ;
#print MACRO " ener sele $SELECTION end \n" ;
#print MACRO " anal sele $SELECTION end energy resid 1\n" ;
print MACRO " open unit 65 file $ANALYSIS_FILE over_write\n" ;
print MACRO " show unit 65 anal sele $SELECTION .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 ( all on ) dens on\n" ;

}
elsif ( $my_main{"ANAL_CENTER_BY"}[0] eq "ENE_VDW" ) 
{
#    print " in ene vdw\n";

print MACRO " ener chem ( all off vdw on )\n" ;
print MACRO " ener sele $SELECTION end \n" ;
print MACRO " anal sele $SELECTION end force\n" ;
print MACRO " open uni 65 file $ANALYSIS_FILE over_write\n" ;
print MACRO " show uni 65 anal sele $SELECTION 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_MAIN_CHAIN" ) 
{

print MACRO " ener chem ( all off vdw on elec on ) \n" ;
#print MACRO " ener sele $SELECTION end \n" ;
print MACRO " anal sele $SELECTION .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 $SELECTION .a atom name C N H CA CB O 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 "PLANARITY" ) 
{
#    print " in ene vdw\n";

print MACRO " ener chem ( all off plane on ) dens off \n" ;
print MACRO " ener sele $SELECTION end \n" ;
print MACRO " anal sele $SELECTION end force\n" ;
print MACRO " open uni 65 file $ANALYSIS_FILE over_write\n" ;
print MACRO " show uni 65 anal sele $SELECTION 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 "B-VALUE" ) 
{

print MACRO " anal sele $SELECTION .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 $SELECTION 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 -k $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 sele atom numb NEXT_RESI end
image map over
return
END_OF_TEXT


close ( MACRO ) ;





