#!/usr/bin/perl -w
use strict;
use lib $ENV{ 'MAIN_CONF'}  ;
use main_config ;
use File::Find ;

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 %new_main = () ;
my %column = () ; 
my @symmetry = () ;
my @words ;
my $record ;
my $ICL = 0 ;
my $FILE ;

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

if ( !exists( $my_main{"FILE_MTZ"} ) ) { push ( @{$my_main{"FILE_MTZ"}}, "solve.mtz" )} ;
push ( @{$new_main{"MTZ_FOBS"}}, "" ) ;
push ( @{$new_main{"MTZ_SIGMA"}}, "" ) ;
push ( @{$new_main{"MTZ_PHASE"}}, "" ) ;
push ( @{$new_main{"MTZ_WEIGHT"}}, "" ) ;
push ( @{$new_main{"MTZ_HLA"}}, "" ) ;
push ( @{$new_main{"MTZ_HLB"}}, "" ) ;
push ( @{$new_main{"MTZ_HLC"}}, "" ) ;
push ( @{$new_main{"MTZ_HLD"}}, "" ) ;
push ( @{$new_main{"INIT_MAP"}}, "NONE" ) ;

my $KEY ;
foreach $KEY ( %my_main )
{
    if ($KEY =~ m"MTZ_" ) { @{$new_main{$KEY}} = @{$my_main{$KEY}} }
}

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

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,3) eq "mtz" ) { goto MTZ }
    if ( $keyword eq 'f' || substr($keyword, 0,4) eq "fobs" ) { goto FOBS }
    if ( $keyword eq 'p' || substr($keyword, 0,6) eq "phase" ) { goto PHASE }
    if ( $keyword eq 's' || substr($keyword, 0,6) eq "sigma" ) { goto SIGMA }
    if ( $keyword eq 'w' || substr($keyword, 0,6) eq "weight" ) { goto WEIGHT }
    if ( $keyword eq 'a' || substr($keyword, 0,3) eq "HLA" ) { goto HLA }
    if ( $keyword eq 'b' || substr($keyword, 0,3) eq "HLB" ) { goto HLB }
    if ( $keyword eq 'c' || substr($keyword, 0,3) eq "HLC" ) { goto HLC }
    if ( $keyword eq 'd' || substr($keyword, 0,3) eq "HLD" ) { goto HLD }
    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
                if MTZ labels were not defined before the first found 
                F, Q, P and W records are taken as FOBS, SIGMA, PHASE and WEIGHT
                A are matched for HLA, HLB, HLC and HLD keywords 
  -m|--mtz)     mtz input file [$my_main{"FILE_MTZ"}[0]]
  -f|--fobs)    FOBS label in mtz file [$new_main{"MTZ_FOBS"}[0]]
  -s|--sigma)   SIGMA of FOBS label in mtz file [$new_main{"MTZ_SIGMA"}[0]]
  -p|--phase)   PHASE label in mtz file [$new_main{"MTZ_PHASE"}[0]]
  -w|--weight)  WEIGHT of PHASE label in mtz file [$new_main{"MTZ_WEIGHT"}[0]]
  -a|--hla)     HLA Hendrickson-Latman coeff label in mtz file [$new_main{"MTZ_HLA"}[0]]
  -b|--hlb)     HLB Hendrickson-Latman coeff label in mtz file [$new_main{"MTZ_HLB"}[0]]
  -c|--hlc)     HLC Hendrickson-Latman coeff label in mtz file [$new_main{"MTZ_HLC"}[0]]
  -d|--hld)     HLD Hendrickson-Latman coeff label in mtz file [$new_main{"MTZ_HLD"}[0]]
     --doit)    save extracted data in "main_config.data" 
                write cell constants and symmetry operators file
                create MTZ 2 MAIN macro and run it if "mtz2various" is found
END_OF_TEXT
    exit ;
