#!/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 @SPACE_GROUP = () ;
my @words ;
my $ICL = 0 ;
my $FILE ;

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

if ( !exists( $my_main{"FILE_SCA"} ) ) { push ( @{$my_main{"FILE_SCA"}}, "diffract.sca" )} ;
if ( !exists( $my_main{"FILE_SCA_NUMB"} ) ) { @{$my_main{"FILE_SCA_NUMB"}} = (0)} ;
if ( !exists( $my_main{"REFL_TEST_FRACT"} ) ) { push ( @{$my_main{"REFL_TEST_FRACT"}}, 20 )} ;
if ( !exists( $my_main{"REFL_RAND"} ) ) { push ( @{$my_main{"REFL_RAND"}}, "OFF" )} ;
if ( !exists( $my_main{"REFL_RAND_SIGMA"} ) ) { push ( @{$my_main{"REFL_RAND_SIGMA"}}, 1.0 )} ;
if ( !exists( $my_main{"REFL_RAND_FRACT"} ) ) { push ( @{$my_main{"REFL_RAND_FRACT"}}, 0.5 )} ;

my $KEY ;
foreach $KEY ( %my_main )
{
    if ($KEY =~ m"MTZ_" ) { @{$my_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 'f' || substr($keyword, 0,4) eq "file" ) { goto FILE }
    if ( $keyword eq 'n' || substr($keyword, 0,6) eq "number" ) { goto NUMBER }
    if ( $keyword eq 'r' || substr($keyword, 0,9) eq "randomize" ) { goto RANDOMIZE }
    if ( $keyword eq 'o' || substr($keyword, 0,6) eq "output" ) { goto OUTPUT }
    if ( $keyword eq 'c' || substr($keyword, 0,8) eq "fraction" ) { goto FRACTION }
    if ( $keyword eq 's' || substr($keyword, 0,5) eq "sigma" ) { goto SIGMA }
    if ( $keyword eq 't' || substr($keyword, 0,4) eq "test" ) { goto TEST }
    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
  -f|--file)       scalepack input file [$my_main{"FILE_SCA"}[0]]
  -n|--number)     scalepack output file [$my_main{"FILE_SCA_NUMB"}[0]]
  -o|--output)     outout file for MAIN [$my_main{"FILE_REFL"}[0]]
  -r|--randomize)  randomize [ON/OFF] [$my_main{"REFL_RAND"}[0]]
  -s|--sigma)      randomize interval in I/sigma [$my_main{"REFL_RAND_SIGMA"}[0]]
  -c|--fraction)   randomize fraction of reflections [$my_main{"REFL_RAND_FRACT"}[0]]
  -t|--test)       TEST flag label fraction from the sca file [$my_main{"REFL_TEST_FRACT"}[0]]
     --doit)       save extracted data in "main_config.data" 
                   write cell constants and symmetry operators file
END_OF_TEXT
    exit ;
FILE: @{$my_main{"FILE_SCA"}} = shift ( @{$commands{$keyword}} ) ; next ;
NUMBER: @{$my_main{"FILE_SCA_NUMB"}} = shift ( @{$commands{$keyword}} ) ; next ;
OUTPUT: @{$my_main{"FILE_REFL"}} = shift ( @{$commands{$keyword}} ) ; next ;
RANDOMIZE: @{$my_main{"REFL_RAND"}} = shift ( @{$commands{$keyword}} ) ; next ;
SIGMA: @{$my_main{"REFL_RAND_SIGMA"}} = shift ( @{$commands{$keyword}} ) ; next ;
FRACTION: @{$my_main{"REFL_RAND_FRACT"}} = shift ( @{$commands{$keyword}} ) ; next ;
TEST: @{$my_main{"REFL_TEST_FRACT"}} = shift ( @{$commands{$keyword}} ) ; next ;
}

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

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

my $SCA_FILE = $my_main{"FILE_SCA"}[0] ;
print "reading scalepack file \"$SCA_FILE\" \n" ;

open ( SCAPCK,  "< $SCA_FILE" ) || die "FILE OPEN ERROR: >$SCA_FILE< \n" ;
# binmode(SCAPCK); 

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

