#!/usr/bin/perl

use strict;
#use warnings;

use lib 'c:/Programs/Perl/lib';
use lib 'd:/Programs/Perl/lib';
use lib "$ENV{TkPerlDir}/lib";

use Utils;
use Sci qw($torad);
use MyApplication;
use Crystal::CIF;
use Crystal::Crystal;

#===============================================
# $B@_DjJQ?t(J
#===============================================
my $OutCIFFileName = "out.cif";

#my $Action = 'shift';
my $Action = 'c-rotation';
#my $Action = 'c-surface';
#my $Action = 'c-superlattice';

# For Action=all
# $BD63J;R$NE83+3J;RHO0O(J
my @nSuperlattice = (
		[1, 1, 1],
		[1, 1, 2],
		);

# For $Action ='shift'
# $B86;R:BI8$N%7%U%H(J
my @Shift = (0.0, 0.0, -1.045617);

# For $Action ='c-extract'
# $B<h$j9~$`(JZ$B:BI8HO0O(J
my @ZRange = (0.0, 1.0);
# $B3J;RDj?t$NJQ2=NL(J
my @ChangeLatticeParameters = (0.0, 0.0, 0.0);

# For $Action ='c-rotation'
# $B86;R:BI8$N2sE>3QEY(J
my $Rotation = 0.0;

# For $Action ='c-surface', 'c-superlattice'
# $BI=LL$N%9%Z!<%9(J
my @Space  = (0.0, 0.0, 10.0);
my @Border = (1.0, 1.0, 1.0);

#===============================================
# Application$B%/%i%9:n@=(J
#===============================================
my $App = new MyApplication;
exit if($App->Initialize() < 0);

my $Program = $App->Program();
$App->SetAppName($Program);
my $Version = $App->SetVersion("Ver 0.1");
my $ProgramPath = $App->SpeculateProgramPath($0);
#$B:G8e$N0z?t$r(J0$B$K$9$k$H!"(JIniFile$B$,B8:_$7$J$/$F$b%(%i!<$,$G$J$$(J
my $IniFile = $App->OpenIniFile($ProgramPath, 0);

$App->AddArgument("--OutputFile",     "--OutputFile: Specify Output CIF FileName");
$App->AddArgument("--Action",         "--Action=[shift|c-rotation|c-extract|c-surface|a-surface|c-superlattice]");
$App->AddArgument("--Rotation",       "--Rotation=val        : Specify rotation angle for Action='c-rotation'");
$App->AddArgument("--Shift",          "--Shift=0.0,0.0,0.0   : Specify shifts in fractional coordinate for Action='shift'");
$App->AddArgument("--ZRange",         "--ZRange=0.0,0.26     : Specify the Z range in fractional coordinate for Action='extract'");
$App->AddArgument("--ChangeLatticeParameters", "--ChangeLatticeParameters=0.0,0.0,0.0: Specify the changes in lattice parameters for Action='c-extract'");
$App->AddArgument("--Space",          "--Space=0.0,0.0,0.0   : Specify spaces in angstrom for Action='c-surface'/'c-superlattice'\n");
$App->AddArgument("--Border",         "--Border=0.0,0.0,0.0  : Specify borders in fractional coordinate for Action='c-surface'/'c-superlattice'");
$App->AddArgument("--ChooseRandomly", "--ChooseRandomly=[0|1]: Choose solid-solution sites");
$App->AddArgument("--help",           "--help: Show this help");
exit 1 if($App->ReadArgs() != 1);
# Ini$B%U%!%$%kFI$_9~$_(J
&ConfigureIniFileVariables();
my %Arg = $App->Args()->GetArgHash();

$App->print("\n");

