#!/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{"SYM_CA_COLOR"}  ) )   { push ( @{$my_main{"SYM_CA_COLOR"}} , 105 ) ; }
if ( !exists($my_main{"SYM_CA_STEP"}  ) )    { push ( @{$my_main{"SYM_CA_STEP"}}  , 4 ) ; }
if ( !exists($my_main{"SYM_CA_RADIUS"}  ) )  { push ( @{$my_main{"SYM_CA_RADIUS"}} , 60.0 ) ; }
if ( !exists($my_main{"SYM_CA_ATOM"}  ) )  { push ( @{$my_main{"SYM_CA_ATOM"}} , "CA" ) ; }
if ( !exists($my_main{"SYM_CA_IMAGE"}  ) )   { push ( @{$my_main{"SYM_CA_IMAGE"}} , "SPHERE" ) ; }

#if ( $my_main{"SG_NMOL"}[0] > 4 ) { $ICOLOR = 90 ; }
#if ( $my_main{"SG_NMOL"}[0] > 8 ) { $ICOLOR_STEP = 2 ; }


if ( !exists($my_main{"SYM_CA_SPHERE"}  ) )  { push ( @{$my_main{"SYM_CA_SPHERE"}} , 60.0 ) ; }

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

my $MACRO_FILE="symmetry_ca.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 'a' || substr($keyword, 0,4) eq "atom" ) { goto ATOM }
    if ( $keyword eq 'c' || substr($keyword, 0,5) eq "color" ) { goto COLOR }
    if ( $keyword eq 'r' || substr($keyword, 0,4) eq "step" ) { goto STEP }
    if ( $keyword eq 's' || substr($keyword, 0,6) eq "radius" ) { goto RADIUS }
    if ( $keyword eq 'g' || substr($keyword, 0,5) eq "gener"  ) { goto GENER }

    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]
  -a|--atom)    atom name for generation  [@{$my_main{"SYM_CA_ATOM"}}]
  -c|--color)   starting color index for molecules [@{$my_main{"SYM_CA_COLOR"}}]
  -s|--step)    increment of next molecule color [@{$my_main{"SYM_CA_STEP"}}]
  -r|--radius)  sphere radius for symmetry atoms generation 
                around the last picked atom [@{$my_main{"SYM_CA_RADIUS"}}]
  -g|--gener)   symmetry generation of symmetry mates
                by [SPHERE/NO_CUT/WHOLE/CLOSEST/EXACT] current [@{$my_main{"SYM_CA_IMAGE"}}]
                SPHERE: within a sphere of the above specified radius
                NO_CUT: evergy segment with at least an atom inside the specified radius
                CLOSEST: whole segments positioned closes to the last clicked atom
                WHOLE: whole segments positioned into the unit cell 
                EXACT: segments are cut and shiftd to fit exactly the unit cell edges 
     --doit)    create the macro 
END_OF_TEXT
    exit ;
OUTPUT: $MACRO_FILE = shift ( @{$commands{$keyword}} ) ; next ;
ATOM: @{$my_main{"SYM_CA_ATOM"}} = shift ( @{$commands{$keyword}} ) ; next ;
COLOR: @{$my_main{"SYM_CA_COLOR"}} = shift ( @{$commands{$keyword}} ) ; next ;
STEP: @{$my_main{"SYM_CA_STEP"}} = shift ( @{$commands{$keyword}} ) ; next ;
RADIUS: @{$my_main{"SYM_CA_RADIUS"}} = shift ( @{$commands{$keyword}} ) ; next ;
GENER:   @{$my_main{"SYM_CA_IMAGE"}} = uc(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 ; }

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

if ( -f $MACRO_FILE ) 
{ 
    my $back = join ('', $MACRO_FILE, ".old" ) ; 
    system ( "mv  $MACRO_FILE $back" ) ; 
}

print "creating \"$MACRO_FILE\" \n" ;
open ( MACRO,  "> $MACRO_FILE" ) || die "FILE OPEN ERROR: >$MACRO_FILE< \n" ;

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

my $SYMM_COLOR = ${$my_main{"SYM_CA_COLOR"}}[0] ;
my $SYMM_STEP = ${$my_main{"SYM_CA_STEP"}}[0] ;
my $SYMM_SPHERE = ${$my_main{"SYM_CA_RADIUS"}}[0] ;
my $SYMM_IMAGE = ${$my_main{"SYM_CA_IMAGE"}}[0] ;
my $SYMM_ATOM =  ${$my_main{"SYM_CA_ATOM"}}[0] ;

print "sym ca image>",   ${$my_main{"SYM_CA_IMAGE"}}[0] , "\n" ;

print MACRO << "END_OF_TEXT" ;
subroutine char SEGMENTS
delete atom select segment name \#* end

