#!/usr/bin/perl -w
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{"DFR_LIMIT_H"} ) ) { push ( @{$my_main{"DFR_LIMIT_H"}}, 0 ) };
if ( !exists($my_main{"DFR_LIMIT_K"} ) ) { push ( @{$my_main{"DFR_LIMIT_K"}}, 0 ) };
if ( !exists($my_main{"DFR_LIMIT_L"} ) ) { push ( @{$my_main{"DFR_LIMIT_L"}}, 0 ) };
if ( !exists($my_main{"FILE_CELL"} ) ) { push ( @{$my_main{"FILE_CELL"}}, "" ) };
if ( !exists($my_main{"FILE_REFL"} ) ) { push ( @{$my_main{"FILE_REFL"}}, "diffract.dat" ) };
if ( !exists($my_main{"FILE_SEQUENCE"} ) ) { push ( @{$my_main{"FILE_SEQUENCE"}}, "" ) };
if ( !exists($my_main{"FILE_MODEL_BACK"} ) ) { push ( @{$my_main{"FILE_MODEL_BACK"}}, "" ) };
if ( !exists($my_main{"FILE_MAPS"} ) ) { push ( @{$my_main{"FILE_MAPS"}}, "" ) };
if ( !exists($my_main{"FILE_MY_TOPO"} ) ) { push ( @{$my_main{"FILE_MY_TOPO"}}, "" ) };
if ( !exists($my_main{"FILE_TOPO"} ) ) { push ( @{$my_main{"FILE_TOPO"}}, "" ) };
if ( !exists($my_main{"DFR_FORMAT"} ) ) { push ( @{$my_main{"DFR_FORMAT"}}, "MAIN" ) };
if ( !exists($my_main{"INIT_MAP"} ) ) { push ( @{$my_main{"INIT_MAP"}}, "NONE" ) };

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

my $MACRO_FILE = "read.com" ;
my $PROC_ERROR = "FALSE" ;
my $doit = "FALSE" ;
my $SEGM ;


my $keyword ; 
foreach $keyword ( sort keys (%commands) ) 
{
    if ( $keyword eq 'h' || substr($keyword, 0,4) eq "help" ) { goto HELP }
    if ( $keyword eq 'a' || substr($keyword, 0,4) eq "atom" || substr($keyword, 0,3) eq "pdb" ) { goto PDB }
    if ( $keyword eq 'b' || substr($keyword, 0,4) eq "back" ) { goto BACK }
    if ( $keyword eq 'u' || substr($keyword, 0,4) eq "cell" ) { goto CELL }
    if ( $keyword eq 'c' || substr($keyword, 0,4) eq "ctab" ) { goto CTAB }
    if ( $keyword eq 'd' || substr($keyword, 0,5) eq "diffr" ) { goto DIFFR }
    if ( $keyword eq 'f' || substr($keyword, 0,10) eq "diffr_form" ) { goto DIFFR_FORM }
    if ( $keyword eq 'l' || substr($keyword, 0,5) eq "limit" || substr($keyword, 0,3) eq "hkl" ) { goto HKL }
    if ( $keyword eq 'i' || substr($keyword, 0,4) eq "init" ) { goto INIT_MAP }
    if ( $keyword eq 'm' || substr($keyword, 0,3) eq "map" ) { goto MAP }
    if ( $keyword eq 'o' || substr($keyword, 0,6) eq "output" ) { goto OUTPUT }
    if ( $keyword eq 'q' || substr($keyword, 0,3) eq "seq" ) { goto SEQ }
    if ( $keyword eq 'r' || substr($keyword, 0,5) eq "resol" ) { goto RESOL }
    if ( $keyword eq 's' || substr($keyword, 0,4) eq "symm" ) { goto SYMM }
    if ( $keyword eq 'y' || substr($keyword, 0,7) eq "my_topo" ) { goto MY_TOPO }
    if ( $keyword eq 't' || substr($keyword, 0,4) eq "topo" ) { goto TOPO }

    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|--help) prints this message with available options and current status 
  -a|--atom|--pdb) file with molecular model [@{$my_main{"FILE_MODEL"}}]
  -b|--back)       file of background molecules [@{$my_main{"FILE_MODEL_BACK"}}]
  -c|--ctab)       file with molecular connectivity table [@{$my_main{"FILE_CTAB"}}]
  -u|--cell)       file with unit cell constants [@{$my_main{"FILE_CELL"}}]
  -d|--diffr )     file with diffraction data [@{$my_main{"FILE_REFL"}}] 
  -f|--diffr_form) diffraction data format [MAIN/SCALEPACK/SHELX] [@{$my_main{"DFR_FORMAT"}}]
  -i|--init )      initial maps to be calculated [NONE/MODEL/FOBS/COMB] [@{$my_main{"INIT_MAP"}}]
  -l|--limit|--hkl)  set HKL limits for diffraction data [@{$my_main{"DFR_LIMIT_H"}}, @{$my_main{"DFR_LIMIT_K"}}, @{$my_main{"DFR_LIMIT_L"}}]
  -m|--map)        file names of additional maps to be read [@{$my_main{"FILE_MAPS"}}]
  -o|--output)     file name of the created macro [$MACRO_FILE]
  -q|--seq)        file name with sequence information [@{$my_main{"FILE_SEQUENCE"}}]
  -r|--resol)      resolution limits for diffraction data [@{$my_main{"DFR_RES_MIN"}} - @{$my_main{"DFR_RES_MAX"}}]
  -s|--symm)       space group symmetry [@{$my_main{"FILE_SYMM"}}]
  -t|--topo)       basic topology libraries more than one can be specified
                   [ENGH-HUBER/PURY/PURY_ALLH/SUGAR/RCSB_NUC]
                   current [@{$my_main{"FILE_TOPO"}}]
  -y|--my_topo)    additional topology libraries [@{$my_main{"FILE_MY_TOPO"}}]
     --doit)     create the macro $MACRO_FILE