# $x = length($record); printf ( "$x \n");
my @whole_file = () ;
@whole_file = ( <SCAPCK> ) ;
my $line ;
my $nc ;

$line = $whole_file[0] ;
$nc = length($line) ;
$line = $whole_file[1] ;
$nc = length($line) ;
#
# cell constants and space group line
#

$line = $whole_file[2] ;
$nc = length($line) ;
#print $nc, ">", $line ;
@words = split ( " ", $line ) ;

my $out ;
$out = lc ( $words[6] ) ;
my @digits = split ('', $out ) ;
my @axis = ()  ;
@SPACE_GROUP = shift ( @digits ) ; 
my $nn = scalar ( @digits ) ; $nn-- ;
print "MY SPACE GROUP: $out $nn \n" ;
my $II ;
push ( @SPACE_GROUP, $digits[0] ) ;

my $last = 1 ;
print " nn test:", $nn, ">", $digits[0], "|", $digits[1], "<",  @SPACE_GROUP, "\n" ;
if ( $nn == 1 ) 
{
    if ( $digits[0] < $digits[1] ) { push ( @SPACE_GROUP, '_' ) ; }
    push ( @SPACE_GROUP, $digits[1] ) ;
print " nn == 1:", $nn, ">", $digits[0], "|", $digits[1], "<",  @SPACE_GROUP, "\n" ;
}
elsif ( $nn == 2 ) 
{
    if (  $digits[1] != 1 ) { push ( @SPACE_GROUP, '_' ) ; }
    push ( @SPACE_GROUP, $digits[1] ) ;
    push ( @SPACE_GROUP, '_' ) ;
    push ( @SPACE_GROUP, $digits[2] ) ;
print " nn == 2:", $nn, ">", $digits[0], "|", $digits[1], "<",  @SPACE_GROUP, "\n" ;
}
elsif ( $nn == 3 && $digits[0] > $digits[1] ) 
{
    push ( @SPACE_GROUP, $digits[1] ) ;
    push ( @SPACE_GROUP, '_' ) ;
    push ( @SPACE_GROUP, $digits[2] ) ;
    push ( @SPACE_GROUP, '_' ) ;
    push ( @SPACE_GROUP, $digits[3] ) ;
print " nn == 3:", $nn, ">", $digits[0], "|", $digits[1], "<",  @SPACE_GROUP, "\n" ;
}
else
{
    for( $II=1; $II<$nn; $II++ )
    {
	push ( @SPACE_GROUP, $digits[$II] ) ;
	if ( $digits[$II] <= $digits[$II+1] || $digits[$II] == 1 ) 
	{ 
	    print $II, " new [$last] \n" ; 
	    push ( @SPACE_GROUP, "_" ) ; $last = 0 
	}
	else { $last++ ; }
	if ($last > 1 ) { push ( @SPACE_GROUP, "_" ) ; $last = 0 }
	
	print $II, ' last', $last, '> ',  $digits[$II], ' - ', $digits[$II+1], "\n" ; 
    }
    print " nn == else:", $nn, ">", $digits[0], "|", $digits[1], "<",  @SPACE_GROUP, "\n" ;
#    push ( @SPACE_GROUP, $digits[$nn] ) ;
}
$out = join( "", @SPACE_GROUP ) ;
print "use_sca.pl thinks this is the space group: $out \n" ;
 @{$my_main{"FILE_SYMM"}} = $out ;    
 @{$my_main{"DFR_FORMAT"}} = "MAIN" ;    


find ( \&find_space_group, $ENV{"MAIN_SYMM"} ) ;
if ( !exists( $my_main{"SPACE_GROUP"} ) ) 
{ 
    print "%WARNING: the space group $out not found in MAIN_SYMM\n\n" ;
    @{$my_main{"SPACE_GROUP"}} = ( $out ) ; 
}


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

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

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

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

if ( $my_main{"REFL_RAND"}[0] eq "OFF" )
{ &write_sca_to_main_refl_file() ; }
else
{ &write_sca_file_randomized () ; }

exit ;



