#!/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 ) ; 
my %color_list = ("WHITE"=> 32, "RED"=>128, "ORANGE"=>144,"YELLOW"=>160,  "GREEN"=>196, "CYAN"=>220, "BLUE"=>244, "AS_IS"=>-1 ) ;

if ( !exists($my_main{"DM_SOLV_METHOD"} ) )  { push ( @{$my_main{"DM_SOLV_METHOD"}} , "WANG" ) };
if ( !exists($my_main{"DM_SOLV_WAY"} ) )  { push ( @{$my_main{"DM_SOLV_WAY"}} , "FFT" ) };
if ( !exists($my_main{"DM_SOLV_SPHERE"} ) )  { push ( @{$my_main{"DM_SOLV_SPHERE"}} , 10.0 ) };
if ( !exists($my_main{"DM_SOLV_CONTENT"}) )  { push ( @{$my_main{"DM_SOLV_CONTENT"}} , 0.93 ) };
if ( !exists($my_main{"DM_SOLV_INP"}  ) )  { push ( @{$my_main{"DM_SOLV_INP"}} , 1 ) };
if ( !exists($my_main{"DM_SOLV_RESULT"}  ) )  { push ( @{$my_main{"DM_SOLV_RESULT"}} , 3 ) };
if ( !exists($my_main{"DM_SOLV_FUNCTION"}  ) )  { push ( @{$my_main{"DM_SOLV_FUNCTION"}} , "LINEAR" ) };
if ( !exists($my_main{"DM_MAP_COLOR"}  ) )  { push ( @{$my_main{"DM_MAP_COLOR"}}  , "CYAN" ) ; }

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

my $ MACRO_FILE="map_mask_score_map.cmds" ;
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 'm' || substr($keyword, 0,6) eq "method" ) { goto METHOD }
    if ( $keyword eq 'c' || substr($keyword, 0,7) eq "content" ) { goto CONTENT }
    if ( $keyword eq 'i' || substr($keyword, 0,5) eq "input"  ) { goto INPUT }
    if ( $keyword eq 'r' || substr($keyword, 0,6) eq "result" ) { goto RESULT }
    if ( $keyword eq 's' || substr($keyword, 0,6) eq "sphere" ) { goto SPHERE }
    if ( $keyword eq 'f' || substr($keyword, 0,8) eq "function" ) { goto FUNCTION }
    if ( $keyword eq 'w' || substr($keyword, 0,3) eq "way" ) { goto WAY }
    if ( $keyword eq 'a' || substr($keyword, 0,5) eq "color" ) { goto COLOR }
    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 
-c|--content)    solvent content [@{$my_main{"DM_SOLV_CONTENT"}}]
-i|--input)      input density map  [1/2/3/4/5/6/7/8/9/10] [@{$my_main{"DM_SOLV_INP"}}]
-r|--result)     resulting score map  [1/2/3/4/5/6/7/8/9/10] [@{$my_main{"DM_SOLV_RESULT"}}]
-m|--method)     solvent flattening method [WANG/SOLOMON] [@{$my_main{"DM_SOLV_METHOD"}}]
-s|--sphere)     solvent flattening sphere radius [@{$my_main{"DM_SOLV_SPHERE"}}]
-f|--function)   solvent sphere function [LINEAR/GAUSSIAN] [@{$my_main{"DM_SOLV_FUNCTION"}}]
-w|--way)        calculation way [REAL_SPACE/FFT/FEM] [@{$my_main{"DM_SOLV_WAY"}}]
-a|--color)      color of the resulting map [RED/ORANGE/YELLOW/GREEN/CYAN/BLUE/WHITE] [@{$my_main{"DM_MAP_COLOR"}}]
-o|--output)     set file name of the created macro [$MACRO_FILE]
   --doit)       create the macro 
END_OF_TEXT
    exit ;
  OUTPUT: $MACRO_FILE = shift ( @{$commands{$keyword}} ) ; next ;

  CONTENT: @{$my_main{"DM_SOLV_CONTENT"}} = shift ( @{$commands{$keyword}} ) ; next ;
  INPUT:   @{$my_main{"DM_SOLV_INP"}} = shift ( @{$commands{$keyword}} ) ; next ;
  METHOD:  @{$my_main{"DM_SOLV_METHOD"}} = uc( shift ( @{$commands{$keyword}} )) ; next ;
  RESULT:  @{$my_main{"DM_SOLV_RESULT"}} = shift ( @{$commands{$keyword}} ) ; next ;
  SPHERE:  @{$my_main{"DM_SOLV_SPHERE"}} = shift ( @{$commands{$keyword}} ) ; next ;
  FUNCTION:  @{$my_main{"DM_SOLV_FUNCTION"}} = shift ( @{$commands{$keyword}} ) ; next ;
  WAY:  @{$my_main{"DM_SOLV_WAY"}} = uc( shift ( @{$commands{$keyword}} ) ) ; next ;
  COLOR:  @{$my_main{"DM_MAP_COLOR"}} = 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 ) ; 

###  . ${MAIN_CONF}main_config.data.save.sh

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

my $VARI = ${$my_main{"DM_SOLV_METHOD"}}[0] ;
my $CALC_WAY = ${$my_main{"DM_SOLV_WAY"}}[0] ;

my @METHOD = grep ( m/$VARI/, ("WANG", "SOLOMON" ) ) ;
if ( @METHOD <= 0 ) 
{ print "$MACRO_FILE %ERROR: no solvent accounting method specified ?? [@{$my_main{\"DM_SOLV_METHOD\"}}] \n"; exit }
my @TEST = grep ( m/$CALC_WAY/, ("REAL_SPACE", "FFT", "FEM" ) ) ;
if ( @TEST <= 0 ) 
{ 
    print "$MACRO_FILE %ERROR: no calcuation way specified ?? [@{$my_main{\"DM_SOLV_WAY\"}}] \n"; 
    exit 
}

