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

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

my $MACRO_FILE = "make_masks.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 'd' || substr($keyword, 0,9) eq "directory" ) { goto DIRECTORY }
    if ( $keyword eq 's' || substr($keyword, 0,4) eq "size" ) { goto SIZE }
    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]
  -d|--directory)  directory for rotation and translational macros [@{$my_main{"DM_DIR_MASK"}}]
  -s|--size)       size of atoms (radii) [ $my_main{"DM_MASK_ATOM"}[0]]
     --doit)       create the macro 
END_OF_TEXT
    exit ;
OUTPUT: $MACRO_FILE = shift ( @{$commands{$keyword}} ) ; next ;
DIRECTORY: @{$my_main{"DM_DIR_MASK"}} = shift ( @{$commands{$keyword}} ) ; next ;
SIZE: @{$my_main{"DM_MASK_ATOM"}} = 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 ( $IGR, $CRYST, $GROUP, $CRYST_GROUP, $STRATEGY, $SEGM_BASE, $SEGM_IN, $SEGM_FROM, 
     $WORK_IN, $MASK_FILE, $MAP_FROM) ;
my @lines = () ; 

@lines = (@lines, "set vari ATOM_RAD = ", $my_main{"DM_MASK_ATOM"}[0], "\n" ) ;
@lines = (@lines, "set vari MAP_MASK = 9 \n") ;
push ( @lines, "\n" ) ;

