#!/usr/bin/perl
##!d:/Perl/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 CGI::Carp qw(fatalsToBrowser);
use Cwd;

use Deps;
use Utils;
use MyHTMLApplication;
use Crystal::VASP;
use Sci::ChemicalReaction;

BEGIN {
#	$| = 1;
	open (STDERR, ">&STDOUT");
}

#===============================================
# 大域変数
#===============================================
my $ScriptCharCode = 'utf8';
my $FileSystemCharCode = 'sjis';

my $OutFile = "TotalEnergy.csv";
$OutFile = $ARGV[0] if(defined $ARGV[0]);
my $Target = ($ARGV[1] eq '')? '' : $ARGV[1];

#===============================================
# Applicationオブジェクト作成
#===============================================
my $App = new MyHTMLApplication;
my $ret = $App->Initialize();
exit(-1) if($ret < 0);

$App->SetOutputMode("console");

#my $DOSDir = "I:/Functional/Si/Si-HF/DOS";
#my ($EF, $VBM, $CBM, $Eg) = &ReadFromDOSOUTCAR(Deps::MakePath($DOSDir, 'OUTCAR', 0));
#print "$EF, $VBM, $CBM, $Eg\n";
#exit;

my $nLevel = 3;
my @Dirs;
#my @Dirs = sort { $a cmp $b; } glob("*");
@Dirs = Utils::SearchFilesRecursive2(".", "*", $nLevel, \@Dirs, 1,
			sub { 
				my ($path) = @_; 
#				print "path: $path\n"; 
				my $p = Deps::MakePath($path, "SCF", 0);
				if(-d $p) {
#print("p=[$p] is registered\n");
					return 1;
				}
			},
			);
#exit;
print("\n");
print("Directories to search...\n");
for(my $i= 0 ; $i < @Dirs ; $i++) {
	print("  $i: $Dirs[$i]\n");
}
#exit;

my $R = new ChemicalReaction;

my $out = new JFile;
if(!$out->Open($OutFile, "w")) {
	$App->print("Error: Can not write to [$OutFile].\n");
	exit;
}
$out->print("Source,Compound,SortedComposition/Z,Composition,Type,"
		   ."Z,"
		   ."GGA,METAGGA,LHFCALC,AEXX,AGGAC,ALDAC,HFSCREEN,"
		   ."Etot,Emol,EF(SCF),"
		   ."EF(DOS),EVBM,ECBM,Eg,"
		   ."Density,a,b,c,V,"
		   ."PP,"
		   ."PREC,aK(SCF),aK(VCRelax),EDIFF,EDIFFG,NBANDS,"
		   ."ISPIN,NUPDOWN,LDAU,U,J,"
		   ."ISMEAR,SIGMA,"   ."Status,Ref\n");

print("\nMakeSummaryHTML\n");
for(my $i = 0 ; $i < @Dirs ; $i++) {
	print("Try [$Dirs[$i]]\n");

	next if(!-d $Dirs[$i]);
	next if($Dirs[$i] =~ /junk/i);
	
	my $SCFDir = Deps::MakePath($Dirs[$i], "SCF", 0);
	next if(!-d $SCFDir);

	$App->print("\n$i: $Dirs[$i]\n");
	my $ret = &MakeVASPSummary($App, $out, $Dirs[$i]);
}

$out->Close();

exit;

