#!/usr/bin/perl

use lib 'd:/Programs/Perl/lib';

BEGIN {
#use lib 'd:/Programs/Perl/lib';
#use lib '/home/tkamiya/bin/lib';
my $BaseDir = $ENV{'PerlDir'};
$BaseDir = $ENV{'TkPerlDir'} unless(defined $BaseDir);
print "BaseDir: $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 CSV;
use Sci::Science;
use Sci::Algorism;
use Optics;

#===============================================
# デバッグ関係変数
#===============================================
#$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 $nDivide = 1;
my $ExtraporateLow  = "Drude";
#my $ExtraporateLow  = "None";
my $ExtraporateHigh = "Constant";
#my $ExtraporateHigh = "None";
#my $Integrator = "Rectangular";
my $Integrator = "Simpson";

#==========================================
# コマンドラインオプション読み込み
#==========================================
#$App->AddArgument("--Action", "--Action=[Convolute]",       '');
$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;

&Execute();

#if($Action =~ /Convolute/i) {
#	&Convolute();
#}
#else {
#	$App->print("Error: Invald Action: $Action\n");
#}

#Utils::EndHTML();

exit $ret;

#===============================================
# スクリプト終了
#===============================================

#==========================================
# &Subroutines
#==========================================
sub Execute
{
	my $h  = Sci::h();
	my $e  = Sci::e();
	my $pi = Sci::pi();

	my $InputFile  = $Args->GetGetArg(0);
	$InputFile = "Au.asp.csv" if(!defined $InputFile);
	my $OutputFile = $Args->GetGetArg(1);
	if(!defined $OutputFile or $InputFile eq $OutputFile) {
		$OutputFile = Deps::ReplaceExtension($InputFile, "KK.csv");
	}

	$App->print("  Input file : $InputFile\n");
	$App->print("  Output file: $OutputFile\n");
	$App->print("  ExtraporateLow : $ExtraporateLow\n");
	$App->print("  ExtraporateHigh: $ExtraporateHigh\n");
	$App->print("  Integrator     : $Integrator\n");

	my $csv = new CSV;
	if($csv->Read($InputFile)) {
		$App->print("  Read [$InputFile]\n");
	}
	else {
		$App->print("  Error!!: Can not read [$InputFile]\n");
		return -1;
	}

	my $pLabelArray = $csv->LabelArray();
	my $pDataArray  = $csv->DataArray();
	my $nDataRow = @$pDataArray;
	my $pX       = $pDataArray->[0];
	my $nData = @$pX;
	$App->print("  nDataRow: $nDataRow\n");
	$App->print("  nData   : $nData\n");
	my $x0 = $pX->[0];
	my $x1 = $pX->[@$pX - 1];
	my $dx = $pX->[1] - $pX->[0];
	$App->print("  x: $x0 - $x1     dx: $dx\n");
#	for(my $i = 0 ; $i < $nDataRow ; $i++) {
#		$App->print("  Row $i: ", $pLabelArray->[$i], "\n");
#	}

	my $Eidx = -1;
	for(my $i = 0 ; $i < $nDataRow ; $i++) {
		if($pLabelArray->[$i] eq 'E' or $pLabelArray->[$i] =~ /^E[ \(]*eV[ \)]*/ ) {
			$Eidx = $i;
			last;
		}
	}
	$App->print("  E data is at Row $Eidx\n");
	my $Ridx = -1;
	for(my $i = 0 ; $i < $nDataRow ; $i++) {
		if($pLabelArray->[$i] eq 'R') {
			$Ridx = $i;
			last;
		}
	}
	$App->print("  R data is at Row $Ridx\n");

	my $nidx = -1;
	for(my $i = 0 ; $i < $nDataRow ; $i++) {
		if($pLabelArray->[$i] eq 'n') {
			$nidx = $i;
			last;
		}
	}
	$App->print("  n data is at Row $nidx\n") if($nidx >= 0);
	my $kidx = -1;
	for(my $i = 0 ; $i < $nDataRow ; $i++) {
		if($pLabelArray->[$i] eq 'k') {
			$kidx = $i;
			last;
		}
	}
	$App->print("  k data is at Row $kidx\n") if($kidx >= 0);

	my $pf = $pDataArray->[$Eidx];
	my $pR = $pDataArray->[$Ridx];
	for(my $i = 0 ; $i < $nData ; $i++) {
		$pf->[$i] = $pf->[$i] * $e / $h;
	}

	my $Minf = $pf->[0];
	my $Maxf = $pf->[$nData-1];
	my $df = ($Maxf - $Minf) / ($nData - 1);
	$App->printf("  f range: %8.4e - %8.4e Hz (%8.4e Hz)\n", $Minf, $Maxf, $df);

	my $nDataOrg = $nData;
	$nData *= $nDivide;
print " nData: $nDataOrg => $nData\n";
	my $dfOrg = $df;
	$df /= $nDivide;
print " delta f: $dfOrg => $df\n";
	my @f;
	my @R;
	my @lnR2;
	my @nOrgInt;
	my @kOrgInt;
	for(my $i = 0; $i < $nData ; $i++) {
		my $x = $Minf + $i * $df;
		my $v = Algorism::Interporate($nDataOrg, $Minf, $dfOrg, $pR, $x);
#print "$i: ($x, $v)\n";
		$f[$i] = $x;
		$v = 1e-10 if($v <= 1e-10);
		$R[$i] = $v;
#my $E = $h * $x / $e;
#print "$i: $E   $x  $R[$i]\n";
		$lnR2[$i] = 0.5 * log($v);
		if($nidx >= 0) {
			$nOrgInt[$i] = Algorism::Interporate(
					$nDataOrg, $Minf, $dfOrg, $pDataArray->[$nidx], $x);
		}
		if($kidx >= 0) {
			$kOrgInt[$i] = Algorism::Interporate(
					$nDataOrg, $Minf, $dfOrg, $pDataArray->[$kidx], $x);
		}
	}

	my $Optics = new Optics;
	my ($pQ) = $Optics->KKConversion(\@f, \@lnR2, $ExtraporateLow, $ExtraporateHigh, $Integrator);

	my (@n, @k);
	for(my $i = 0 ; $i < $nData ; $i++) {
		my $SqrR = sqrt($R[$i]);
		my $div = 1.0 + $R[$i] - 2.0 * $SqrR * cos($pQ->[$i]);
		$n[$i] = (1.0 - $R[$i]) / $div;
		$k[$i] = 2.0 * $SqrR * sin($pQ->[$i]) / $div;
	}

	my @LabelArray = ("f(s-1)", "R", "0.5lnR", "Q", "n", "k");
	if($nidx >= 0) {
		push(@LabelArray, "n(org)");
	}
	if($kidx >= 0) {
		push(@LabelArray, "k(org)");
	}
	my @DataArray  = (\@f, \@R, \@lnR2, $pQ, \@n, \@k);
	if($nidx >= 0) {
		push(@DataArray, \@nOrgInt);
	}
	if($kidx >= 0) {
		push(@DataArray, \@kOrgInt);
	}

	$csv->SetLabelArray(\@LabelArray);
	$csv->SetDataArray(\@DataArray);
	if($csv->Save($OutputFile)) {
		$App->print("  Save to [$OutputFile]\n");
	}
	else {
		$App->print("  Error!!: Can not write to [$OutputFile]\n");
		return -2;
	}

	$App->print("\n\n<b>Convolute CSV File: Finished</b>\n");
}
