#!/usr/bin/perl

BEGIN {
#use lib 'd:/Programs/Perl/lib';
#use lib '/home/tkamiya/bin/lib';
my $BaseDir = $ENV{'TkPerlDir'};
#print "\nBaseDir: $BaseDir\n";
@INC = ("$BaseDir/lib", "$BaseDir/VNL", "d:/Programs/Perl/lib", @INC);
}

use strict;
#use warnings;
use File::Path;
use File::Basename;
use File::Find;

use Math::Matrix;
use Math::MatrixReal;

use Deps;
use Utils;
use JFile;

use MyApplication;
use Sci::Algorism;
use Sci::GeneralFileFormat;

use Crystal::CIF;
use Crystal::Crystal;
use Crystal::SpaceGroup;
use Crystal::AtomType;
use Crystal::VASP;
use Crystal::VESTA;
use Crystal::XCrySDen;

#===============================================
# デバッグ関係変数
#===============================================
#$PrintLevelが大きいほど、情報が詳しくなる
my $PrintLevel = 0;

#===============================================
# 文字コード関係変数
#===============================================
# sjis, euc, jis, noconv
my $PrintCharCode      = Deps::PrintCharCode();
my $OSCharCode         = Deps::OSCharCode();
my $FileSystemCharCode = Deps::FileSystemCharCode();

my $LF        = Deps::LF();
my $DirSep    = Deps::DirSep();
my $RegDirSep = Deps::RegDirSep();

#===============================================
# Applicationオブジェクト作成
#===============================================
my $App = new MyApplication;
exit if($App->Initialize() < 0);

#$App->SetLF("<br>\n");
#$App->SetPrintCharCode("sjis");
#$App->SetDebug($Debug);
$App->SetDeleteHTMLFlag(1);

#===============================================
# スクリプト大域変数
#===============================================
my $InitialDirectory = Deps::GetWorkingDirectory();
my %ParamHash;

#==========================================
# コマンドラインオプション読み込み
#==========================================
$App->AddArgument("--Action", "--Action=[MergePositionsInCIFs]", '');
#$App->AddArgument("--Positions", "--Positions=[indexes;]",       "");
exit 1 if($App->ReadArgs(1, "sjis", 0) != 1);
my $Args = $App->Args();
#my $form = new CGI;
#$Args->SetCGIForm($form);
#$Args->parseInput($WebCharCode);

my %ArgHash = $Args->GetArgHash();
foreach my $key (keys %ArgHash) {
#print "key: [$key]: $ArgHash{$key}\n";
	if($key =~ /^Param:(.*?)$/i) {
		$ParamHash{$1} = $ArgHash{$key};
#print "$1:  $ArgHash{$key}\n";
	}
}
$App->{pParamHash} = \%ParamHash;

#==========================================
# メイン関数スタート
#==========================================

#Utils::InitHTML("Research", $WebCharSet, "_self");

my $ret = &MergePositionsInCIFs();

#Utils::EndHTML();

exit $ret;

#===============================================
# スクリプト終了
#===============================================