for ( $IGR = 1; $IGR <= $my_main{"SG_NGROUP"}[0] ; $IGR++ )
{

#    print "2222 XXXXX\n";
    $GROUP= join ( '', "SG_GROUP" , $IGR ) ;
    $STRATEGY = join ( '', "SG_GROUP" , $IGR, "_STRATEGY" ) ;

    if ( $my_main{$STRATEGY}[0] eq "WHOLE" )
    {
	$MASK_FILE = join ('', $my_main{"DM_DIR_MASK"}[0], 
			   "mask_whole_", $IGR, ".mrc" ) ;
#	print "mask file WHOLE>: $MASK_FILE \n";
	$SEGM_BASE = join ( ' ', @{$my_main{$GROUP}} ) ;
#	print "segm base: $SEGM_BASE \n";
	for ( $CRYST = 0; $CRYST < $my_main{"SG_NCRYST"}[0] ; $CRYST++ )
	{
	    $CRYST_GROUP = join ( '', "SG_CRYST" , $CRYST+1 ) ;
	    foreach $SEGM_FROM ( @{$my_main{$CRYST_GROUP}} )
	    {
#		print " foreach : $SEGM_FROM \n" ;
		if ( $my_main{$GROUP}[0] eq $SEGM_FROM )
		{
		    $WORK_IN = join ( ' ', @{$my_main{$CRYST_GROUP}} ) ;
		    $MAP_FROM = $CRYST * 2 + 1 ;
		    print "! WHOLE mask crystal form ", $CRYST, " segment: ", $SEGM_BASE, 
		    " from map: ", $MAP_FROM, "\n"  ;
		}
	    }
	}

	@lines = (@lines, "set vari SEGM_BASE = \"", $SEGM_BASE, "\"\n") ;
	@lines = (@lines, "set vari WORK_IN = \"", $WORK_IN, "\"\n") ;
	@lines = (@lines, "set vari MAP_FROM = ", $MAP_FROM, "\n") ;
	@lines = (@lines, "make map MAP_MASK from MAP_FROM empty init \\ \n",
		  "     around 10 sele segm name SEGM_BASE end  real \n" ) ;
	@lines = (@lines, "! if ( MAP_MASK .ne. nmaps ) return \n") ; 
	@lines = (@lines, "dele atom sele segm name \#* end \n") ;
	@lines = (@lines, "key other sele .not segm name SEGM_BASE .a segm name WORK_IN end \n") ;
	push ( @lines, "\n" ) ;

	foreach $SEGM_IN ( @{$my_main{"SG_LIST"}} )
	{
	    @lines = (@lines, "symm sele segm name $SEGM_IN end around \\ \n") ;
	    @lines = (@lines, "     sele segm name SEGM_BASE end dist ATOM_RAD + 1. cut\n") ;
	}
	push ( @lines, "\n" ) ;

	@lines = (@lines, "set rad sele segm name SEGM_BASE end sele segm name \#* .or other end \\\n") ;
	@lines = (@lines, "	overlap 1.5 ATOM_RAD \n") ;
	@lines = (@lines, "\n") ;
	@lines = (@lines, "make map MAP_MASK atom ( radii mask ) select  segm name SEGM_BASE end\n") ;
	@lines = (@lines, "make map MAP_MASK + 1 from MAP_MASK full init copy\n") ;
	@lines = (@lines, "make map MAP_MASK from MAP_MASK + 1 fill 3\n") ;
	@lines = (@lines, "make map MAP_MASK + 1 from MAP_MASK full init copy\n") ;
	@lines = (@lines, "make map MAP_MASK from MAP_MASK + 1 fill 3\n") ;
	@lines = (@lines, "\n") ;
	@lines = (@lines, "write over file ", $MASK_FILE, " map MAP_MASK mrc\n") ;
	push ( @lines, "\n" ) ;
    }

# mask built of separated envelopes
    else
    {
	foreach $SEGM_BASE ( @{$my_main{$GROUP}} )
	{
	    $MASK_FILE = join ('', $my_main{"DM_DIR_MASK"}[0], 
			   "mask_", $SEGM_BASE, ".mrc" ) ;
	    for ( $CRYST = 0; $CRYST < $my_main{"SG_NCRYST"}[0] ; $CRYST++ )
	    {
		$CRYST_GROUP = join ( '', "SG_CRYST" , $CRYST+1 ) ;
		foreach $SEGM_FROM ( @{$my_main{$CRYST_GROUP}} )
		{
#		print " foreach : $SEGM_FROM \n" ;
		    if ( $SEGM_BASE eq $SEGM_FROM )
		    {
			$WORK_IN = join ( ' ', @{$my_main{$CRYST_GROUP}} ) ;
			$MAP_FROM = $CRYST * 2 + 1 ;
			print "! EACH MASK crystal form ", $CRYST, " segment: ", $SEGM_BASE, 
			" from map: ", $MAP_FROM, "\n"  ;
		    }
		}
	    }

	    @lines = (@lines, "set vari SEGM_BASE = ", $SEGM_BASE, "\n") ;
	    @lines = (@lines, "set vari WORK_IN = \"", $WORK_IN, "\"\n") ;
	    @lines = (@lines, "set vari MAP_FROM = ", $MAP_FROM, "\n") ;
	    @lines = (@lines, "make map MAP_MASK from MAP_FROM empty init \\ \n",
		      "     around 10 sele segm name SEGM_BASE end  real \n" ) ;
	    @lines = (@lines, "!if ( MAP_MASK .ne. nmaps ) return \n") ; 
	    @lines = (@lines, "dele atom sele segm name \#* end \n") ;
	    @lines = (@lines, "key other sele .not segm name SEGM_BASE .a segm name WORK_IN end \n") ;
	    push ( @lines, "\n" ) ;
	    
	    foreach $SEGM_IN ( (split( " ", $WORK_IN)) )
	    {
		@lines = (@lines, "symm sele segm name $SEGM_IN end around \\ \n") ;
		@lines = (@lines, "     sele segm name SEGM_BASE end dist ATOM_RAD + 1. cut\n") ;
	    }
	    push ( @lines, "\n" ) ;

	    @lines = (@lines, "set rad sele segm name SEGM_BASE end sele segm name \#* .or other end \\\n") ;
	    @lines = (@lines, "	overlap 1.5 ATOM_RAD \n") ;
	    @lines = (@lines, "\n") ;
	    @lines = (@lines, "make map MAP_MASK atom ( radii mask ) select  segm name SEGM_BASE end\n") ;
	    @lines = (@lines, "make map MAP_MASK + 1 from MAP_MASK full init copy\n") ;
	    @lines = (@lines, "make map MAP_MASK from MAP_MASK + 1 fill 4\n") ;
	    @lines = (@lines, "write over file ", $MASK_FILE, " map MAP_MASK mrc\n") ;
	    push ( @lines, "\n" ) ;

	}
    }
}


@lines = (@lines, "dele map MAP_MASK + 1\n") ;
@lines = (@lines, "dele map MAP_MASK\n") ;
@lines = (@lines, "key other drop\n") ;
@lines = (@lines, "return\n") ;

print MACRO @lines ;
close (MACRO ) ;


