#!/usr/bin/perl

use lib 'd:/Programs/Perl/lib';
use lib 'c:/Programs/Perl/lib';
#use lib 'd:/MyWebs/cgi-bin/lib';

use lib '/home/tkamiya/bin/lib';
use lib '/home/tkamiya/bin';

use Utils;
use ProgVars;
use MyApplication;
use Crystal::CIF;
use Crystal::Crystal;
use Crystal::AtomType;

use strict;
#use warnings;


my $ProgramDir      = ProgVars::ProgramDir(); #"d:\\Programs";
my $BinDir          = ProgVars::BinDir();
my $DBDir           = ProgVars::PeriodicTableDir();

my $NonrelInputPath           = Deps::MakePath($DBDir, "nonrel",                      0);
my $IonRadius1DBPath          = Deps::MakePath($DBDir, "IonRadius1.html",             0);
my $IonRadius2DBPath          = Deps::MakePath($DBDir, "IonRadius2.html",             0);
my $PeriodicTable1DBPath      = Deps::MakePath($DBDir, "PeriodicTable1.html",         0);
my $PeriodicTable2DBDir       = Deps::MakePath($DBDir, "PeriodicTable2",              0);
my $PeriodicTable3DB          = Deps::MakePath($DBDir, "PERIODIC.CSV",                0);
my $ElectronicConfigurationDB = Deps::MakePath($DBDir, "ElectronicConfiguration.csv", 0);

my $MXDDir     = ProgVars::MXDDir();
my $MXDExecDir = ProgVars::MXDExecDir();
my $SX1DBPath  = ProgVars::SX1DBPath();

my $LF = "\n";

my $OutputDBDir    = Deps::MakePath($DBDir, 'atoms', 0);
my $OutputCharCode = 'utf-8';

my $in = JFile->new($NonrelInputPath, 'r') or die "$!";
for(my $i = 1 ; ; $i++) {
# H  HFS ATOM CALC.
#    1  300    1
#   1.00000   0.97804  20.00000  32.00000   0.00000
#  1.0  0.0  0.0   -0.30       1.0
	my $line1 = $in->ReadLine();  #    1  300    1
	last if(!$line1);

	my ($atomname) = ($line1 =~ /^\s*(.*?)\s/);
	$atomname = ucfirst lc $atomname;
	last if($atomname eq '');

	my $DBPath = Deps::MakePath($OutputDBDir, sprintf("%03d-%s.ini", $i, $atomname), 0);
	print("i=$i: $atomname  saved to [$DBPath]\n");

	my ($patomdb, $pmaterialdb, $pbusingdb) = &GetAtomDBHash($atomname, 0);
	my $out = JFile->new($DBPath, 'w', $OutputCharCode) or die $!;
	$out->print("[Atom]\n");
	foreach my $key (sort keys %$patomdb) {
		print("  $key: $patomdb->{$key}\n");
		if($key eq 'pIonRadius') {
			my $p = $patomdb->{$key};
			my $val = join(',', @$p);
#			$out->print("$key=$val\n");
			}
		else {
			$out->print("$key=$patomdb->{$key}\n");
		}
	}
	$out->print("\n");
	$out->print("[Busing]\n");
	foreach my $key (sort keys %$pbusingdb) {
		print("  $key: $pbusingdb->{$key}\n");
		$out->print("$key=$pbusingdb->{$key}\n");
	}
	$out->print("\n");
	$out->print("[Material]\n");
	foreach my $key (sort keys %$pmaterialdb) {
		print("  $key: $pmaterialdb->{$key}\n");
		$out->print("$key=$pmaterialdb->{$key}\n");
	}
	$out->Close();

	while(1) {
		my $line2 = $in->ReadLine();     #   1.00000   0.97804  20.00000
		last if(!$line2 or Utils::DelSpace($line2) eq '');
	}
}
$in->Close();

exit;