sub write_sca_to_main_refl_file
{
# 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", @words ;
close ( TXT ) ;

my $A = $words[0] ;
my $B = $words[1] ;
my $C = $words[2] ;
my $AL = $words[3] ;
my $BE = $words[4] ;
my $GA = $words[5] ;

my $RAND_FRACT = $my_main{"REFL_TEST_FRACT"}[0] ;

$KEY =  "CELL_DATA" ;
$FILE = $my_main{"FILE_REFL"}[0] ;
print "creating diffraction data \"$FILE\"\n" ;
open ( TXT,  "> $FILE" ) || print "FILE OPEN ERROR: >$FILE< \n" ;
my $TEST ;
my $fobs ;
$AL = $AL / 180. * 3.1415 ;
$BE = $BE / 180. * 3.1415 ;
$GA = $GA / 180. * 3.1415 ;
my $COAL = cos ( $AL ) ;
my $COBE = cos ( $BE ) ;
my $COGA = cos ( $GA ) ;
my $SIAL=sqrt(1. - $COAL*$COAL ) ;
my $SIBE=sqrt(1. - $COBE*$COBE ) ;
my $SIGA=sqrt(1. - $COGA*$COGA ) ;
my $VOL=$A*$B*$C*sqrt(1.-$COAL**2-$COBE**2-$COGA**2+2.*$COAL*$COBE*$COGA) ;

my $COALST=($COBE*$COGA-$COAL) / ($SIBE*$SIGA) ;
my $SIALST=sqrt(1. - $COALST*$COALST ) ;
my @tr ;

$tr[0] = 1 ;
$tr[1] = $COGA ;
$tr[2] = $COBE ;
$tr[3] = 0. ;
$tr[4] = $SIGA ;
$tr[5] = - $SIBE * $COALST ;
$tr[6] = 0. ;
$tr[7] = 0. ;
$tr[8] = $SIBE * $SIALST ;

my @aort ;
my @bort ;
my @cort ;
my @arep ;
my @brep ;
my @crep ;
# make the real space cell vectors
$aort[0] = $A*$tr[0] ; $aort[1] = $A*$tr[3] ; $aort[2] = $A*$tr[6] ; 
$bort[0] = $B*$tr[1] ; $bort[1] = $B*$tr[4] ; $bort[2] = $B*$tr[7] ;
$cort[0] = $C*$tr[2] ; $cort[1] = $C*$tr[5] ; $cort[2] = $C*$tr[8] ;

# print "AORT: ", @aort, "\n" ;
# print "BORT: ", @bort, "\n" ;
# print "CORT: ", @cort, "\n" ;
$VOL = 1.0 / $VOL ;
# make the reciprocal cell vectors
@crep = main_config::vec_prod( @aort, @bort ) ; @crep = main_config::sc_prod ( @crep,  $VOL ) ;
@arep = main_config::vec_prod( @bort, @cort ) ; @arep = main_config::sc_prod ( @arep,  $VOL ) ;
@brep = main_config::vec_prod( @cort, @aort ) ; @brep = main_config::sc_prod ( @brep,  $VOL ) ;

# $line= join ( " x ", @arep ) ; 
# print "AREP: ",  $line, "\n" ;
# $line= join ( " x ", @brep ) ;
# print "BREP: ",  $line, "\n" ;
# $line= join ( " x ", @crep ) ;
# print "CREP: ", $line, "\n" ;
my $rmin = -9999999.0 ;
my $rmax = 9999999.0 ;
$II = 3 ;
while ( $II < scalar ( @whole_file ) )
{
    $line = $whole_file[$II] ;  chomp ( $line ) ;
    $words[0] = substr($line, 0,4) ; 
    $words[1] = substr($line, 4,4) ; 
    $words[2] = substr($line, 8,4) ; 
    $words[3] = substr($line, 12,8) ; 
    $words[4] = substr($line, 20,8) ; 

#    @words = split ( " ", $line ) ;
    $TEST = int (rand $RAND_FRACT) ;
    if ( $TEST != 1 ) { $TEST = 0 ; }

    my ( $rh, $rk, $rl, $dh2 ) ;
    $rh = $words[0] ;
    $rk = $words[1] ;
    $rl = $words[2] ;
    my @t = () ;

    $t[0] = $arep[0] * $rh + $brep[0] * $rk + $crep[0] * $rl ;
    $t[1] = $arep[1] * $rh + $brep[1] * $rk + $crep[1] * $rl ;
    $t[2] = $arep[2] * $rh + $brep[2] * $rk + $crep[2] * $rl ;
    $dh2 = sqrt ( $t[0]*$t[0] + $t[1]*$t[1] + $t[2]*$t[2]  ) ;
    $dh2 = 1.0 / $dh2 ;
    if ( $dh2 < $rmax ) { $rmax = $dh2 } ;
    if ( $dh2 > $rmin ) { $rmin = $dh2 } ;
#    print $II, '>', $line , " res:", 1./$dh2, "\n" ;

    $fobs = $words[3] ; 
    if ($fobs <= 0. ) { 
	print $II, '>', $line , " res:", 1. / $dh2, "\n" ;
	$fobs = 0.0 ; 
	$II++; 
	next 
    } 
    else { 
	$fobs = sqrt($fobs); 
    }
#    printf "IND %5d %5d %5d FOBS %11.3f SIG %8.3f TEST %3d res: %8.3f\n", 
#    $rh, $rk, $rl, $fobs, $words[4]*0.5, $TEST, 1./$dh2 ;
    printf TXT "IND %4d %4d %4d FOBS %10.3f SIG %8.3f TEST %2d\n", 
    $rh, $rk, $rl, $fobs, $words[4]*0.5/$fobs, $TEST ;
    $II++;
}
close ( TXT ) ;
$my_main{"DFR_RES_MIN"}[0] = int(100*$rmin) / 100. ;
$my_main{"DFR_RES_MAX"}[0] = int(100*$rmax) / 100. ;

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

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


}