#==========================================
# &Subroutines
#==========================================
sub MergePositionsInCIFs
{
	$App->print("\n\n<b>Merge Positions from CIF Files:</b>\n");

	my $VASP = new VASP;

	my $CARDir    = $Args->GetGetArg(0);
	my $CIFFile   = $Args->GetGetArg(1);
	$CIFFile      = $VASP->GetFileNameFromSystemName($CARDir, ".cif") if(!defined $CIFFile);
	my $Positions = $Args->GetGetArg("Positions");

	unless($CIFFile) {
		$App->print("File names should be specified.\n");
		$App->print("   Usage: MergePositionsInCIFs.pl --Positions=[indxe1;indxe2] CARDir CIFFile\n");
		return 0;
	}

$App->print("CAR dir: [$CARDir]\n");
$App->print("Output CIF file: [$CIFFile]\n");

	if(!defined $Positions) {
		$App->print("Positions should be specified.\n");
		$App->print("   Usage: MergePositionsInCIFs.pl --Positions=[indxe1;indxe2] CARDir CIFFile\n");
		return 0;
	}

	my @iPos = Utils::Split('\s*;\s*', $Positions);
$App->print("Positions=", join('/', @iPos), "\n");

	$App->print("  Read from [$CARDir].\n");
	$App->print("  Save to $CIFFile.\n");

	my $Crystal = $VASP->ReadStructureFromCARFiles($CARDir);
	unless($Crystal) {
		$App->print("Error: Can not read from [$CARDir].\n");
		return 0;
	}

	my @f = glob('*'); #Utils::Glob('*.*');
	for(my $i = 0 ; $i < @f ; $i++) {
		my $dir = $f[$i];
		next if(!-d $dir);
		
		my $SCFDir = Utils::MakePath($dir, 'SCF', '/', 0);
		next if(!-d $SCFDir);

		$App->print("  $i: Read CIF from [$SCFDir].\n");
		my $Crystal2 = $VASP->ReadStructureFromCARFiles($SCFDir);
		unless($Crystal2) {
			$App->print("    Warning: Can not read from [$SCFDir].\n");
			next;
		}

		for(my $j = 0 ; $j < @iPos ; $j++) {
			my $is = $iPos[$j];
#print "get $is\n";
			my $atom = $Crystal2->GetCAtomSite($is);
			if($atom) {
				my $name = $atom->AtomNameOnly();
				my ($x, $y, $z) = $atom->Position(1);
				$App->print("    Add [$name] at ($x, $y, $z)\n");
				$Crystal->AddAtomSite($name, $name, $x, $y, $z, 1.0);
			}
		}
	}

	my $CIF = new CIF;
	$CIF->CreateCIFFileFromCCrystal($Crystal, $CIFFile, 0, 'unix');

	$App->print("\nMerge Positions from CIF Files: Finished\n");

	return 1;
}

sub ConvCONTCARFiles
{
	$App->print("\n\n<b>Make CIF Files from VASP POSCAR.initial/POSCAR Files:</b>\n");

	my $VASP = new VASP;

	my $CARDir  = $Args->GetGetArg(0);
	unless($CARDir) {
		$App->print("Directory should be specified.\n");
		$App->print("   Usage: VASP.pl --Action=ConvCONTCARFiles CAR_Dir\n");
		return 0;
	}
	my $POSCAR  = $VASP->GetPOSCARFileName($CARDir) . ".initial";
	if(!-f $POSCAR) {
		$POSCAR  = $VASP->GetPOSCARFileName($CARDir);
	}
	my $CONTCAR  = $VASP->GetCONTCARFileName($CARDir);
	my $CIFFile = $VASP->GetFileNameFromSystemName($CARDir, ".cif");
	my ($drive, $directory, $filename, $ext1, $lastdir, $filebody) = Deps::SplitFilePath($CIFFile);
	my $InitialCIFFile = Deps::MakePath("$drive$directory", "${filebody}-initial.cif", 0);
	my $FinalCIFFile   = Deps::MakePath("$drive$directory", "${filebody}-final.cif", 0);

	$App->print("  Read from [$CARDir].\n");
	$App->print("  Initial strcuture from [$POSCAR].\n");
	$App->print("    Save to [$InitialCIFFile].\n");
	$App->print("  Final strcuture from [$CONTCAR].\n");
	$App->print("    Save to [$FinalCIFFile].\n");

	my $Crystal = $VASP->ReadStructureFromCARFiles($CARDir, 1, POSCARPath => $POSCAR);
	unless($Crystal) {
		$App->print("Error: Can not read from [$CARDir, $POSCAR].\n");
		return 0;
	}
	my $CIF = new CIF;
	if($CIF->CreateCIFFileFromCCrystal($Crystal, $InitialCIFFile, 0, 'unix')) {
		$App->print("CIF File [$InitialCIFFile] was created.\n");
	}
	else {
		$App->print("Error: Could not create [$InitialCIFFile].\n");
	}

	$Crystal = $VASP->ReadStructureFromCARFiles($CARDir, 1, POSCARPath => $CONTCAR);
	unless($Crystal) {
		$App->print("Error: Can not read from [$CARDir, $CONTCAR].\n");
		return 0;
	}
	if($CIF->CreateCIFFileFromCCrystal($Crystal, $FinalCIFFile, 0, 'unix')) {
		$App->print("CIF File [$FinalCIFFile] was created.\n");
	}
	else {
		$App->print("Error: Could not create [$FinalCIFFile].\n");
	}

	$App->print("\nMake CIF Files from VASP POSCAR.initial/POSCAR Files: Finished\n");

	return 1;
}

1;