MTZ: @{$my_main{"FILE_MTZ"}} = shift ( @{$commands{$keyword}} ) ; next ;
FOBS: @{$new_main{"MTZ_FOBS"}} = shift ( @{$commands{$keyword}} ) ; next ;
SIGMA: @{$new_main{"MTZ_SIGMA"}} = shift ( @{$commands{$keyword}} ) ; next ;
PHASE: @{$new_main{"MTZ_PHASE"}} = shift ( @{$commands{$keyword}} ) ; next ;
WEIGHT: @{$new_main{"MTZ_WEIGHT"}} = shift ( @{$commands{$keyword}} ) ; next ;
HLA: @{$new_main{"MTZ_HLA"}} = shift ( @{$commands{$keyword}} ) ; next ;
HLB: @{$new_main{"MTZ_HLB"}} = shift ( @{$commands{$keyword}} ) ; next ;
HLC: @{$new_main{"MTZ_HLC"}} = shift ( @{$commands{$keyword}} ) ; next ;
HLD: @{$new_main{"MTZ_HLD"}} = shift ( @{$commands{$keyword}} ) ; next ;
}

if ( $PROC_ERROR eq "TRUE" ) { exit ; }

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

my $MTZ_FILE = $my_main{"FILE_MTZ"}[0] ;
print "reading mtz file \"$MTZ_FILE\" \n" ;
open ( MTZ,  "< $MTZ_FILE" ) || die "FILE OPEN ERROR: >$MTZ_FILE< \n" ;

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

while (<MTZ> ) { $record = $_ ; } close ( MTZ ) ;

my @base = split ( 'VERS MTZ', $record ) ;

my $text = join ('', 'VERS MTZ', $base[1] ) ;

my @mtz_tail = () ;

my ($I, $N) ; $N = -1 ;
for ( $I = 0 ; $I <= length ($text) ; $I = $I + 80 )
{ 
    $N++; 
    push ( @mtz_tail, substr($text, $I, 79 ) ) ; 
#    printf ( "%5d : %5d : %5d >%s< \n", $I, $I+79, $N, $mtz_tail[$N] );
}