sub write_sca_file_randomized 
{

#   2   0   0  242.89    3.68
    my @name = split (/\./, $my_main{"FILE_SCA"}[0] ) ;
    my $numb = $my_main{"FILE_SCA_NUMB"}[0] ;
    print "name ", $#name, " ", $my_main{"FILE_SCA"}[0], " - @name -\n" ;
    my $ext = pop( @name ) ;

    my $SCA_FILE = join( "", @name, "_", $numb, ".", $ext ) ;


    print " SCA FILE:> $SCA_FILE<\n" ;
    srand( $numb ) ;
    open ( TXT,  "> $SCA_FILE" ) || print "FILE OPEN ERROR: >$FILE< \n" ;
    
#
# cell constants and space group line
#
    print TXT $whole_file[0] ;
    print TXT $whole_file[1] ;
    print TXT $whole_file[2] ;

    $II = 3 ;
    my $rand_fract =  $my_main{"REFL_RAND_FRACT"}[0] ;
    my $rand_sigma = $my_main{"REFL_RAND_SIGMA"}[0] * 2 ;
    while ( $II < scalar ( @whole_file ) )
    {
	$line = $whole_file[$II] ;  chomp ( $line ) ;
	@words = split ( " ", $line ) ;
	my ( $rh, $rk, $rl, $iobs, $sigma ) ;
	$rh = $words[0] ;
	$rk = $words[1] ;
	$rl = $words[2] ;
	$iobs = $words[3] ;
	$sigma = $words[4] ;
	if ( $rand_fract > 0 )
	{
	    my $xx = rand( 1.0) ;
	    if ( $xx <= $rand_fract ) 
	    { $iobs = $iobs + (rand(1.0)-0.5) * $sigma * $rand_sigma ; }
	    
	}
#    print $II, '>', $line , " res:", 1./$dh2, "\n" ;
	

#    printf "IND %5d %5d %5d FOBS %11.3f SIG %8.3f TEST %3d res: %8.3f\n", 
#    $rh, $rk, $rl, $fobs, $words[4]*0.5, $TEST, 1./$dh2 ;
	printf TXT "%4d%4d%4d %10.4f %8.3f\n", $rh, $rk, $rl, $iobs, $sigma ;
	$II++;
    }
    
    
    close (TXT) ;

}


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




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" ;
		@{$my_main{"SPACE_GROUP"}} = ( $GROUP ) ;
	    }
	}
    }
    if ( $found eq "NO" ) 
    { 
#	print "%WARNING: the space group $out not found in MAIN_SYMM\n\n" ;
	@{$my_main{"SPACE_GROUP"}} = ( $out ) ; 
    }
}