END_OF_TEXT
    exit ;


 OUTPUT: $MACRO_FILE = shift ( @{$commands{$keyword}} ) ; next ;

 PDB: @{$my_main{"FILE_MODEL"}} = shift ( @{$commands{$keyword}} ) ; next ;
 CTAB: @{$my_main{"FILE_CTAB"}} = shift ( @{$commands{$keyword}} ) ; next ;
# CELL: @{$my_main{"FILE_CELL"}} = shift ( @{$commands{$keyword}} ) ; next ;
 CELL: @{$my_main{"FILE_CELL"}} = @{$commands{$keyword}} ; next ;
 SYMM: @{$my_main{"FILE_SYMM"}} = () ;
       foreach $SEGM ( @{$commands{$keyword}}) 
       { push ( @{$my_main{"FILE_SYMM"}}, lc($SEGM) ); }
       next ;
 SEQ: @{$my_main{"FILE_SEQUENCE"}} = shift ( @{$commands{$keyword}} ) ; next ;
 DIFFR: @{$my_main{"FILE_REFL"}} = shift ( @{$commands{$keyword}} ) ; next ;
 DIFFR_FORM:
    my $SEGM = shift( @{$commands{$keyword}} ) ; $SEGM = uc($SEGM) ;
if ( $SEGM eq "MAIN" || $SEGM eq "SCALEPACK" || $SEGM eq "SHELX" ) 
{ 
    @{$my_main{"DFR_FORMAT"}} = $SEGM;  
}
else { @{$my_main{"DFR_FORMAT"}} = "MAIN" ;  } 
next ;
 INIT_MAP: @{$my_main{"INIT_MAP"}} = shift ( @{$commands{$keyword}} ) ; next ;
 MY_TOPO: @{$my_main{"FILE_MY_TOPO"}} = @{$commands{$keyword}} ; next ;
 TOPO: @{$my_main{"FILE_TOPO"}} = () ;
       foreach $SEGM ( @{$commands{$keyword}}) 
       { push ( @{$my_main{"FILE_TOPO"}}, uc($SEGM) ); }
       next ;
 RESOL: @{$my_main{"DFR_RES_MIN"}} = shift ( @{$commands{$keyword}} ) ; 
       @{$my_main{"DFR_RES_MAX"}} = shift ( @{$commands{$keyword}} ) ; next ;
 HKL: @{$my_main{"DFR_LIMIT_H"}} = shift ( @{$commands{$keyword}} ) ; 
      @{$my_main{"DFR_LIMIT_K"}} = shift ( @{$commands{$keyword}} ) ; 
     @{$my_main{"DFR_LIMIT_L"}} = shift ( @{$commands{$keyword}} ) ; next ;
 MAP: @{$my_main{"FILE_MAPS"}} =  @{$commands{$keyword}} ; next ;
 BACK: @{$my_main{"FILE_MODEL_BACK"}} = 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 $FILE_SEQ = "" ;

if ( length ( ${$my_main{"FILE_SEQUENCE"}}[0]) > 0 )
{
    $FILE_SEQ = ${my_main{"FILE_SEQUENCE"}}[0] ; 
}