my $COLOR =  $color_list{${$my_main{"DM_MAP_COLOR"}}[0]} ;
my $color_text = "" ;
if ( $COLOR > 0 ) { $color_text = "color ".$COLOR ; } 

print " color text: >", $color_text, "< >", $COLOR, "<\n" ;

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

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 $MAP_FROM = ${$my_main{"DM_SOLV_INP"}}[0] ;
my $MAP_TO = ${$my_main{"DM_SOLV_RESULT"}}[0] ;

my $SOLV_RAD = ${$my_main{"DM_SOLV_SPHERE"}}[0] ;
my $SOLV_CONTENT =  ${$my_main{"DM_SOLV_CONTENT"}}[0] ;
my $DENSITY_FUNCTION =  ${$my_main{"DM_SOLV_FUNCTION"}}[0] ;
my $MAP_LABEL = sprintf ( "\"SC%4.1f\"", $SOLV_RAD ) ;
$MAP_LABEL =~ s/ /x/ ;
#print " my  label: >$MAP_LABEL<\n" ;
#my $SCORE_MAP = "SCALE" ;
#$SCORE_MAP = "USUAL" ;

if ( $CALC_WAY ne "FEM" )
{
print MACRO << "END_OF_TEXT" ;
!set lev 3
set vari MAP_FROM = $MAP_FROM 
set vari MAP_TO = $MAP_TO 

make map MAP_TO from MAP_FROM full init cell real
END_OF_TEXT

if ( $VARI eq "WANG" ) 
{ print MACRO "make map MAP_TO from MAP_FROM copy\n" ; }
else
{ print MACRO "make map MAP_TO from MAP_FROM rad $SOLV_RAD rms grid\n" ; }

print MACRO << "END_OF_TEXT" ;

!make map MAP_TO set -999999 0 0.0

make map from MAP_TO empty init cell real
set vari NEW_MAP = MAP_LAST
if ( NEW_MAP .le. 0 ) return

fourier map MAP_TO

!reflect sele WORK_REFL end shells 10 r-values 

make atom from coor 0.0 0.0 0.0
make map NEW_MAP sele atom numb natom end atom dist $SOLV_RAD $DENSITY_FUNCTION
make map NEW_MAP set -999999 -100 0.0
dele atom sele atom numb natom end
fourier map NEW_MAP

make map MAP_TO from NEW_MAP mult
make map MAP_TO conj
dele map NEW_MAP

! refl move fcalc fwork
! refl sele defined .o asym end solv_flat SOLV_RAD 
! refl sele defined .o asym end set ampl phase fwork = fwork * 1.0 * fcalc * -1.0
! 
! make map MAP_TO zero
! refl fill-map MAP_TO select defined .o asymm end

four map MAP_TO back 
make map MAP_TO prescale 

anal ini 
anal map MAP_TO step 512 
show anal = $SOLV_CONTENT
image $color_text map MAP_TO label $MAP_LABEL
image $color_text map MAP_TO dens RESULT_0 map_boxx map_boxy map_boxz 
return
END_OF_TEXT

close(MACRO) ;
}

else
# fetature scaled
{
print MACRO << "END_OF_TEXT" ;
!set lev 3
set vari MAP_FROM = $MAP_FROM 
set vari MAP_SQ = $MAP_TO 
set vari MAP_SF = MAP_SQ + 1
set vari MAP_LN = MAP_SQ + 2

make map MAP_SQ from MAP_FROM full init cell real
make map MAP_SQ from MAP_FROM copy
make map MAP_SQ from MAP_SQ multiply
fourier map MAP_SQ
make map MAP_LN from MAP_FROM full init cell real
make map MAP_LN from MAP_FROM copy
fourier map MAP_LN

set vari VOL = 4 / 3 * 3.1415 * $SOLV_RAD * $SOLV_RAD * $SOLV_RAD

set vari NEW_MAP = nmaps + 1
make atom from coor 0.0 0.0 0.0

make map NEW_MAP from MAP_FROM init 0 cell real
make map NEW_MAP sele atom numb natom end atom dist $SOLV_RAD $DENSITY_FUNCTION
fourier map NEW_MAP
make map MAP_SQ from NEW_MAP mult
make map MAP_SQ conj
four map MAP_SQ back 

make map NEW_MAP zero
make map NEW_MAP sele atom numb natom end atom dist $SOLV_RAD $DENSITY_FUNCTION
fourier map NEW_MAP
make map MAP_LN from NEW_MAP mult
make map MAP_LN conj
make map MAP_LN from MAP_LN mult
four map MAP_LN back 

make map MAP_LN scale -1. \/ VOL
make map MAP_SQ from MAP_LN add

make map MAP_LN full
make map MAP_LN from MAP_FROM copy

make map MAP_SQ from MAP_LN divide

dele atom sele atom numb natom end
dele map NEW_MAP

! refl move fcalc fwork
! refl sele defined .o asym end solv_flat SOLV_RAD 
! refl sele defined .o asym end set ampl phase fwork = fwork * 1.0 * fcalc * -1.0
! 
! make map MAP_SQ zero
! refl fill-map MAP_SQ select defined .o asymm end

make map MAP_SQ prescale 

anal ini 
anal map MAP_SQ step 512 
show anal = $SOLV_CONTENT
image $color_text map MAP_SQ label $MAP_LABEL
image $color_text map MAP_SQ dens RESULT_0 map_boxx map_boxy map_boxz 
return
END_OF_TEXT

close(MACRO) ;

}