my @CIFFile;
for(my $i = 0 ; ; $i++) {
	last if(!defined $App->GetGetArg($i));

	$CIFFile[$i] = $App->GetGetArg($i);
	$nSuperlattice[$i] = [1,1,1];
	if($CIFFile[$i] =~ /^(.*):([\d,]+)$/) {
		$CIFFile[$i] = $1;
		my $s = $2;
		my @a = Utils::Split(",", $s);
		$nSuperlattice[$i] = \@a;
	}
$App->print("CIFFile[$i]: $CIFFile[$i] (", join(',', @{$nSuperlattice[$i]}), ")\n");
}
if(defined $Arg{OutputFile}) {
	$OutCIFFileName = $Arg{OutputFile};
	$App->print("OutCIFFileName: $OutCIFFileName\n");
}
if(defined $Arg{Action}) {
	$Action = $Arg{Action};
	$App->print("Action: $Action\n");
}
if(defined $Arg{Rotation}) {
	$Rotation = $Arg{Rotation};
	$App->print("Rotation: $Rotation\n");
}
if(defined $Arg{Shift}) {
	@Shift = &cal(Utils::Split(",", $Arg{Shift}));
	$App->print("Shift: ", join(', ', @Shift), "\n");
}
if(defined $Arg{ZRange}) {
	@ZRange = &cal(Utils::Split(",", $Arg{ZRange}));
	$App->print("ZRange: ", join(', ', @ZRange), "\n");
}
if(defined $Arg{ChangeLatticeParameters}) {
	@ChangeLatticeParameters = &cal(Utils::Split(",", $Arg{ChangeLatticeParameters}));
	$App->print("Space: ", join(', ', @ChangeLatticeParameters), "\n");
}
if(defined $Arg{Space}) {
	@Space = &cal(Utils::Split(",", $Arg{Space}));
	$App->print("Space: ", join(', ', @Space), "\n");
}
if(defined $Arg{Border}) {
	@Border = &cal(Utils::Split(",", $Arg{Border}));
	$App->print("Border: ", join(', ', @Border), "\n");
}
$App->print("\n");

#===============================================
# CIF$B%/%i%9$r:n@.(J
#===============================================
if(!$App->GetGetArg(0)) {
	$App->Usage();
	exit 1;
}

my (@Crystal, @Superlattice);
my (@pa, @pb, @pc, @palpha, @pbeta, @pgamma);
my (@sa, @sb, @sc, @salpha, @sbeta, @sgamma);
for(my $i = 0 ; $i < @CIFFile ; $i++) {
#	last if(!defined $App->GetGetArg($i));

#	$CIFFile[$i]      = $App->GetGetArg($i);
	$Crystal[$i]      = &GetCrystal($CIFFile[$i]);
	$Superlattice[$i] = &GetSuperlatticeCrystal($CIFFile[$i], @{$nSuperlattice[$i]});
	($pa[$i], $pb[$i], $pc[$i], $palpha[$i], $pbeta[$i], $pgamma[$i]) = $Crystal[$i]->LatticeParameters();
	($sa[$i], $sb[$i], $sc[$i], $salpha[$i], $sbeta[$i], $sgamma[$i]) = $Superlattice[$i]->LatticeParameters();

	$App->print("$i: Lattice parameters for [$CIFFile[$i]]:\n");
	$App->print("     $pa[$i], $pb[$i], $pc[$i], $palpha[$i], $pbeta[$i], $pgamma[$i]\n");
	$App->print("     $sa[$i], $sb[$i], $sc[$i], $salpha[$i], $sbeta[$i], $sgamma[$i]\n");
}

#my $cif = &ShowSuperlatticeInformation($CIFFile, $nx, $ny, $nz);

my ($newa, $newb, $newc);

#CartesianToFractional
my $nc = new Crystal();
$nc->SetCrystalName($Crystal[0]->CrystalName());
$nc->SetSampleName($Crystal[0]->SampleName());
#$nc->SetLatticeVector(*$l0, $l12*$l0, $l13*$l0, 
#				   $l21*$l0, $l22*$l0, $l23*$l0, 
#				   $l31*$l0, $l32*$l0, $l33*$l0);
#my ($a, $b, $c, $alpha, $beta, $gamma) = $crystal->CalculateLatticeConstantFromVector();

