#!/usr/bin/env perl
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"}}, "" ) ;

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

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

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 '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 
  -o|--output)  set file name of the created macro [$MACRO_FILE]
  -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 ;
OUTPUT: $MACRO_FILE = shift ( @{$commands{$keyword}} ) ; next ;
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\" \n" ;
open ( MTZ,  "< $MTZ_FILE" ) || die "FILE OPEN ERROR: >$MTZ_FILE< \n" ;

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

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

my @base = split ( 'DCVERS 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"}} = join ( ' ', @words ) ; 
    }
# symmetry file info
    if ( $line =~ m"^SYMINF" ) 
    {
#	  print " $line \n" ;
	  $out = lc ( $words[5] ) ;
#	  print "$out\n" ;
	  my @digits = split ('', $out ) ;
	  find ( \&find_space_group, $ENV{"MAIN_SYMM"} ) ;
#	  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] ne "H" ) { push ( @{$column{$words[1]}}, $words[2] ) ; }
#	  push ( @{$column{$words[1]}}{"NN"}, $ICL ) ;
	  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] )} ;
 	  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:   %s \n", $KEY, @{$new_main{$KEY}} ;
    if ( exists ($column{$colkey})){ delete $column{$colkey} ; }
}
print "\n\nUNUSED MTZ FILE COLUMNS:\n" ;
foreach $KEY ( sort keys (%column) ) 
{ print "$KEY: @{$column{$KEY}} \n" ; } print "\n" ;



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

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

print " DOOOOOOOOOOOOOOOOOOOOOOOOOOO IIIIIIIIITTTT\n" ;

foreach $KEY ( sort keys (%new_main) ) 
{
#    print "$KEY: @{$new_main{$KEY}} \n" ;
    if ( $KEY eq "CELL_DATA" )
    {
	my $CELL_FILE = $my_main{"FILE_CELL"}[0] ;
	open ( TXT,  "> $CELL_FILE" ) || print "FILE OPEN ERROR: >$CELL_FILE< \n" ;
	print TXT @{$new_main{"CELL_DATA"}}, "\n" ;
	close ( TXT ) ;
	next ;
    }

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



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

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

# create the main_2_mtz files

if ( length ($my_main{"MTZ_PHASE"}[0]) > 0 )
{
    $FILE = "mtz_phase_2_main.com" ;
    open ( TXT,  "> $FILE" ) || print "FILE OPEN ERROR: >$FILE< \n" ;
    print TXT << "END_OF_TEXT" ;
#
# mtz_2_main.ccp4
#
mtz2various HKLIN my.mtz HKLOUT my.phase << EOF
RESOLUTION 25.0 2.9
EXCLUDE SIGP 1.0
OUTPUT USER (3HIND, 3I4, 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

    close ( TXT ) ;
}
else  # without phase information
{
    $FILE = "mtz_2_main.com" ;
    open ( TXT,  "> $FILE" ) || print "FILE OPEN ERROR: >$FILE< \n" ;
    print TXT << "END_OF_TEXT" ;
#
# mtz_2_main.ccp4
#
mtz2various HKLIN x1.mtz HKLOUT x1.fobs << EOF
RESOLUTION 20.0 2.0
EXCLUDE SIGP 1.0
OUTPUT USER (3HIND, 3I4, 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 ) ;
}

exit ;

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


sub find_space_group
{
    if ( $File::Find::name =~ m"symm" ) 
    { 
	my $XX = $File::Find::name ; $XX =~ s/_//g ;
#	    print "file: $XX\n" ; 
	if ( $XX =~ m"$out" ) 
	{
	    my @Y = split ('/', $File::Find::name ) ;
	    my $GROUP = $Y[scalar(@Y)-1] ;
	    substr( $GROUP, -5 ) = '' ;
#	    print "comparison: $out $GROUP $File::Find::name \n" ;
	    @{$new_main{"SPACE_GROUP"}} = ( $GROUP ) ;
	}
    }
}