my $line ;
$I = 0 ;
my $out ;
while ( $I < $N )
{
#foreach $line (@mtz_tail ) 
    $line = $mtz_tail[$I] ; $I++ ;
    @words = split (" ", $line ) ;
# CELL
    if ( $line =~ m"^CELL" ) 
    {
	print " $line \n" ;
	my $out = shift ( @words ) ;
	@{$new_main{"CELL_DATA"}} = @words ; 
    }
# RESOLUTION
    if ( $line =~ m"^RESO" ) 
    {
#	print " $line \n" ;
#	print " RESOLUTIONS WORDS: @words \n" ;
	my $out = shift ( @words ) ;
	if ( $words[0] == 0.0 )
	{
	    $new_main{"RESOLUTION"}[0] = 999.0 ;
	}
	else
	{
	    $new_main{"RESOLUTION"}[0] = sprintf ("%7.2f",  sqrt(1. / $words[0]) ) ;
	}
	$new_main{"RESOLUTION"}[1] = sprintf ("%7.2f",  sqrt(1. / $words[1]) ) ;
	$new_main{"RESOLUTION"}[0] =~ s/ //g ;
	$new_main{"RESOLUTION"}[1] =~ s/ //g ;
#	printf " RESOLUTION: @{$new_main{\"RESOLOLUTION\"}} \n",    ;
    }
# symmetry file info
    if ( $line =~ m"^SYMINF" ) 
    {
#	  print " $line \n" ;
	$out = lc ( $words[5] ) ;
#	  print "MY SPACE GROUP: $out \n" ;
	my @digits = split ('', $out ) ;
	if ( $digits[0] eq "\'" ) 
	{
	    my @dig_breaks = split ('\'', $line ) ;
	    my $dig_out = lc ( $dig_breaks[1] ) ;
	    @digits = split (' ', $dig_out ) ;
	    $out = join ( '_', @digits ) ;
	    $out =~ s/_// ;
#	  $out = join( '.', $out, 'symm' ) ;
#	  print "MY SPACE GROUP: $out - wom work\n" ;
	    
	}
# # OLD     {
# # OLD #	  print " $line \n" ;
# # OLD 	  $out = lc ( $words[5] ) ;
# # OLD #	  print "MY SPACE GROUP: $out \n" ;
# # OLD 	  my @digits = split ('', $out ) ;
	  find ( \&find_space_group, $ENV{"MAIN_SYMM"} ) ;
    if ( !exists( $new_main{"SPACE_GROUP"} ) ) 
    { 
	print "%WARNING: the space group $out not found in MAIN_SYMM\n\n" ;
	@{$new_main{"SPACE_GROUP"}} = ( $out ) ; 
    }
#	  my $CELL_DAT = $my_main{"FILE_CELL"}[0] ;
#	  open ( TXT,  "> $CELL_DAT" ) || print "FILE OPEN ERROR: >$CELL_DAT< \n" ;
#	  print TXT "@words \n" ;
#	  close ( TXT ) ;
    }
# column info
    if ( $line =~ m"^COLUMN" ) 
    {
	  $ICL++ ;
#	  print " $ICL: $line \n" ;

	  if ( $words[2] eq "H" ) { next ; } #push ( @{$column{$words[1]}}, $words[2] ) ; }
	  push ( @{$column{$words[1]}}, $words[2] ) ;
	  if ( length( $new_main{"MTZ_FOBS"}[0]) <= 0 && $words[2] eq "F" )
	  { @{$new_main{"MTZ_FOBS"}} = ( $words[1] ) ; }
 	  if ( length( $new_main{"MTZ_SIGMA"}[0]) <= 0 && $words[2] eq "Q" ) 
 	     { @{$new_main{"MTZ_SIGMA"}} = ( $words[1] )} ;
 	  if ( length( $new_main{"MTZ_PHASE"}[0]) <= 0 && $words[2] eq "P" ) 
 	     { 
		 @{$new_main{"MTZ_PHASE"}} = ( $words[1] ) ;
		 @{$new_main{"INIT_MAP"}} = ( "FOBS" ) ;
	     } 
 	  if ( length( $new_main{"MTZ_WEIGHT"}[0]) <= 0 && $words[2] eq "W" ) 
 	     { @{$new_main{"MTZ_WEIGHT"}} = ( $words[1] )} ;
 	  if ( length( $new_main{"MTZ_HLA"}[0]) <= 0 && $words[2] eq "A" && uc($words[1]) =~ m"HLA" ) 
 	     { @{$new_main{"MTZ_HLA"}} = ( $words[1] )} ;
 	  if ( length( $new_main{"MTZ_HLB"}[0]) <= 0 && $words[2] eq "A" && uc($words[1]) =~ m"HLB" ) 
 	     { @{$new_main{"MTZ_HLB"}} = ( $words[1] )} ;
 	  if ( length( $new_main{"MTZ_HLC"}[0]) <= 0 && $words[2] eq "A" && uc($words[1]) =~ m"HLC" ) 
 	     { @{$new_main{"MTZ_HLC"}} = ( $words[1] )} ;
 	  if ( length( $new_main{"MTZ_HLD"}[0]) <= 0 && $words[2] eq "A" && uc($words[1]) =~ m"HLD" ) 
 	     { @{$new_main{"MTZ_HLD"}} = ( $words[1] )} ;
    }
    if ( $line =~ m"^SYMM" ) 
    {
#	  print " $line \n" ;
	  my $out = shift ( @words ) ;
	  my $rest = join ( " ", @words ) ;
	  push ( @symmetry, $rest ) ;
    }

}

foreach $KEY ( sort keys (%new_main) ) 
{
    my $colkey = $new_main{$KEY}[0] ;
    printf " %20s:   @{$new_main{$KEY}} \n", $KEY ;
    if ( exists ($column{$colkey})){ delete $column{$colkey} ; }
}
print "\n\nUNUSED MTZ FILE COLUMNS:\n" ;
foreach $KEY ( sort keys (%column) ) 
{ printf " %20s:   %s \n", @{$column{$KEY}}, $KEY ; } print "\n" ;