if($Action =~ /shift/i) {
	my @AtomTypeList = $Superlattice[0]->GetCAtomTypeList();
	for(my $j = 0 ; $j < @AtomTypeList ; $j++) {
		$nc->AddAtomType($AtomTypeList[$j]->AtomNameOnly(), 0);
	}
	$nc->SetLatticeParameters($sa[0], $sb[0], $sc[0], $salpha[0], $sbeta[0], $sgamma[0]);

	my @ExpandedAtomSiteList = sort SortAtomSiteFunc $Superlattice[0]->GetCExpandedAtomSiteList();
	for(my $j = 0 ; $j < @ExpandedAtomSiteList ; $j++) {
		my $label          = $ExpandedAtomSiteList[$j]->Label();
		my $type           = $ExpandedAtomSiteList[$j]->AtomName();
		my ($x,  $y,  $z)  = $ExpandedAtomSiteList[$j]->Position(1);
		my $occupancy      = $ExpandedAtomSiteList[$j]->Occupancy();
#print "$j: $type: ($x, $y, $z) occ=$occupancy\n";

		$x += $Shift[0];
		$y += $Shift[1];
		$z += $Shift[2];
		$nc->AddAtomSite($label, $type, $x, $y, $z, $occupancy);
	}
}
elsif($Action =~ /a-rotation/i) {
	$Rotation *= $torad;
	my $cosQ = cos($Rotation);
	my $sinQ = sin($Rotation);

	my @AtomTypeList = $Superlattice[0]->GetCAtomTypeList();
	for(my $j = 0 ; $j < @AtomTypeList ; $j++) {
		$nc->AddAtomType($AtomTypeList[$j]->AtomNameOnly(), 0);
	}
	$nc->SetLatticeParameters($sa[0], $sc[0], $sb[0], $salpha[0], $sgamma[0], $sbeta[0]);

	my @ExpandedAtomSiteList = sort SortAtomSiteFunc $Superlattice[0]->GetCExpandedAtomSiteList();
	for(my $j = 0 ; $j < @ExpandedAtomSiteList ; $j++) {
		my $label          = $ExpandedAtomSiteList[$j]->Label();
		my $type           = $ExpandedAtomSiteList[$j]->AtomName();
		my ($x,  $y,  $z)  = $ExpandedAtomSiteList[$j]->Position(1);
		my ($rx, $ry, $rz) = $Superlattice[0]->FractionalToCartesian($x, $y, $z);
		my $occupancy      = $ExpandedAtomSiteList[$j]->Occupancy();
	
		my $rx2 = $rx;
		my $ry2 = $ry * $cosQ - $rz * $sinQ;
		my $rz2 = $ry * $sinQ + $rz * $cosQ;
$App->print("$j: ($y,$z) r:($ry,$rz)\n    => r:($ry2,$rz2) ");
		($x, $y, $z) = $Superlattice[0]->CartesianToFractional($rx2, $ry2, $rz2);
$App->print("($x,$y)\n");
		$nc->AddAtomSite($label, $type, $x, $y, $z, $occupancy);
	}
}
elsif($Action =~ /c-rotation/i) {
	$Rotation *= $torad;
	my $cosQ = cos($Rotation);
	my $sinQ = sin($Rotation);

	my @AtomTypeList = $Superlattice[0]->GetCAtomTypeList();
	for(my $j = 0 ; $j < @AtomTypeList ; $j++) {
		$nc->AddAtomType($AtomTypeList[$j]->AtomNameOnly(), 0);
	}
	$nc->SetLatticeParameters($sb[0], $sa[0], $sc[0], $sbeta[0], $salpha[0], $sgamma[0]);

	my @ExpandedAtomSiteList = sort SortAtomSiteFunc $Superlattice[0]->GetCExpandedAtomSiteList();
	for(my $j = 0 ; $j < @ExpandedAtomSiteList ; $j++) {
		my $label          = $ExpandedAtomSiteList[$j]->Label();
		my $type           = $ExpandedAtomSiteList[$j]->AtomName();
		my ($x,  $y,  $z)  = $ExpandedAtomSiteList[$j]->Position(1);
		my ($rx, $ry, $rz) = $Superlattice[0]->FractionalToCartesian($x, $y, $z);
		my $occupancy      = $ExpandedAtomSiteList[$j]->Occupancy();
	
		my $rx2 =  $rx * $cosQ - $ry * $sinQ;
		my $ry2 =  $rx * $sinQ + $ry * $cosQ;
		my $rz2 = $rz;
$App->print("$j: ($x,$y) r:($rx,$ry)\n    => r:($rx2,$ry2) ");
		($x, $y, $z) = $Superlattice[0]->CartesianToFractional($rx2, $ry2, $rz2);
$App->print("($x,$y)\n");
		$nc->AddAtomSite($label, $type, $x, $y, $z, $occupancy);
	}
}
elsif($Action =~ /c-extract/i) {
	my @AtomTypeList = $Superlattice[0]->GetCAtomTypeList();
	for(my $j = 0 ; $j < @AtomTypeList ; $j++) {
		$nc->AddAtomType($AtomTypeList[$j]->AtomNameOnly(), 0);
	}
	$nc->SetLatticeParameters($sa[0]+$ChangeLatticeParameters[0], $sb[0]+$ChangeLatticeParameters[1], $sc[0]+$ChangeLatticeParameters[2], 
								$salpha[0], $sbeta[0], $sgamma[0]);

	my @ExpandedAtomSiteList = sort SortAtomSiteFunc $Superlattice[0]->GetCExpandedAtomSiteList();
	for(my $j = 0 ; $j < @ExpandedAtomSiteList ; $j++) {
		my $label          = $ExpandedAtomSiteList[$j]->Label();
		my $type           = $ExpandedAtomSiteList[$j]->AtomName();
		my ($x,  $y,  $z)  = $ExpandedAtomSiteList[$j]->Position(1);
		my ($rx, $ry, $rz) = $Superlattice[0]->FractionalToCartesian($x, $y, $z);
		my $occupancy      = $ExpandedAtomSiteList[$j]->Occupancy();
		next if($z < $ZRange[0] or $ZRange[1] < $z);

		($x, $y, $z) = $nc->CartesianToFractional($rx, $ry, $rz);
		$nc->AddAtomSite($label, $type, $x, $y, $z, $occupancy);
	}
}
elsif($Action =~ /c-superlattice/i) {
	($newa, $newb, $newc) = ($sa[0], $sb[0], 0.0);
	for(my $i = 0 ; $i < @Superlattice ; $i++) {
		$newc += $sc[$i];
#		$Superlattice[$i]->SetLatticeParameters($sa[0], $sb[0], $sc[$i], $salpha[0], $sbeta[0], $sgamma[0]);
		my @AtomTypeList = $Superlattice[$i]->GetCAtomTypeList();

		for(my $j = 0 ; $j < @AtomTypeList ; $j++) {
			$nc->AddAtomType($AtomTypeList[$j]->AtomNameOnly(), 0);
		}
	}
	$nc->SetLatticeParameters($newa, $newb, $newc, $salpha[0], $sbeta[0], $sgamma[0]);

	my $coffset = 0;
	for(my $i = 0 ; $i < @Superlattice ; $i++) {
		my @ExpandedAtomSiteList = sort SortAtomSiteFunc $Superlattice[$i]->GetCExpandedAtomSiteList();
print "c(offset)=$coffset (c=$newc)\n";
		for(my $j = 0 ; $j < @ExpandedAtomSiteList ; $j++) {
			my $label          = $ExpandedAtomSiteList[$j]->Label();
			my $type           = $ExpandedAtomSiteList[$j]->AtomName();
			my ($x,  $y,  $z)  = $ExpandedAtomSiteList[$j]->Position(1);
			my ($rx, $ry, $rz) = $Superlattice[$i]->FractionalToCartesian($x, $y, $z);
			my $occupancy      = $ExpandedAtomSiteList[$j]->Occupancy();

print "$i:$j [$label] ($x,$y,$z)[$sc[$i] - $newc] - \n";
# $i=0$B$N3J;R$K$D$$$F!"(J$space?$B$G;XDj$7$?6u4V$r(J$boarder?$B$K6u$1$k(J
			if($i == 0) {
				$rx += $newa - $sa[0] if($x > $Border[0]);
				$ry += $newb - $sb[0] if($y > $Border[1]);
				$rz += $newc - $sc[0] if($z > $Border[2]);
			}
			$z = Utils::Reduce01(($rz+$coffset) / $newc);
#print "$z ($rz, $coffset, $newc) ($x,$y,$z)\n";
			$nc->AddAtomSite($label, $type, $x, $y, $z, $occupancy);
		}
		if($Border[2] <= 0 or $Border[2] >= 1) {
			$coffset += $sc[$i];
		}
		else {
			$coffset += $Border[2] * $sc[0];
		}
	}
}
elsif($Action =~ /surface/i) {
	$newa = $sa[0] + $Space[0];
	$newb = $sb[0] + $Space[1];
	$newc = $sc[0] + $Space[2];
print "latt: ($sa[0],$sb[0],$sc[0]) => ($newa, $newb, $newc)\n";
	$nc->SetLatticeParameters($newa, $newb, $newc, $salpha[0], $sbeta[0], $sgamma[0]);

	my @AtomTypeList = $Superlattice[0]->GetCAtomTypeList();
	my @ExpandedAtomSiteList = sort SortAtomSiteFunc $Superlattice[0]->GetCExpandedAtomSiteList();
	for(my $i = 0 ; $i < @AtomTypeList ; $i++) {
		$nc->AddAtomType($AtomTypeList[$i]->AtomNameOnly(), 0);
	}
	for(my $i = 0 ; $i < @ExpandedAtomSiteList ; $i++) {
		my $label          = $ExpandedAtomSiteList[$i]->Label();
		my $type           = $ExpandedAtomSiteList[$i]->AtomName();
		my ($x,  $y,  $z)  = $ExpandedAtomSiteList[$i]->Position(1);
		my ($rx, $ry, $rz) = $Crystal[0]->FractionalToCartesian($x, $y, $z);
#		my ($rx, $ry, $rz) = $Superlattice[0]->FractionalToCartesian($x, $y, $z);
		my $occupancy      = $ExpandedAtomSiteList[$i]->Occupancy();

		$rx += $Space[0] if($x > $Border[0]);
		$ry += $Space[1] if($y > $Border[1]);
		$rz += $Space[2] if($z > $Border[2]);
		my $x2 = Utils::Reduce01($rx / $newa);
		my $y2 = Utils::Reduce01($ry / $newb);
		my $z2 = Utils::Reduce01($rz / $newc);
#		my ($x2, $y2, $z2) = $Superlattice[0]->CartesianToFractional($rx, $ry, $rz);
		$nc->AddAtomSite($label, $type, $x2, $y2, $z2, $occupancy);
		print "$label: ($x,$y,$z) => ($x2, $y2,$z2)\n";
	}
}
else {
	$App->print("\nError: Invalid Action [$Action]\n");
	exit;
}

