#!/usr/bin/perl

use lib 'd:/git/tkProg/tklib/Perl/lib';
use lib '/home/share/tkProg/tklib/Perl/lib';

use strict;
use Tk;

use Jcode;
use encoding 'sjis';

use ProgVars;
use Sci qw($pi $kB $R $NA $c $e $e0 $u0 $me $mp $mn $h $hbar);
use Sci::Material;
use Sci::Optics;
use Crystal::AtomType;

use MyTk::MyNoteBook;
use MyTk::MyLabel;
use MyTk::MyEntry;
use MyTk::MyText;
use MyTk::MyButton;

my $Debug = 0;

my $material = new Material;
my $pArgs = &GetArgs(\@ARGV);

my $mw = MainWindow->new();
$mw->title("Semiconductor Parameter Calculator");
if(0) {
	my @Fonts = $mw->fontFamilies();
	for my $s (@Fonts) {
		print "$s\n";
	}
}

my $this = $mw;

my $EntryWidth = 10;
my $T              = 300.0;

my $EffMass         = 0.35;
my $CBMultiplicity  = 1.0;
my $Ne              = 1.0e19; # cm-3
my ($Nc, $Dc0, $EF, $dEBM, $Ep, $lDrift, $lDiff);

my $Book = $mw->MyNoteBook()->pack(-fill => 'both', -expand => 'yes');
my @Pages;
my $FirstPage;

	$Pages[1] = $Book->add("Nc",           -label => "Nc,BM shift");
	my $Frame = &MakeNcPage($Pages[1], $EntryWidth);
	$this->{EffMassButton} = $Frame->MyButton(
		-text => 'm*:',
		-takefocus => 1,
		-command => [\&ButtonPressed, 'RButtonDown', 'm*'],
		)->grid(-row => 6, -column => 0, -columnspan => 1, -sticky => 'e' );
	$this->{EffMassButton}->{status} = 1;
	$this->{NeButton} = $Frame->MyButton(
		-text => 'Ne:',
		-takefocus => 1,
		-command => [\&ButtonPressed, 'RButtonDown', 'Ne'],
		)->grid(-row => 6, -column => 6, -columnspan => 1, -sticky => 'e' );
	$FirstPage = "Nc" if(!$FirstPage);

$Book->raise($FirstPage) if($FirstPage);
# raised(): 表示されているページを返す
# delete(), pagecget($Page1, -option), pageconfigure(pageName, options)

&UpdateParameters();

MainLoop;
exit;
#=========================================================================================
# Main routine end
#=========================================================================================

#=========================================================================================
# Subroutines
#=========================================================================================
sub GetArgs
{
	my ($pArgs) = @_;
	my %Args;
	if(@$pArgs == 0) {
		$Args{All} = 1;
		return \%Args;
	}

	foreach my $s (@$pArgs) {
		my ($key, $val) = ($s =~ /^([^=]+)=(.*)$/);
		if(!$key) {
			$key = $s;
			$val = 1;
		}
		$Args{$key} = $val;
#print "$key: $val\n";
	}
	return \%Args;
}

sub ButtonPressed
{
	my ($event, $type) = @_;
#print "$event $type\n";
	if($type eq 'm*') {
		if($this->{EffMassButton}->{status}) {
			$this->{EffMassButton}->{status} = 0;
			$this->{NeButton}->{status}      = 1;
			$this->{EffMassEntry}->configure(-state => 'disabled');
			$this->{NeEntry}->configure(-state => 'normal');
		}
		else {
			$this->{EffMassButton}->{status} = 1;
			$this->{NeButton}->{status}      = 0;
			$this->{EffMassEntry}->configure(-state => 'normal');
			$this->{NeEntry}->configure(-state => 'disabled');
		}
	}
	elsif($type eq 'Ne') {
		if($this->{NeButton}->{status}) {
			$this->{NeButton}->{status}      = 0;
			$this->{EffMassButton}->{status} = 1;
			$this->{NeEntry}->configure(-state => 'disabled');
			$this->{EffMassEntry}->configure(-state => 'normal');
		}
		else {
			$this->{NeButton}->{status}      = 1;
			$this->{EffMassButton}->{status} = 0;
			$this->{NeEntry}->configure(-state => 'normal');
			$this->{EffMassEntry}->configure(-state => 'disabled');
		}
	}
}