foreach $KEY ( sort keys (%new_main) ) 
{
#    print "$KEY: @{$new_main{$KEY}} \n" ;
    if ( $KEY eq "SPACE_GROUP" )
    {
	@{$my_main{"FILE_SYMM"}} = @{$new_main{"SPACE_GROUP"}} ;
	next ;
    }
    if ( $KEY eq "MTZ_FOBS" )
    { @{$my_main{"MTZ_FOBS"}} = ( @{$new_main{"MTZ_FOBS"}} ) ; 	next ; }
    if ( $KEY eq "MTZ_SIGMA" )
    { @{$my_main{"MTZ_SIGMA"}} = ( @{$new_main{"MTZ_SIGMA"}} ) ; next ; }
    if ( $KEY eq "MTZ_PHASE" )
    { 
	@{$my_main{"MTZ_PHASE"}} = ( @{$new_main{"MTZ_PHASE"}} ) ; 
	@{$my_main{"INIT_MAP"}} = ( @{$new_main{"INIT_MAP"}} ) ; 
	next ; 
    }
    if ( $KEY eq "MTZ_WEIGHT" )
    { @{$my_main{"MTZ_WEIGHT"}} = ( @{$new_main{"MTZ_WEIGHT"}} ) ; next ; }
    if ( $KEY eq "MTZ_HLA" )
    { @{$my_main{"MTZ_HLA"}} = ( @{$new_main{"MTZ_HLA"}} ) ; next ; }
    if ( $KEY eq "MTZ_HLB" )
    { @{$my_main{"MTZ_HLB"}} = ( @{$new_main{"MTZ_HLB"}} ) ; next ; }
    if ( $KEY eq "MTZ_HLC" )
    { @{$my_main{"MTZ_HLC"}} = ( @{$new_main{"MTZ_HLC"}} ) ; next ; }
    if ( $KEY eq "MTZ_HLD" )
    { @{$my_main{"MTZ_HLD"}} = ( @{$new_main{"MTZ_HLD"}} ) ; next ; }
    if ( $KEY eq "RESOLUTION" )
    { 
	@{$my_main{"DFR_RES_MIN"}} = ( $new_main{"RESOLUTION"}[0] ) ;
	@{$my_main{"DFR_RES_MAX"}} = ( $new_main{"RESOLUTION"}[1] ) ;
	next ; 
    }
}

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

$conf_file = "main_config.data" ; 
main_config::write_main_config_file ( $conf_file, %my_main ) ; 

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

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

# print " DOOOOOOOOOOOOOOOOOOOOOOOOOOO IIIIIIIIITTTT\n" ;

# cell data

$KEY =  "CELL_DATA" ;
$FILE = $my_main{"FILE_CELL"}[0] ;
print "creating \"$FILE\"\n" ;
open ( TXT,  "> $FILE" ) || print "FILE OPEN ERROR: >$FILE< \n" ;
printf TXT "%9.3f %9.3f %9.3f %8.2f %8.2f %8.2f\n", 
    @{$new_main{"CELL_DATA"}} ;
close ( TXT ) ;

if ( scalar (@symmetry) > 0 ) 
{
    $FILE = join ( '', $my_main{"FILE_SYMM"}[0], '.symm' ) ;
    print "creating \"$FILE\"\n" ;
    open ( TXT,  "> $FILE" ) || print "FILE OPEN ERROR: >$FILE< \n" ;
    my $ll ;
    foreach $ll ( @symmetry ) 
    {
	print TXT $ll, "\n" ;
    }
    close ( TXT ) ;
}

# create the main_2_mtz files

if ( length ($my_main{"MTZ_PHASE"}[0]) > 0 )
{
    $FILE = "mtz_phase_2_main.com" ;
    print "creating \"$FILE\"\n" ;

    open ( TXT,  "> $FILE" ) || print "FILE OPEN ERROR: >$FILE< \n" ;

if ( length ($my_main{"MTZ_SIGMA"}[0]) > 0 )
{
    print TXT << "END_OF_TEXT" ;
#
# mtz_2_main.ccp4
#
mtz2various HKLIN ${$my_main{"FILE_MTZ"}}[0] HKLOUT ${$my_main{"FILE_REFL"}}[0] << EOF
RESOLUTION $my_main{"DFR_RES_MIN"}[0] $my_main{"DFR_RES_MAX"}[0]
EXCLUDE SIGP 1.0
OUTPUT USER (3HIND, 3I5, 4H FOB, F11.2, 4H SIG, F8.2, 4H PHA, F7.1, 3H WE, F7.3)
LABIN FP=$my_main{"MTZ_FOBS"}[0] SIGFP=$my_main{"MTZ_SIGMA"}[0] PHIB=$my_main{"MTZ_PHASE"}[0] W=$my_main{"MTZ_WEIGHT"}[0]
END
EOF

END_OF_TEXT

}
else
{
    print TXT << "END_OF_TEXT" ;
#
# mtz_2_main.ccp4
#
mtz2various HKLIN ${$my_main{"FILE_MTZ"}}[0] HKLOUT ${$my_main{"FILE_REFL"}}[0] << EOF
RESOLUTION $my_main{"DFR_RES_MIN"}[0] $my_main{"DFR_RES_MAX"}[0]
EXCLUDE SIGP 1.0
OUTPUT USER (3HIND, 3I5, 4H FOB, F11.2, 4H PHA, F7.1, 3H WE, F7.3)
LABIN FP=$my_main{"MTZ_FOBS"}[0] PHIB=$my_main{"MTZ_PHASE"}[0] W=$my_main{"MTZ_WEIGHT"}[0]
END
EOF

END_OF_TEXT

}

    close ( TXT ) ;



}
else  # without phase information
{
    $FILE = "mtz_2_main.com" ;
    print "creating \"$FILE\"\n" ;
    open ( TXT,  "> $FILE" ) || print "FILE OPEN ERROR: >$FILE< \n" ;
    print TXT << "END_OF_TEXT" ;
#
# mtz_2_main.ccp4
#
mtz2various HKLIN ${$my_main{"FILE_MTZ"}}[0] HKLOUT ${$my_main{"FILE_REFL"}}[0] << EOF
RESOLUTION $my_main{"DFR_RES_MIN"}[0] $my_main{"DFR_RES_MAX"}[0]
EXCLUDE SIGP 1.0
OUTPUT USER (3HIND, 3I5, 4H FOB, F11.2, 4H SIG, F8.3 )
LABIN FP=$my_main{"MTZ_FOBS"}[0] SIGFP=$my_main{"MTZ_SIGMA"}[0] 
END
EOF
END_OF_TEXT

    close ( TXT ) ;
}
    print "executing \"$FILE\" > $FILE.log\n" ;