$nc->ExpandCoordinates();
my $newCIF = new CIF;
$newCIF->CreateCIFFileFromCCrystal($nc, $OutCIFFileName, $Arg{ChooseRandomly});
#CIFObject->WriteSimpleCIFFile($NewFile, $WritePublication, $strCRLF);

print("\nPress ENTER to terminate>> ");
<STDIN>;
exit 0;

#===============================================
# $B%9%/%j%W%H=*N;(J
#===============================================

#==========================================
# $B%5%V%k!<%A%s(J
#==========================================
sub SortAtomSiteFunc
{
	my ($ax, $ay, $az) = $a->Position(1);
	my ($bx, $by, $bz) = $b->Position(1);
	my $alabel = $a->Label();
	my $blabel = $b->Label();
	return $az <=> $bz or $alabel cmp $blabel;
}

sub GetSuperlatticeCrystal
{
	my ($CIFFile, $nx, $ny, $nz) = @_;

	my $cif = new CIF;
	unless($cif->Read($CIFFile)) {
		$App->print("Error: Can not read [$CIFFile]\n\n");
		return undef;
	}
	my $Crystal = $cif->GetCCrystal();
	$Crystal->ExpandCoordinates();
	$Crystal->CreateSuperLattice($nx,$ny,$nz);
	my $SuperLattice = $Crystal->GetCSuperLattice();

	return $SuperLattice;
}