# my $FILE_SYMM = join( '', '"?MAIN_SYMM:', ${$my_main{"FILE_SYMM"}}[0], '.symm"' ) ;
# my $FILE_FOBS = ${$my_main{"FILE_REFL"}}[0] ;
# my $FILE_CELL = ${$my_main{"FILE_CELL"}}[0] ;
# my $RESOL_MIN = ${$my_main{"DFR_RES_MIN"}}[0] ;
# my $RESOL_MAX = ${$my_main{"DFR_RES_MAX"}}[0] ;

if ( length ($FILE_SEQ) > 0 ) 
{ print MACRO "set vari FILE_SEQ = $FILE_SEQ \n" ; }

# set vari FILE_SYMM = $FILE_SYMM 
# set vari FILE_FOBS = $FILE_FOBS
# set vari FILE_CELL = $FILE_CELL 
# 
# set vari RESOL_MIN global real = $RESOL_MIN 
# set vari RESOL_MAX global real = $RESOL_MAX 

if ( length ($my_main{"FILE_TOPO"}[0] ) <= 0  ) 
{
print MACRO << "END_OF_DATA" ;
< ?MAIN_UTILS:get_top_par_19_csd
END_OF_DATA
} 
else
{
    my $FILE ;
    print MACRO "! TOPOLOGY AND PARAMETERS SECTION \n"  ; 
    print MACRO "topo init \n"  ; 
    print MACRO "read param init \n"  ; 
    print MACRO "end_of_file\n\n"  ; 
    foreach $FILE ( @{$my_main{"FILE_TOPO"}} )
    {
#	print "topo loop: $FILE \n";
	if ( uc($FILE) eq "ENGH-HUBER" )
	{ print MACRO "< ?MAIN_UTILS:get_top_par_19_csd\n"  ; }
	if ( uc($FILE) eq "PURY" )
	{ print MACRO "< ?MAIN_UTILS:get_top_par_PURY\n"  ; }
	if ( uc($FILE) eq "PURY_ALLH" )
	{ print MACRO "< ?MAIN_UTILS:get_top_par_PURY_ALLH\n"  ; }
	if ( uc($FILE) eq "SUGAR" )
	{ print MACRO "< ?MAIN_UTILS:get_top_par_sugar.com\n"  ; }
	if ( uc($FILE) eq "RCSB_NUC" )
	{ print MACRO "< ?MAIN_UTILS:get_top_par_RCSB_NUC\n"  ; }
    }
    print MACRO "\n" ;
}


if ( length ($my_main{"FILE_MY_TOPO"}[0] ) > 0  )
{
    my $FILE_MY_TOPO = ${$my_main{"FILE_MY_TOPO"}}[0] ;
    print MACRO "\<", $FILE_MY_TOPO, "\n";
    print MACRO "read file MAIN_UTILS:dummy.dat topo main \n" ;
    print MACRO " \n" ;
}


#echo "-- 1 --"

if ( $my_main{"SG_NMOL"}[0] > $my_main{"SG_NGROUP"}[0] ) 
{	    
print MACRO  "set vari MAT_ROT global int = 3 \n" ; 
my $line = join( '', "load_", ${$my_main{"SG_NMOL"}}[0], "mol.com" ) ;
print MACRO  "< $line \n" ; 
}

if ( length (${$my_main{"FILE_SEQUENCE"}}[0]) > 0 )
{
    print MACRO "read file MAIN_UTILS:seq_sim_penalty.table sequence table \n" ;
    print MACRO "read file FILE_SEQ sequence protein \n" ;
}

my $FILE_ATOM = ${$my_main{"FILE_MODEL"}}[0] ;
my $FILE_CTAB = ${$my_main{"FILE_CTAB"}}[0] ;

print MACRO << "END_OF_DATA" ;
! ATOMS SECTION

set vari FILE_ATOM = $FILE_ATOM 
set vari FILE_CTAB = $FILE_CTAB

read file FILE_ATOM atom pdb
set vari WORK_SEGM char global segm sele all end 
 set rad sele segm name WORK_SEGM end vdw

read file FILE_CTAB ctable
show bonds
if ( IRESULT_0 .le. 0 ) <>utils/calculate.bonds WORK_SEGM

<DEF_ALL WORK_SEGM
define init group 
set charge sele .not atom name C CA N H O .a \\ 
    resi name ASP GLU LYS ARG end = 0.0