system ( "chmod +x $FILE ; $FILE > $FILE.log" ) ;
exit ;

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

# # OLD ORIG 
# # OLD ORIG sub find_space_group
# # OLD ORIG {
# # OLD ORIG     my $found = "NO" ;
# # OLD ORIG 
# # OLD ORIG     if ( $File::Find::name =~ m"symm" ) 
# # OLD ORIG     { 
# # OLD ORIG 	my $XX = $File::Find::name ; $XX =~ s/_//g ;
# # OLD ORIG #	    print "file: $XX and $out \n" ; 
# # OLD ORIG 	if ( $XX =~ m"$out" ) 
# # OLD ORIG 	{
# # OLD ORIG 	    $found = "YES" ;
# # OLD ORIG 	    my @Y = split ('/', $File::Find::name ) ;
# # OLD ORIG 	    my $GROUP = $Y[scalar(@Y)-1] ;
# # OLD ORIG 	    substr( $GROUP, -5 ) = '' ;
# # OLD ORIG #	    print "comparison: $out $GROUP $File::Find::name \n" ;
# # OLD ORIG 	    if ( $GROUP eq $out )
# # OLD ORIG 	    {
# # OLD ORIG #		print "SUCESS: $out $GROUP $File::Find::name \n" ;
# # OLD ORIG 		@{$new_main{"SPACE_GROUP"}} = ( $GROUP ) ;
# # OLD ORIG 	    }
# # OLD ORIG 	}
# # OLD ORIG     }
# # OLD ORIG #    if ( $found eq "NO" ) 
# # OLD ORIG #    { 
# # OLD ORIG #	print "%WARNING: the space group $out not found in MAIN_SYMM\n\n" ;
# # OLD ORIG #	@{$new_main{"SPACE_GROUP"}} = ( $out ) ; 
# # OLD ORIG #    }
# # OLD ORIG }

sub find_space_group
{
    my $found = "NO" ;

    if ( $File::Find::name =~ m"symm" ) 
    { 
	my $XX = $File::Find::name ; # $XX =~ s/_//g ;
#	    print "file: $XX and $out \n" ; 
	if ( $XX =~ m"$out" ) 
	{
	    $found = "YES" ;
	    my @Y = split ('/', $File::Find::name ) ;
	    my $GROUP = $Y[scalar(@Y)-1] ;
	    substr( $GROUP, -5 ) = '' ;
#	    print "comparison: $out $GROUP $File::Find::name \n" ;
	    if ( $GROUP eq $out )
	    {
#		print "SUCESS: $out $GROUP $File::Find::name \n" ;
		@{$new_main{"SPACE_GROUP"}} = ( $GROUP ) ;
	    }
	}
    }
    if ( $found eq "NO" ) 
    { 
#	print "%WARNING: the space group $out not found in MAIN_SYMM\n\n" ;
	@{$new_main{"SPACE_GROUP"}} = ( $out ) ; 
    }
}