sub GetCrystal
{
	my ($CIFFile) = @_;

	my $cif = new CIF;
	unless($cif->Read($CIFFile)) {
		$App->print("Error: Can not read [$CIFFile]\n\n");
		return undef;
	}
	my $Crystal = $cif->GetCCrystal();
	$Crystal->ExpandCoordinates();

	return $Crystal;
}

sub ShowSuperlatticeInformation
{
	my ($CIFFile, $nx,$ny,$nz) = @_;

#CIF$B%/%i%9$r<hF@(J
	my $cif = new CIF;
#CIF$B%U%!%$%kL>$r0z?t$KM?$($FFI$_9~$`(J
	unless($cif->Read($CIFFile)) {
		$App->print("Error: Can not read [$CIFFile]\n\n");
		return undef;
	}
	$App->print("CIF: ", $cif->FileName(), "\n");

#CIF$B%/%i%9$NFbMF$+$i!"(JCrystal$B%/%i%9$r:n@.(J
#$B:n@.$7$?;~E@$G!"(JMetrics$B$N7W;;!"%$%*%s>pJs(J($B86;RNL$J$I(J)$B$NFI$_9~$_!"(J
#$B3J;RBN@Q$N7W;;$O=*$o$C$F$$$k(J
	my $Crystal = $cif->GetCCrystal();

	print "\n";
	my $CrystalName = $Crystal->CrystalName();
	print "CrystalName: $CrystalName\n";
	my ($a,$b,$c,$alpha,$beta,$gamma) = $Crystal->LatticeParameters();
	print "cell: $a $b $c  $alpha $beta $gamma\n";
	my ($g11,$g12,$g13,$g21,$g22,$g23,$g31,$g32,$g33) = $Crystal->Metrics();
	print "Metrics: $g11 $g22 $g33  $g12 $g23 $g31\n";
	my $vol = $Crystal->Volume();
	print "Volume: $vol A^3\n";
#$BBP>NMWAG$r;H$$!"HsBP>NC10LCf$N86;R$rE83+$9$k(J
#$B$3$N:]!"(JDensity$B$b7W;;$5$l$k(J
	$Crystal->ExpandCoordinates();
	my $Density = $Crystal->Density();
	print "Density: $Density g/cm^3\n";

	print "\n";
#Crystal$B%/%i%9$+$i!"(JSpaceGroup$B%/%i%9$r<h$j=P$9(J
#$B$3$N;~E@$G!"JB?JBP>NMWAG$NCj=P!"(JLatticeSystem$B$NCj=P$O40N;$7$F$$$k(J
	my $SPG = $Crystal->GetCSpaceGroup();
	my $SPGName = $SPG->SPGName();
	my $iSPG    = $SPG->iSPG();
	my $LatticeSystem = $SPG->LatticeSystem();
	print "Space Group: $SPGName ($iSPG)\n";
	print "Lattice System: $LatticeSystem\n";

	print "\n";
	my $nTranslation = $SPG->nTranslation();
	print "nTranslation: $nTranslation\n";
	for(my $i = 0 ; $i < $nTranslation ; $i++) {
		my ($x,$y,$z) = $SPG->TranslationVector($i+1);
		print "   ($x, $y, $z)\n";
	}

	print "\n";
	my $nSymmetryOperation = $SPG->nSymmetryOperation();
	print "nSymmetryOperation: $nSymmetryOperation\n";
	for(my $i = 0 ; $i < $nSymmetryOperation ; $i++) {
		my $symop = $SPG->SymmetryOperation($i+1);
		print "   $symop\n";
	
		my ($x1,$y1,$z1,$t1,
			$x2,$y2,$z2,$t2,
			$x3,$y3,$z3,$t3)
			= $SPG->SymmetryOperationByMatrix($i+1);
		print "      $x1 $y1 $z1  $t1\n";
		print "      $x2 $y2 $z2  $t2\n";
		print "      $x3 $y3 $z3  $t3\n";
	}

	print "\n";
#Crystal$B%/%i%9Cf$N!"86;R$N<oN`(J AtomType$B%/%i%9$N%j%9%H$r$H$k(J
	my @AtomTypeList = $Crystal->GetCAtomTypeList();
	my $nAtomType = @AtomTypeList;
	print "nAtomType: $nAtomType\n";
	for(my $i = 0 ; $i < $nAtomType ; $i++) {
		my $label        = $AtomTypeList[$i]->Label();
		my $atomname     = $AtomTypeList[$i]->AtomName();
		my $charge       = $AtomTypeList[$i]->Charge();
		my $AtomicNumber = $AtomTypeList[$i]->AtomicNumber();
		my $AtomicMass   = $AtomTypeList[$i]->AtomicMass();
		my $i1 = $i+1;
		print "   #$i1: $label : $atomname [$AtomicNumber] ($charge) "
			."($AtomicMass)\n";
	}

	print "\n";
#Crystal$B%/%i%9Cf$N!"HsBP>NC10LCf$N86;R(J AsymmetricAtomSite$B%/%i%9$N%j%9%H$r$H$k(J
	my @AtomSiteList = $Crystal->GetCAsymmetricAtomSiteList();
	my $nAsymmetricAtomSite = @AtomSiteList;
	print "nAsymmetricAtomSite: $nAsymmetricAtomSite\n";
	for(my $i = 0 ; $i < $nAsymmetricAtomSite ; $i++) {
		my $label     = $AtomSiteList[$i]->Label();
		my $type      = $AtomSiteList[$i]->AtomName();
		my ($x,$y,$z) = $AtomSiteList[$i]->Position(1);
		my $occupancy = $AtomSiteList[$i]->Occupancy();
		my $iAtomType = $Crystal->FindiAtomType($type);

		print "   $label ($type)[#$iAtomType]: ($x, $y, $z) [$occupancy]\n";
	}

	print "\n";
	my @ExpandedAtomSiteList = $Crystal->GetCExpandedAtomSiteList();
	my $nTotalExpandedAtomSite = $Crystal->nTotalExpandedAtomSite();
	my @nMultiplicityExpandedAtomSiteList 
		= $Crystal->GetCnMultiplicityExpandedAtomSiteList();
	print "nTotalExpandedAtomSite: $nTotalExpandedAtomSite\n";
	for(my $i = 0 ; $i < $nTotalExpandedAtomSite ; $i++) {
		my $label     = $ExpandedAtomSiteList[$i]->Label();
		my $type      = $ExpandedAtomSiteList[$i]->AtomName();
		my ($x,$y,$z) = $ExpandedAtomSiteList[$i]->Position(1);
		my $occupancy = $ExpandedAtomSiteList[$i]->Occupancy();
		my $id = $ExpandedAtomSiteList[$i]->IdAsymmetricAtomSite();
		my $mult = $nMultiplicityExpandedAtomSiteList[$id-1];
		my $i1 = $i+1;
		print "   $i1: [$id]$label ($type): ($x, $y, $z) [$occupancy][$mult]\n";
	}

	print "\n";

#$Crystal$B$r$b$H$K!"D63J;R$N7k>=3J;R(J$SuperLattice$B$r:n$k(J
	$Crystal->CreateSuperLattice($nx,$ny,$nz);
	my $SuperLattice = $Crystal->GetCSuperLattice();

	print "\n";
	print "SuplaerLattice $nx x $ny x $nz\n";
	my ($a,$b,$c,$alpha,$beta,$gamma) = $SuperLattice->LatticeParameters();
	print "Cell: $a $b $c  $alpha $beta $gamma\n";

	my @ExpandedAtomSiteList = $SuperLattice->GetCExpandedAtomSiteList();
	my $nTotalExpandedAtomSite = $SuperLattice->nTotalExpandedAtomSite();
	my @nMultiplicityExpandedAtomSiteList 
		= $SuperLattice->GetCnMultiplicityExpandedAtomSiteList();
	print "nTotalExpandedAtomSite: $nTotalExpandedAtomSite\n";
	for(my $i = 0 ; $i < $nTotalExpandedAtomSite ; $i++) {
		my $label     = $ExpandedAtomSiteList[$i]->Label();
		my $type      = $ExpandedAtomSiteList[$i]->AtomName();
		my ($x,$y,$z) = $ExpandedAtomSiteList[$i]->Position(1);
		my $occupancy = $ExpandedAtomSiteList[$i]->Occupancy();
		my $id = $ExpandedAtomSiteList[$i]->IdAsymmetricAtomSite();
		my $mult = $nMultiplicityExpandedAtomSiteList[$id-1];
		my $i1 = $i+1;
		print "   $i1: [$id]$label ($type): ($x, $y, $z) [$occupancy][$mult]\n";
	}
	
	return $cif;
}

sub cal
{
	my @a = @_;
	for(my $i = 0 ; $i < @a ; $i++) {
		$a[$i] = eval($a[$i]);
	}
	return @a;
}

sub ConfigureIniFileVariables
{
	$App->AddIniFileVariable("\\Preferences\\WorkDir",        "WorkDir");
	$App->ReadSetting();
}