END_OF_DATA
    if ( $my_main{"SG_NCRYST"}[0] > 1 ) 
{
    my  $GROUP = join ( '', "SG_CRYST" , $my_main{"SG_NCRYST"}[0] ) ;
    $SEGM = join(" ", @{$my_main{$GROUP}} ) ;
    print MACRO "set vari WORK_SEGM char global = \"$SEGM\" \n" ;
}
# DIFRRACTION DATA
    my $CRYST ;
for ($CRYST=0; $CRYST < $my_main{"SG_NCRYST"}[0]; $CRYST++ )
{

main_config::write_get_diffr_data (*MACRO, \%my_main, $CRYST ) ; 
my $MAP = join ( '', "MAP_CRYS_" , $CRYST+1 ) ;

print MACRO << "END_DATA" ;
! map section

make map from 0 init -9999 auto_grid cell real
set vari $MAP = nmaps
make map from nmaps init -9999 

set vari MAP_2FOFC global inte = $MAP 
set vari MAP_FO global inte = $MAP 
set vari MAP_FOFC global inte = $MAP + 1 
set vari MAP_WORK global inte = $MAP + 1 

END_DATA
}


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

my $FILE ;
if ( length ($my_main{"FILE_MAPS"}[0]) > 0 && $my_main{"FILE_MAPS"}[0] ne " " )
{
    foreach $FILE ( @{$my_main{"FILE_MAPS"}} )
    {
	print MACRO "read file $FILE map xplor \n"  ;
    }
}

#echo "-- 3 --"

print MACRO << "END_OF_DATA" ;
ener all on dens on dens map MAP_2FOFC dens scal 25.
END_OF_DATA

    if ( $my_main{"INIT_MAP"}[0] eq "MODEL" )
{
print MACRO << "END_OF_DATA" ;

! map calculation from model

< ?MAIN_CMDS:re_phase.cmds WORK_SEGM MAP_WORK
< ?MAIN_CMDS:calc_fofc_diff_map.cmds MAP_2FOFC 2. 1. 
< ?MAIN_CMDS:calc_fofc_diff_map.cmds MAP_FOFC 1. 1.

copy map 2 3

END_OF_DATA
}

if ( $my_main{"INIT_MAP"}[0] eq "FOBS" )
{
print MACRO << "END_OF_DATA" ;

! map calculation
<?MAIN_CMDS:calc_fo_map.cmds MAP_FO

END_OF_DATA
}

if ( $my_main{"INIT_MAP"}[0] eq "COMB" )
{
print MACRO << "END_OF_DATA" ;

! map calculation
<?MAIN_CMDS:phase_comb.cmds MAP_FO

END_OF_DATA
}

print MACRO << "END_OF_DATA" ;

!      final part: opening display, unit cell, chain trace ...

ima init cent calc
<SAVE_FILE.VIEW
!<>utils/rama
<>utils/show.cell

END_OF_DATA

my $COLOR = 90 ;
foreach $FILE ( @{$my_main{"FILE_MODEL_BACK"}} )
{
    $FILE =~ s/ // ;
    if ( length($FILE) > 0 ) 
    {	
	print MACRO "<?MAIN_UTILS:background_file_image \\ \n" ; 
	print MACRO "   $FILE $COLOR \"delete\" \n" ; 
    }
    $COLOR = $COLOR + 10 ;
}

print MACRO << "END_OF_DATA" ;

ima sele atom name CA C N .a segm name WORK_SEGM end col 1 bond
ima from erase
END_OF_DATA

    my ( $MAP_FROM, $MAP_TO, $NCRYST ) ;
$NCRYST = $my_main{"SG_NCRYST"}[0] ;

for ( $CRYST = 0; $CRYST < $NCRYST ; $CRYST++ )
{
$MAP_FROM = $CRYST * 2 + 1 ;	     
$MAP_TO = $MAP_FROM + 1 ;	     
print MACRO << "END_OF_DATA" ;
 ima col 245 map $MAP_FROM dens 0.8 16 16 16 
 ima col  90 map $MAP_TO dens 2.0 16 16 16
END_OF_DATA
}
##echo "-- 5 --"

my $I = 2 ;
foreach $FILE ( @{$my_main{"FILE_MAPS"}} )
{
    $FILE =~ s/ // ;
    $I++ ; if ( length($FILE) > 0 ) 
{ print MACRO "image map $I dens 1.0 16 16 16 \n" ; }
}

print MACRO << "END_OF_DATA" ;

<?MAIN_CMDS:re_image.cmds WORK_SEGM

return
END_OF_DATA

close (MACRO) ;