#===============================================
# Subroutines
#===============================================
sub MakeVASPSummary
{
	my ($App, $out, $RootDir) = @_;

	my ($drive, $directory, $filename, $ext1, $lastdir, $filebody) = Deps::SplitFilePath($RootDir);

	my $VCRelaxDir = Deps::MakePath($RootDir, "VCRelax", 0);
	my $SCFDir     = Deps::MakePath($RootDir, "SCF", 0);
	my $DOSDir     = Deps::MakePath($RootDir, "DOS", 0);

	my $vasp = new VASP;
	my $INCARHash          = $vasp->ReadINCARtoHash(Utils::MakePath($SCFDir, 'INCAR', '/', 0));
	my $KPOINTSHash        = $vasp->ReadKPOINTStoHash(Utils::MakePath($SCFDir, 'KPOINTS', '/', 0));
	my $VCRelaxKPOINTSHash = $vasp->ReadKPOINTStoHash(Utils::MakePath($VCRelaxDir, 'KPOINTS', '/', 0));
	my $POTCARHash         = $vasp->ReadPOTCARtoHash(Utils::MakePath($SCFDir, 'POTCAR', '/', 0));
	my $POSCARHash         = $vasp->ReadPOSCARtoHash(Utils::MakePath($SCFDir, 'POSCAR', '/', 0));
	my $SCFOUTCARHash      = $vasp->ReadOUTCARtoHash(Utils::MakePath($SCFDir, 'OUTCAR', '/', 0));
	my $VCROUTCARHash      = $vasp->ReadOUTCARtoHash(Utils::MakePath($VCRelaxDir, 'OUTCAR', '/', 0));

	my $Status = '';
	if(-d $VCRelaxDir and $VCROUTCARHash->{RequiredAccuracyMessage} =~ /^\s*$/) {
		$Status = 'Relaxation not converged(1)';
	}
	elsif(-d $VCRelaxDir and $VCROUTCARHash->{AbortMessage} !~ /is\s+reached/) {
		$Status = 'Relaxation not converged(2)';
	}
	elsif(-d $VCRelaxDir and $VCROUTCARHash->{TotCPUTime} eq '') {
		$Status = 'VCR aborted(1)';
	}
	elsif($SCFOUTCARHash->{AbortMessage} =~ /^\s*$/) {
		$Status = 'SCF not converged(1)';
	}
	elsif($SCFOUTCARHash->{TotCPUTime} eq '') {
		$Status = 'SCF aborted(1)';
	}
	my ($EF, $VBM, $CBM, $Eg) = VASP->new()->ReadEgFromDOSOUTCAR(Deps::MakePath($DOSDir, 'OUTCAR', 0));

	$App->print("GGA=$INCARHash->{GGA}\n");
	$App->print("METAGGA=$INCARHash->{METAGGA}\n");
	$App->print("LHFCALC=$INCARHash->{LHFCALC}\n");
	$App->print("AEXX=$INCARHash->{AEXX}\n");
	$App->print("AGGAC=$INCARHash->{AGGAC}\n");
	$App->print("ALDAC=$INCARHash->{ALDAC}\n");
	$App->print("HFSCREEN=$INCARHash->{HFSCREEN}\n");
	$App->print("ISPIN=$INCARHash->{ISPIN}\n");
	$App->print("PREC=$INCARHash->{PREC}\n");
	$App->print("EDIFF=$INCARHash->{EDIFF}\n");
	$App->print("EDIFFG=$INCARHash->{EDIFFG}\n");
	$App->print("LDAU=$INCARHash->{LDAU}\n");
	$App->print("LDAUTYPE=$INCARHash->{LDAUTYPE}\n");
	$App->print("LDAUU=$INCARHash->{LDAUU}\n");
	$App->print("LDAUJ=$INCARHash->{LDAUJ}\n");
	$App->print("ISMEAR=$INCARHash->{ISMEAR}\n");
	$App->print("SIGMA=$INCARHash->{SIGMA}\n");
	$POTCARHash->{PseudoPotential} =~ s/ .*$//s;
	$App->print("PseudoPotential=$POTCARHash->{PseudoPotential}\n");

	$VCRelaxKPOINTSHash->{KPOINTS} =~ s/^[^\n]*\n[^\n]*\n[^\n]*\n//m;
	$VCRelaxKPOINTSHash->{KPOINTS} =~ s/\n.*$//m;
	Utils::DelSpace($VCRelaxKPOINTSHash->{KPOINTS});
	my @nKVCRelax = Utils::Split("\\s+", $VCRelaxKPOINTSHash->{KPOINTS});

	$KPOINTSHash->{KPOINTS} =~ s/^[^\n]*\n[^\n]*\n[^\n]*\n//m;
	$KPOINTSHash->{KPOINTS} =~ s/\n.*$//m;
	Utils::DelSpace($KPOINTSHash->{KPOINTS});
	my @nK = Utils::Split("\\s+", $KPOINTSHash->{KPOINTS});

	$App->print("KPOINTS=$KPOINTSHash->{KPOINTS}\n");
	$App->print("ISPIN=$INCARHash->{ISPIN}\n");
	$App->print("Etot=$SCFOUTCARHash->{TOTEN}\n");
	$App->print("EF(SCF)=$SCFOUTCARHash->{EF}\n");
	$App->print("EF(DOS)=$EF\n");
	$App->print("EVBM(DOS)=$VBM\n");
	$App->print("ECBM(DOS)=$CBM\n");
	$App->print("Eg(DOS)=$Eg\n");
	$App->print("SumChemicalComposition=$POSCARHash->{SumChemicalComposition}\n");
	$App->print("ChemicalComposition=$POSCARHash->{ChemicalComposition}\n");
	$App->print("FormulaUnit=$POSCARHash->{FormulaUnit}\n");

	$POSCARHash->{Latt} =~ s/\n/,/g;
	my @latt = Utils::Split(",+", $POSCARHash->{Latt});

	my @aKVCRelax = ($latt[0]*$nKVCRelax[0], $latt[1]*$nKVCRelax[1], $latt[2]*$nKVCRelax[2]);
	my ($aKminVCRelax, $aKmaxVCRelax) = Utils::CalMinMax(\@aKVCRelax);
	$aKminVCRelax = sprintf("%4.1f", $aKminVCRelax);

	my @aK = ($latt[0]*$nK[0], $latt[1]*$nK[1], $latt[2]*$nK[2]);
	my ($aKmin, $aKmax) = Utils::CalMinMax(\@aK);
	$aKmin = sprintf("%4.1f", $aKmin);

	$App->print("Latt=$POSCARHash->{Latt}\n");
	$App->print("aKMax=$aKmin-$aKmax\n");
	$App->print("Volume=$POSCARHash->{Volume}\n");
	$App->print("Density=$POSCARHash->{Density}\n");

	my $Ref = Deps::MakePath(cwd(), $RootDir, 0);
	$Ref =~ s/$ENV{HOME}//;
	my $Eavrg = $SCFOUTCARHash->{TOTEN} / $POSCARHash->{FormulaUnit};
	my $Compound = $POSCARHash->{ChemicalComposition};
#	my $Compuond = $POSCARHash->{SumChemicalComposition};
	my $SortedComposition = $R->SortChemicalFormula($POSCARHash->{ChemicalComposition});
	$Compound =~ s/\s//g;
	$Status .= " / SCFWarning:$SCFOUTCARHash->{Warning}" if($SCFOUTCARHash->{Warning} ne '');
	$Status .= " / VCRWarning:$VCROUTCARHash->{Warning}" if($VCROUTCARHash->{Warning} ne '');

	my $GGA = $INCARHash->{GGA};
	my $METAGGA = $INCARHash->{METAGGA};
	my $LHFCALC = $INCARHash->{LHFCALC};
	my $AEXX = $INCARHash->{AEXX};
	my $AGGAC = $INCARHash->{AGGAC};
	my $ALDAC = $INCARHash->{ALDAC};
	my $HFSCREEN = $INCARHash->{HFSCREEN};

	$out->print("$filebody,$Compound,$SortedComposition,$POSCARHash->{SumChemicalComposition},,"
			   ."$POSCARHash->{FormulaUnit},"
			   ."$GGA,$METAGGA,$LHFCALC,$AEXX,$AGGAC,$ALDAC,$HFSCREEN,"
			   ."$SCFOUTCARHash->{TOTEN},$Eavrg,$SCFOUTCARHash->{EF},"
			   ."$EF,$VBM,$CBM,$Eg,"
			   ."$POSCARHash->{Density},$latt[0],$latt[1],$latt[2],$POSCARHash->{Volume},"
			   ."$POTCARHash->{PseudoPotential},"
			   ."$INCARHash->{PREC},$aKmin,$aKminVCRelax,$INCARHash->{EDIFF},$INCARHash->{EDIFFG},"
			   ."$INCARHash->{NBANDS},"
			   ."$INCARHash->{ISPIN},$INCARHash->{NUPDOWN},$INCARHash->{LDAU},$INCARHash->{LDAUU},$INCARHash->{LDAUJ},"
			   ."$INCARHash->{ISMEAR},$INCARHash->{SIGMA},"
			   ."$Status,$Ref\n");

	return 1;
}