sub GetAtomicNumber 
{
	my ($name, $Debug) = (@_);

	$name =~ s/\{.*?\}//g;
	$name =~ s/\d//g;
	$name = uc $name;
	$name =~ s/^(\D+?)\d.*$/$1/;
	my $an = -1;
	unless(open(IN, "<$NonrelInputPath")) {
		print "Error: $!: $NonrelInputPath${LF}";# if($Debug);
		return -1;
	}

	while(<IN>) {
# H  HFS ATOM CALC.
#    1  300    1
#   1.00000   0.97804  20.00000  32.00000   0.00000
#  1.0  0.0  0.0   -0.30       1.0
  		if($_ =~ /^\s*$name\s/) { # H  HFS ATOM CALC.
			my $line = <IN>;  #    1  300    1
			$line = <IN>;     #   1.00000   0.97804  20.00000
			($an) = ($line =~ /^\s*(.*?)\s/);
			last;
		}
	}
	close(IN);
	return $an;
}


sub GetAtomDBHash {
	my ($element, $charge, $nCoordination) = @_;
	$charge = 0 if(!defined $charge);

	if($element =~ /^\d+$/) {
		$element = AtomType::GetAtomName($element);
	}

	my ($mass, $charge0, $ai, $bi, $ci, $rad) = AtomType::GetBusingParameter($element);
	my ($AtmNum, $JName, $EName, $NameOrigin) = AtomType::GetIonInfFromPeriodicTable1($element);
	my ($AtomicNumber, $AtomName, $Charge)    = AtomType::GetAtomInformation($element);
	my $CationRadius = AtomType::GetCationRadius($element, $charge, $nCoordination);
	my @IonRadius    = AtomType::GetIonRadius2($element, $charge, $nCoordination);
	my ($filepath, $AtomJName, $AtomEName,
		$AtomicMass, $FoundYear, $AtomicRadius,
		$MeltingPoint, $BoilingPoint, $Density,
		$HeatCapacity, $IonizationPotential, $ElectronAffinity) = AtomType::GetIonInfFromPeriodicTable2($AtmNum);
	my $NameOrigin2;
	($AtmNum, $JName, $EName, $NameOrigin2) = AtomType::GetIonInfFromPeriodicTable1($element);
	my ($pOrbitalName1, $pnElectron1)       = AtomType::GetElectronicConfiguraton($AtmNum);
	my ($pOrbitalName2, $pnElectron2)       = AtomType::SpeculateElectronicConfiguration($AtmNum);
	my $ElectronConfiguration1 = '';
	my $ElectronConfiguration2 = '';
	if($pOrbitalName1) {
		for(my $i = 0 ; $i < @$pOrbitalName1 ; $i++) {
			next if($pnElectron1->[$i] == 0);
			$ElectronConfiguration1 .= "$pOrbitalName1->[$i]($pnElectron1->[$i])";
		}
		for(my $i = 0 ; $i < @$pOrbitalName2 ; $i++) {
			next if($pnElectron2->[$i] == 0);
			$ElectronConfiguration2 .= "$pOrbitalName2->[$i]($pnElectron2->[$i])";
		}
	}
#print "  $ElectronConfiguration1\n";
#print "  $ElectronConfiguration2\n";

	$AtomicMass = $mass        if(!defined $AtomicMass);
	$JName      = $AtomJName   if(!defined $JName);
	$EName      = $AtomEName   if(!defined $EName);
	$NameOrigin = $NameOrigin2 if(!defined $NameOrigin);

	my %atomdb = (
		name                   => $element,
		Z                      => $AtmNum,
		mass                   => $AtomicMass,
		charge                 => $charge,
#		nCoordination          => $nCoordination,
		AtomicRadius           => $AtomicRadius,
#		CationRadius           => $CationRadius,
		pIonRadius             => \@IonRadius,
		ElectronConfiguration1 => $ElectronConfiguration1,
		ElectronConfiguration2 => $ElectronConfiguration2,
		JName                  => $JName,
		EName                  => $EName,
		NameOrigin             => $NameOrigin,
		NameOrigin2 => $NameOrigin2,
		FoundYear              => $FoundYear,
		);

	my %materialdb = (
		IonizationPotential    => $IonizationPotential,
		ElectronAffinity       => $ElectronAffinity,
		MeltingPoint           => $MeltingPoint,
		BoilingPoint           => $BoilingPoint,
		Density                => $Density,
		HeatCapacity           => $HeatCapacity,
		);

	my %busingdb = (
		ai                     => $ai,
		bi                     => $bi,
		ci                     => $ci,
		rad => $rad,
		charge => $charge0,
		);

	return \%atomdb, \%materialdb, \%busingdb;
}