sub UpdateParameters
{
	$Nc   = $material->Nc($EffMass*$me, $CBMultiplicity, $T, 0) * 1.0e-6;
	$Dc0  = $material->Dc0($EffMass*$me, $CBMultiplicity, 0) * $e**1.5 * 1.0e-6; # cm^-3/eV^1.5
}

sub EntryFocusedOut {
	my ($obj, $event, $type) = @_;

	$T              = eval($T      );
	$CBMultiplicity = eval($this->{CBMultEntry}->GetText() );
	$Ne             = eval($this->{NeEntry}->GetText()     );
	$Nc             = eval($this->{NcEntry}->GetText()     );
	$Dc0            = eval($this->{Dc0Entry}->GetText()    );
	if($event eq 'FocusOut') {
		if($type eq 'T') {
			$Nc  = $material->Nc( $EffMass*$me, $CBMultiplicity, $T, 0) * 1.0e-6;
			$Dc0 = $material->Dc0($EffMass*$me, $CBMultiplicity, 0) * $e**1.5 * 1.0e-6; # cm^-3/eV^1.5
		}
	}
	&UpdateParameters();
}

sub MakeNcPage
{
	my ($page, $EntryWidth) = @_;

	my $Frame = $page->Frame()->pack(-anchor => 'nw', -fill => 'x');
	$this->{TEntry}     = &MakeLabelEntry($Frame, "T",     "T:",         \$T,  "%8.2f", $EntryWidth, "K",      1, 0, "normal");

	$this->{EffMassEntry} = &MakeLabelEntry($Frame, "m*",    "m*:",         \$EffMass,  "%8.3f", $EntryWidth, "me0",  6, 0);
	$this->{CBMultEntry}  = &MakeLabelEntry($Frame, "M",     "M:",   \$CBMultiplicity,  "%6.2f", $EntryWidth, "",     6, 1);
	$this->{NeEntry}      = &MakeLabelEntry($Frame, "Ne",    "Ne:",              \$Ne, "%10.4g", $EntryWidth, "cm-3", 6, 2, "disabled");
	$this->{NcEntry}      = &MakeLabelEntry($Frame, "Nc",    "Nc:",              \$Nc, "%10.4g", $EntryWidth, "cm-3", 7, 0, "disabled");
	$this->{Dc0Entry}     = &MakeLabelEntry($Frame, "Dc0",   "D(E)=",           \$Dc0, "%10.4g", $EntryWidth, "E^0.5 /cm^3/eV", 7, 1, "disabled");

	return $Frame;
}


sub MakeLabelEntry
{
	my ($Frame, $name, $label1, $pVariable, $format, $EntryWidth, $label2, $row, $column, $state) = @_;
	$state = 'normal' if(!defined $state);
#print "Frame=$Frame  name=$name,$label1,$format,$label2\n";
	$$pVariable = Utils::DelSpace(sprintf($format, $$pVariable));
	$Frame->MyLabel(-text => $label1)->grid(-row => $row, -column => 3*$column+0, -columnspan => 1, -sticky => 'e' );
	my $ent  = $Frame->MyEntry(
		-name         => $name,
		-width        => $EntryWidth,
#		-text         => $val,
		-textvariable => $pVariable,
		-state        => $state,
		-format       => $format,
		)->grid(-row => $row, -column => 3*$column+1, -columnspan => 1, -sticky => 'e' );
	$Frame->MyLabel(-text => $label2)->grid(-row => $row, -column => 3*$column+2, -columnspan => 1, -sticky => 'w' );
	$ent->bind('<FocusOut>', [\&EntryFocusedOut, 'FocusOut', $name]);

	$this->{pEntryArray} = [] if(!$this->{pEntryArray});
	push(@{$this->{pEntryArray}}, $ent);
	return $ent;
}
