#!/usr/bin/perl

use lib 'c:/Programs/Perl/lib';
use lib 'c:/Programs/Perl/lib2.0';
use lib 'd:/Programs/Perl/lib';
use lib 'd:/Programs/Perl/lib2.0';
use lib '.';

use strict;

use MyApplication2;
use Device::Device;

$SIG{INT} = \&ctrl_c_handler;
BEGIN {
#	$| = 1;
	open (STDERR, ">&STDOUT");
}

#===============================================
# Applicationオブジェクト作成
#===============================================
my $App = new MyApplication2;
$App->SetOutputMode("auto");
my $ProgramPath = $App->SpeculateProgramPath($0, "");
my $IniFile = $App->OpenIniFile($ProgramPath, 1);
$App->AddIniFileVariable("\\Preferences\\DeviceName", "DeviceName", "Keithley2000");
$App->AddIniFileVariable("\\Preferences\\Port",       "Port",       "GPIB17");
$App->ReadSetting();

$App->{Port}       = "GPIB27"        if(!defined $App->{Port});
$App->{DeviceName} = "Keithley6517A" if(!defined $App->{DeviceName});

$App->{Port}       = "GPIB17"        if(!defined $App->{Port});
$App->{DeviceName} = "Keithley2000" if(!defined $App->{DeviceName});

$App->{Port}       = "COM1"        if(!defined $App->{Port});
$App->{DeviceName} = "Cornerstone130" if(!defined $App->{DeviceName});

$App->{Port}       = "COM4"        if(!defined $App->{Port});
$App->{DeviceName} = "Laserstar3APLS" if(!defined $App->{DeviceName});



#===============================================
# Deviceオブジェクト作成
#===============================================
my $dev = OpenDevice($App->{DeviceName}, $App->{Port});
$App->print("'set DeviceName:[GPIB??|COM?]' command to change Port.\n");

#===============================================
# メインループ
#===============================================
while(1) {
	$App->print(">");
	my $line = <STDIN>;
	chomp $line;
	if($line =~ /^\s*$/) {
		next;
	}
	elsif($line =~ /^\s*bye\s*$/i) {
		last;
	}
	elsif($line =~ /set\s+(.*)/i) {
		my $Arg = $1;
		my ($d, $p) = ($Arg =~ /([^:]+)\s*:\s*(\w+)/);
		if(!defined $p) {
			if($Arg =~ /^\s*((COM|GPIB)\d+)\s*$/i) {
				$d = "General";
				$p = $Arg;
			}
			else {
				$App->print("Invalid argument for set: [$line]\n");
				next;
			}
		}
		$App->print(" OpenDevice: $d, $p\n");
		undef $dev;
		$dev = OpenDevice($d, $p);
		$App->print(" Device assigned to [$dev]\n");
	}
	elsif($line =~ /^\s*print\s+(.*)$/i) {
		my $l = $1;
		if($l =~ /^(.*)\s+\?\s*$/) {
			$l = $1;
		}
		$App->print("  print $l\n");
		$dev->print($l);
	}
	elsif($line =~ /^\s*read\s*$/i) {
		my $ret = $dev->read();
		$App->print($ret);
	}
	elsif($line =~ /bye/i) {
		last;
	}
	elsif($line =~ /help/i or $line =~ /^\s*\?\s*$/) {
		help();
		next;
	}
	else {
		my $l = $line;
		if($l =~ /^(.*)\s+\?\s*$/) {
			$l = $1;
		}
		Utils::DelSpace($l);
		$App->print("  print [$l]\n");
#		$dev->print("$l\n");
		$dev->print("$l\r\n");
	}
	if($line =~ /\?/) {
		my $response = $dev->read();
		print "  >>>$response\n";
	}
}

$App->SaveSetting();
exit;

#==================================================================
# 一般関数
#==================================================================
sub ctrl_c_handler{
	$App->print("CTRL+C pressed\n");
	$App->print("Input 'yes' if terminate this program.\n>>");
	my $line = <>;
	if($line =~ /^\s*yes\s*$/i) {
	   exit;
	}
	return;
}

sub OpenDevice
{
	my ($DeviceName, $Port) = @_;
	Utils::DelSpace($DeviceName);
	Utils::DelSpace($Port);

# RS232Cの設定
my $ConfFile        = '';
my $COMPort         = 'COM1';
my $UseModule       = 0;
my $BaudRate        = 9600;
my $Parity          = 'none';
my $DataBits        = 8;
my $StopBits        = 1;
my $HandShake       = 'none';
my $WriteBufferSize = 1024 * 20;
my $ReadBufferSize  = 1024 * 4;
my $ReadInterval    = 800;
my $ReadCharTime    = 400;
my $ErrorMessage    = 1;
my $UserMessage     = 1;

# GPIBの設定
my $GPIBInterface   = "ni";
my $GPIBTimeOut     = GPIB->T1s;
my $GPIBEOT         = 1;
my $GPIBEOS         = 0;

	my $dev = new Device(
			-Port               => $Port,
			-ModuleName         => $DeviceName,
			-DeviceName         => $DeviceName,
			-GPIBInterface      => $GPIBInterface,
			-GPIBTimeOut        => $GPIBTimeOut,
			-GPIBEOT            => $GPIBEOT,
			-GPIBEOS            => $GPIBEOS,
			-COMConfName        => $ConfFile,
			-COMBaudRate        => $BaudRate,
			-COMParity          => $Parity,
			-COMDataBits        => $DataBits,
			-COMStopBits        => $StopBits,
			-COMHandShake       => $HandShake,
			-COMWriteBufferSize => $WriteBufferSize,
			-COMReadBufferSize  => $ReadBufferSize,
			-COMReadInterval    => $ReadInterval,
			-COMReadCharTime    => $ReadCharTime,
			-COMErrorMessage    => $ErrorMessage,
			-COMUserMessage     => $UserMessage,
			-PrintError         => 1,
			);
	if(!defined $dev) {
		$App->print("Device can not be opened. [$DeviceName: $Port]\n");
		exit;
	}

	my $Id = $dev->GetId();
	$App->print("$DeviceName: [$dev->{ModuleName}:$dev->{Port}] (Object: $dev)\n");
	$App->print("Id: $Id\n");

	return $dev;
}

sub help
{
	$App->print("*CLS: Clear status\n");
	$App->print("*IDN?: Query identification\n");
	$App->print("*RST: Reset\n");
	$App->print(":FETCh?: Read data\n");
	$App->print(":READ?: :ABORt, :INITiate & :FETCh?\n");
	$App->print(":sense:volt:range:auto 1\n");
	$App->print(":sense:volt:range 210\n");
	$App->print('$II' . " (powermeter)\n");
	$App->print("GOWAVE wavelength (monochrometer)\n");
	$App->print("set DeviceName:Port\n");
	$App->print("print string\n");
	$App->print("read\n");
	


}
