#!/usr/bin/perl

BEGIN {
#use lib 'd:/Programs/Perl/lib';
#use lib '/home/tkamiya/bin/lib';
my $BaseDir = $ENV{'TkPerlDir'};
print "\n\nBaseDir: $BaseDir\n";
@INC = ("$BaseDir/lib", "$BaseDir/VNL", @INC);
}

use strict;
#use warnings;

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::TranSIESTA;

#===============================================
# デバッグ関係変数
#===============================================
#$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();

#==========================================
# コマンドラインオプション読み込み
#==========================================
$App->AddArgument("--Action",
		"--Action=[MakeATK|MakeCIF]",       '');
$App->AddArgument("--Version", "--Version=[Ver11|Ver20] (Def:Ver20)", "Ver20");
$App->AddArgument("--ElectrodeSpacing", "--ElectrodeSpacing=Value (Def:0.0)", 0.0);
$App->AddArgument("--Function", "--Function=[SCF|Relaxation] (Def:SCF)", "SCF");
$App->AddArgument("--BasisSet", "--BasisSet=[SZ|DZ|SZP|DZP|DZDP] (Def:DZP)", "DZP");
$App->AddArgument("--XCFunctional", 
	"--XCFunctional=[LDA-PZ|LSDA-PZ|GGA-PBE|SGGA-PBE] (Def:GGA-PBE)", "GGA-PBE");
$App->AddArgument("--InitialSpin", "--InitialSpin=Value (Def:0.5)", 0.5);
$App->AddArgument("--DebugMode", "--DebugMode: Set DebugMode", '');
exit 1 if($App->ReadArgs(0) != 1);
my $Args = $App->Args();
#my $form = new CGI;
#$Args->SetCGIForm($form);
#$Args->parseInput($WebCharCode);

#==========================================
# メイン関数スタート
#==========================================

#Utils::InitHTML("Research", $WebCharSet, "_self");

my $Debug = $Args->GetGetArg("DebugMode");
$App->SetDebug($Debug);
my $Action = $Args->GetGetArg("Action");

my $ret = 0;
if($Action =~ /MakeATK/i) {
	&MakeATK();
}
elsif($Action =~ /MakeCIF/i) {
	&MakeCIFFile();
}
else {
	$App->print("Error: Invald Action: $Action\n");
}

#Utils::EndHTML();

exit $ret;

#===============================================
# スクリプト終了
#===============================================

#==========================================
# &Subroutines
#==========================================
sub MakeATK
{
	$App->print("\n\n<b>Make VNL .atk Files from CIF File:</b>\n");

	my $Function = $Args->GetGetArg("Function");
	my $BasisSet = $Args->GetGetArg("BasisSet");
	my $XCFunctional = $Args->GetGetArg("XCFunctional");
	my $InitialSpin  = $Args->GetGetArg("InitialSpin");
	my $Version      = $Args->GetGetArg("Version");
	my $CIFFile = $Args->GetGetArg(0);
	my $AtkFile = $Args->GetGetArg(1);
	unless($AtkFile) {
		$App->print("File names should be specified.\n");
		$App->print("   Usage: VNL.pl --Action=MakeATK CIFFile AtkFile\n");
		return 0;
	}

	$App->print("  Version: $Version\n");
	$App->print("  Function: $Function\n");
	$App->print("  BasisSet: $BasisSet\n");
	$App->print("  XCFunctional: $XCFunctional\n");
	$App->print("  InitialSpin : $InitialSpin\n");
	$App->print("  Read $CIFFile.\n");
	$App->print("  Save to $AtkFile.\n");

	my ($drive, $dir, $filename, $ext, $lastdir, $filebody)
		= Deps::SplitFilePath($CIFFile);

	my $CIF = new CIF();
	unless($CIF->Read($CIFFile)) {
		$App->print("  Error: Can not read [$CIFFile].\n\n");
		return -1;
	}
	my $Crystal = $CIF->GetCCrystal();
	$Crystal->ExpandCoordinates();

	my $SIESTA = new TranSIESTA();
	$SIESTA->SetSampleName($filebody);
	unless($SIESTA->SaveTranSIESTAATKFile(
			$Crystal, $AtkFile, $Function, $BasisSet, $Version,
			$XCFunctional, $InitialSpin, 0)) {
		$App->print("  Error: Can not write to [$AtkFile].\n\n");
		return -1;
	}

	$App->print("\n<b>Make VNL .atk Files from CIF File: Finished</b>\n");
}

sub MakeCIFFile
{
	$App->print("\n\n<b>Make CIF Files from VNL .atk File:</b>\n");

	my $AtkFile = $Args->GetGetArg(0);
	my $CIFFile = $Args->GetGetArg(1);
	unless($CIFFile) {
		$App->print("File names should be specified.\n");
		$App->print("   Usage: VNL.pl --Action=MakeCIF AtkFile CIFFile\n");
		return 0;
	}

	$App->print("  Read $AtkFile.\n");
	$App->print("  Save to $CIFFile.\n");

	my $ElectrodeSpacing = $Args->GetGetArg("ElectrodeSpacing");

	my $VNL = new TranSIESTA;
	my ($Crystal, $LCrystal, $RCrystal) = $VNL->ReadATKFile($AtkFile, $ElectrodeSpacing);
	unless($Crystal) {
		$App->print("Error: Can not read [$AtkFile].\n");
		return 0;
	}

	my $CIF = new CIF;
	$CIF->CreateCIFFileFromCCrystal($Crystal, $CIFFile, 0, 'unix');

	my $LCIFFile = Deps::ReplaceExtension($CIFFile, ".left.cif");
	my $RCIFFile = Deps::ReplaceExtension($CIFFile, ".right.cif");
	if($LCrystal) {
		$CIF->CreateCIFFileFromCCrystal($LCrystal, $LCIFFile, 0, 'unix');
	}
	if($RCrystal) {
		$CIF->CreateCIFFileFromCCrystal($RCrystal, $RCIFFile, 0, 'unix');
	}

	$App->print("\nMake CIF Files from VNL Struct File: Finished\n");

	return 1;
}
