#!/usr/bin/env perl

## Reatance calculator

## This file Copyright 2000 <contact@gbppr.org> under the GPL
## NO WARRANTY. Please send bug reports / patches / reports.

use Math::Complex;

sub Freq {
undef $_;
while (!m/^([0-9.]+)(k|K|m|M|h|H+)$/) {
        print "\nk = kilohertz\n".
	      "m = megahertz\n".
	      "h = just hertz\n\n".
	      "Enter frequency  [value][k,m,h]: ";
	chomp($_ = <STDIN>);

if (m/^([0-9.]+)(k|K|m|M|h|H+)$/) {
	$frq = $1;
	$unit = $2;
}
if ($unit =~ /k/i) {
	$frq = $frq * 1000;
}
elsif ($unit =~ /m/i) {
        $frq = $frq * 1000000;
}                         
elsif ($unit =~ /h/i) {
        $frq = $frq;
  }
 }
}  

sub Cap {
undef $_;
while (!m/^([0-9.]+)(u|U|p|P|n|N+)$/) {
        print "\nu = microfarads\n".
	      "n = nanofarads\n".
	      "p = picofarads\n\n".
	      "Enter capacitance  [value][u,n,p]: ";
        chomp($_ = <STDIN>);

if (m/^([0-9.]+)(u|U|p|P|n|N+)$/) {
        $c = $1;
        $unit = $2;
}       
if ($unit =~ /u/i) {
         $c = $c / 1000000;
}
elsif ($unit =~ /n/i) {
         $c = $c / 1000000000;
}
elsif ($unit =~ /p/i) {
         $c = $c / 1000000000000;
  }
 }
}     

sub Cap_React {
print "\n";
while (!$xc) {
	print "Enter capacitive reactance (in ohms): ";
	chomp($xc = <STDIN>);
	$xc =~ tr/0-9.//csd;
 }      
}

sub Ind {
undef $_;
while (!m/^([0-9.]+)(n|N|m|M|u|U+)$/) {
        print "\nn = nanohenries\n".
	      "u = microhenries\n".
	      "m = millihenries\n\n".
	      "Enter inductance  [value][n,u,m]: ";
	chomp($_ = <STDIN>);

if (m/^([0-9.]+)(n|N|m|M|u|U+)$/) {
        $l = $1;
        $unit = $2;
}
if ($unit =~ /n/i) {
        $l = $l / 1000000000;
}
elsif ($unit =~ /u/i) {
	$l = $l / 1000000;
}
elsif ($unit =~ /m/i) {
        $l = $l / 1000;
  }
 }
}  

sub Ind_React {
print "\n";

while (!$xl) {
	print "Enter inductive reactance (in ohms): ";
        chomp($xl = <STDIN>);
        $xl =~ tr/0-9.//csd;
 }      
}

sub Print_Cap {
printf "\n\n            Frequency : %.6f MHz\n", $frq / 1000000;
printf "                      : %.6f kHz\n", $frq / 1000;
printf "                      : %.6f Hz\n\n", $frq;
printf "          Capacitance : %.4f uF\n", $c * 1000000;
printf "                      : %.4f pF\n\n", $c * 1000000000000;
printf " Capacitive reactance : %.4f ohms\n\n", $xc;
}

sub Print_Ind {
printf "\n\n            Frequency : %.6f MHz\n", $frq / 1000000;
printf "                      : %.6f kHz\n", $frq / 1000;
printf "                      : %.6f Hz\n\n", $frq;
printf "           Inductance : %.6f mH\n", $l * 1000;
printf "	              : %.6f uH\n", $l * 1000000;
printf "                      : %.6f nH\n\n", $l * 1000000000;
printf "  Inductive reactance : %.4f ohms\n\n", $xl;
}

while (!$ans || $ans > 6 || $ans =~ m/[a-z]/i) {
	print "\33[H\33[J".
	      "Reatance calculator\n\n".
              "Xc = Capacitive reactance in ohms\n".
              "Xl = Inductive reactance in ohms\n".
              "F  = Frequency in megahertz\n".
              "C  = Capacitance in picofarads\n".
              "L  = Inductance in microhenrys\n\n".
              "1) Calculate Xc - given F and C\n".
              "2) Calculate F  - given Xc and C\n".
              "3) Calculate C  - given Xc and F\n".
              "4) Calculate Xl - given F and L\n".
              "5) Calculate F  - given Xl and L\n".
              "6) Calculate L  - given Xl and F\n\n".
              "Enter your selection: ";
	chomp($ans = <STDIN>);
}

if ($ans == 1) {

	&Freq;
	&Cap;
	$xc = 1 / (2 * pi * $frq * $c);
	&Print_Cap;
}

elsif ($ans == 2) {

	&Cap_React;
	&Cap;
	$frq = 1 / (2 * pi * $c * $xc);
	&Print_Cap;
}

elsif ($ans == 3) {

	&Cap_React;	
	&Freq;
	$c = 1 / (2 * pi * $frq * $xc);
	&Print_Cap;
}

elsif ($ans == 4) {

	&Freq;
	&Ind;
	$xl = 2 * pi * $frq * $l;
	&Print_Ind;
}

elsif ($ans == 5) {

	&Ind_React;
	&Ind;
	$frq = $xl / (2 * pi * $l);
	&Print_Ind;
}

elsif ($ans == 6) {

	&Ind_React;
	&Freq;
	$l = $xl / (2 * pi * $frq);
	&Print_Ind;
}