set vari CA_SPHERE real = $SYMM_SPHERE

make bond  sele segm name SEGMENTS end from residue = $SYMM_ATOM
delet bond select bond range 6.4 1000. end

END_OF_TEXT

if ( $my_main{"SYM_CA_IMAGE"}[0] eq "SPHERE" ||  $my_main{"SYM_CA_IMAGE"}[0] eq "NO_CUT")
{ print MACRO " set vari ATOM_SPHERE real = $SYMM_SPHERE \n\n" ; }

if ( $my_main{"SG_NMOL"} == 1 )
{
    print MACRO " key old select all end\n" ;
    print MACRO " image group name SYMMETRY_CA\n" ;

    if ( $my_main{"SYM_CA_IMAGE"}[0] eq "SPHERE" )
    { print MACRO
	  " symm select segment name SEGMENTS .a atom name $SYMM_ATOM end around center atom \$1  \\\n",
	  "   dist ATOM_SPHERE neigh 2 \n" ;
    } 
    elsif ( $my_main{"SYM_CA_IMAGE"}[0] eq "WHOLE" )
    { print MACRO
	  "symm select segment name SEGMENTS end cell ( whole ) \n";
    } 
    elsif ( $my_main{"SYM_CA_IMAGE"}[0] eq "CLOSEST" )
    { print MACRO
	  "symm sele segm name SEGMENTS .a atom name $SYMM_ATOM end cell ( close sele active end ) \n";
    }
    elsif ( $my_main{"SYM_CA_IMAGE"}[0] eq "EXACT" )
    { print MACRO
	  "symm sele segm name SEGMENTS .a atom name $SYMM_ATOM end cell ( cut ) \n";
    }
    elsif ( $my_main{"SYM_CA_IMAGE"}[0] eq "NO_CUT" )
    { print MACRO
	  " symm select segm name SEGMENTS .a atom name $SYMM_ATOM end \\\n",
	  "  around sele active end  dist ATOM_SPHERE neigh 1 delete ( by segm ) \n" ;
    }
    print MACRO
	" key SYMM_CA select .not old end \n",
	" image select SYMM_CA end col $SYMM_COLOR bond \n",
	" image select SYMM_CA .a .not by bond all end col $SYMM_COLOR atom cros\n\n";
}
else
{
    my $segm ; my $swat ;
    foreach $segm ( @{$my_main{"SG_LIST"}} )
    {
	$swat = $segm ; 
	print MACRO " image group name SYM_", $swat, "\n" ;
	print MACRO " key old select all end \n" ;
	if ( $my_main{"SYM_CA_IMAGE"}[0] eq "SPHERE" )
	{ print MACRO
	      " symm select segment name $swat .a segm name SEGMENTS .a atom name $SYMM_ATOM end around \\\n", 
	      "  center atom \$1 dist ATOM_SPHERE neigh 2 \n";
	} 
	elsif ( $my_main{"SYM_CA_IMAGE"}[0] eq "WHOLE" )
	{ print MACRO
	      "symm select segment name $swat .a segm name SEGMENTS .a atom name $SYMM_ATOM end cell whole\n";
	} 
	elsif ( $my_main{"SYM_CA_IMAGE"}[0] eq "CLOSEST" )
	{ print MACRO
	      "symm sele segm name $swat .a segm name SEGMENTS .a atom name $SYMM_ATOM end \\\n", 
	      "      cell ( close sele atom numb \$1 end ) \n";
	}
	elsif ( $my_main{"SYM_CA_IMAGE"}[0] eq "EXACT" )
	{ print MACRO
	      "symm sele segm name $swat .a segm name SEGMENTS .a atom name $SYMM_ATOM end \\\n", 
	      "      cell ( cut ) \n";
	}
	elsif ( $my_main{"SYM_CA_IMAGE"}[0] eq "NO_CUT" )
	{ print MACRO
	      " symm select segm name $swat .a segment name SEGMENTS .a atom name $SYMM_ATOM end \\\n",
	      "  around sele active end  dist ATOM_SPHERE neigh 2 delete ( by segm ) \n" ;
	}
	my $SEGM_NAME = join ('', "\#", $swat ) ;
	print MACRO
	    " key SYMM_M sele .not old end \n",
            " rena select SYMM_M end segm $SEGM_NAME \n",
	    " image select SYMM_M end col $SYMM_COLOR bond \n",
	    " image select SYMM_M .a .not by bond all end col $SYMM_COLOR atom cros \n\n" ;
	$SYMM_COLOR = $SYMM_COLOR + $SYMM_STEP ;
    }
}

print MACRO << "END_OF_TEXT" ;
key old select all end 
delete bond sele atom name $SYMM_ATOM .a segm name SEGMENTS end
return
END_OF_TEXT

close ( MACRO ) ;

exit ;

