package CUEPost;

=head1 NAME

CUEPost 

=head1 DESCRIPTION

This file contains subroutines to provide additional Power Syntax
functionality in the CUE Post-Processor

=head1 POWER SYNTAX CONTENT SUBROUTINES

These subroutines provide additional information about the subroutines, 
variables, etc. available to CCL Power Syntax.
=cut

=head2 showSubs()

  void showSubs(String packageName)

Prints a list of the subroutines available in the specified package.  If no 
package is specified, CUEPost is used by default.

=cut

sub showSubs {
  my ($packageName) = @_;

  if (!defined($packageName)) {
    $packageName = "CUEPost";
  }

  my @subList;
  local (*alias);
  *stash = *{"${packageName}::"};
  while ((my $varName, my $globValue ) = each %stash) {
    *alias = $globValue;

 # push the stash item onto the list if it's a subroutine
    if (defined (&alias) && $varName ne "alias") {
      push (@subList,$varName);
    }

  }

  # print the sorted list
   print "\n";
   foreach my $sub (sort(@subList)) {
    print "$sub\n";
  }

}

=head2 showVars()

  void showVars(String packageName)

Prints a list of the Power Syntax variables and their current value defined 
in the specified package.  If no package is specified, CUEPost is used by 
default.

=cut

sub showVars {
  my ($packageName) = @_;

  if (!defined($packageName)) {
    $packageName = "CUEPost";
  }

  my %varList;
  local (*alias);
  *stash = *{"${packageName}::"};
  while ((my $varName,my $globValue ) = each %stash) {
    *alias = $globValue;

 # add the stash item and value onto the list if it's a variable
    if (defined ($alias) && $varName ne "alias") {
      $varList{$varName} = $alias;
    }
  }

 # print the sorted list with values
   print "\n";
   foreach my $var (sort(keys(%varList))) {
     print "\$$var = $varList{$var}\n";
   }

}

=head2 showPkgs()

  void showPkgs()

Prints a list of packages available which may contain other variables or
subroutines in Power Syntax.

=cut

sub showPkgs {
  foreach my $name (keys %main::) {
    if ($name =~ "::") {
      print "$name\n";
    }
  }
}

=head1 QUANTITATIVE SUBROUTINES

These subroutines provide access to the quantitative fuctionality of CUE Post.
Most of these routines provide results in a single return value.  If the 
perl variable '$verbose = 1', then the result is also printed to the
screen.

=head2 massFlowAve(Variable, Location)

  real massFlowAve(Variable, Location)

Computes the massflow weighted average of the Variable at the specified Location.

=cut

sub massFlowAve {
 my ($var,$loc) = @_;
 my $result = calculate("massFlowAve",$var,$loc);

 if (verboseOn() && defined($result)) {
   print "The massflow weighted average of '$var' on '$loc' is $result\n";
 }
 return $result;

} #end massFlowAve

=head2 massFlowAveAbs(Variable, Location)

  real massFlowAveAbs(Variable, Location)

Computes the massflow weighted average of the Variable at the specified Location.

=cut

sub massFlowAveAbs {
 my ($var,$loc) = @_;
 my $result = calculate("massFlowAveAbs",$var,$loc);

 if (verboseOn() && defined($result)) {
   print "The absolute massflow weighted average of '$var' on '$loc' is $result\n";
 }
 return $result;

} #end massFlowAveAbs

=head2 massFlowInt(Variable, Location)

  real massFlowInt(Variable, Location)

Computes the mass integral of the Variable at the specified Location.

=cut

sub massFlowInt {
 my ($var,$loc) = @_;
 my $result = calculate("massFlowInt",$var,$loc);

 if (verboseOn() && defined($result)) {
   print "The integral of massflow times '$var' on '$loc' is $result\n";
 }
 return $result;

} #end massFlowInt

=head2 areaAve(Variable, Location)

  real areaAve(Variable, Location)

Computes the area weighted average of the Variable at the specified Location.

=cut

sub areaAve {
 my ($var,$loc) = @_;

 my $result = calculate("areaAve",$var,$loc);

 if (verboseOn() && defined($result)) {
   print "The area weighted average of '$var' on '$loc' is $result\n";
 }
 return $result;

} #end areaAve

=head2 volumeAve(Variable, Location)

  real volumeAve(Variable, Location)

Computes the volume weighted average of the Variable at the specified Location.

=cut

sub volumeAve {
 my ($var,$loc) = @_;

 my $result = calculate("volumeAve",$var,$loc);

 if (verboseOn() && defined($result)) {
   print "The volume weighted average of '$var' on '$loc' is $result\n";
 }
 return $result;

} #end volumeAve

=head2 volumeInt(Variable, Location)

  real volumeInt(Variable, Location)

Computes the volume integral of the Variable at the specified Location.

=cut

sub volumeInt {
 my ($var,$loc) = @_;

 my $result = calculate("volumeInt",$var,$loc);

 if (verboseOn() && defined($result)) {
   print "The volume integral of '$var' on '$loc' is $result\n";
 }
 return $result;

} #end volumeInt


=head2 ave(Variable, Location)

  real ave(Variable, Location)

Computes the arithmetic average of the Variable at the specified Location.

=cut

sub ave {
 my ($var,$loc) = @_;
 my $result = calculate("ave",$var,$loc);

 if (verboseOn() && defined($result)) {
   print "The arithmetic average of '$var' on '$loc' is $result\n";
 }
 return $result;

} #end ave

=head2 massFlow(Location)

  real massFlow(Location)

Computes the mass flow through the specified Location.

=cut

sub massFlow {
 my ($loc) = @_;
 my $result = calculate("massFlow",$loc);

 if (verboseOn() && defined($result)) {
   print "The mass flow through '$loc' is $result\n";
 }
 return $result;

} #end massFlow

=head2 area(Location,Axis)

  real area(Location,Axis)

Computes the area of the specified Location.
Axis is optional.  If it is not specified, then the total area is reported,
if axis is specified, then projected area is reported.

=cut

sub area {
 my ($loc,$axis) = @_;
 if (!defined($axis)) {
   $axis = "";
 }
 my $result = calculate("area",$loc,$axis);

 if (verboseOn() && defined($result)) {
   print "The area of '$loc' is $result\n";
 }
 return $result;

} #end area

=head2 volume(Location)

  real volume(Location)

Computes the volume of a specified Location.

=cut

sub volume {
  my($loc) = @_;
  my $result = calculate("volume",$loc);
  if(verboseOn() && defined($result)) {
    print "The volume of '$loc' is $result\n";
  }
  return $result;
}

=head2 count(Location)

  real count(Location)

Computes the number of vertices in the specified Location.

=cut

sub count {
 my ($loc) = @_;
 my $result = calculate("count",$loc);

 if (verboseOn() && defined($result)) {
   print "The number of vertices in '$loc' is $result\n";
 }
 return $result;

} #end count

=head2 countTrue(Variable,Location)

  real countTrue(Variable,Location)

Computes the number of vertices where the variable is "true" in the specified Location.

=cut
sub countTrue {
 my ($var,$loc) = @_;
 my $result = calculate("countTrue",$var,$loc);

 if (verboseOn() && defined($result)) {
   print "The countTrue of '$var' on '$loc' is $result\n";
 }
 return $result;

} #end countTrue


=head2 areaInt(Variable, Location,Axis)

  real areaInt(Variable, Location,Axis)

Integrates the specified variable wrt local area on the specified locator.
Axis is optional.  If it is not specified, then the integration is performed
over the total face area.  If axis is specified, thenthe integration is performed
over the projected face area.

=cut

sub areaInt {
 my ($var,$loc,$axis) = @_;
 if (!defined($axis)) {
   $axis = "";
 }
 my $result = calculate("areaInt",$var,$loc,$axis);

 if (verboseOn() && defined($result)) {
   print "The area integral of '$var' on '$loc' is $result\n";
 }
 return $result;

} #end areaInt

=head2 sum(Variable,Location)

  real sum(Variable,Location)

Computes the sum of the specified variable in the specified Location.

=cut
sub sum {
 my ($var,$loc) = @_;
 my $result = calculate("sum",$var,$loc);

 if (verboseOn() && defined($result)) {
   print "The sum of '$var' on '$loc' is $result\n";
 }
 return $result;

} #end sum

=head2 length(Location)

  real Length(Location)

Computes the length of the specified line.
Note that the leading character is capitalised.  This is to
avoid confusion with the Perl internal command 'length'. Ugh.

=cut
sub Length {
 my ($loc) = @_;
 my $result = calculate("length",$loc);

 if (verboseOn() && defined($result)) {
   print "The length of '$loc' is $result\n";
 }
 return $result;

} #length

=head2 lengthAve(Variable,Location)

  real lengthAve(Variable,Location)

Computes the length weighted average of the variable on the specified line.

=cut
sub lengthAve {
 my ($var,$loc) = @_;
 my $result = calculate("lengthAve",$var,$loc);

 if (verboseOn() && defined($result)) {
   print "The length weighted average of '$var' on '$loc' is $result\n";
 }
 return $result;

} #end lengthAve

=head2 lengthInt(Variable,Location)

  real lengthInt(Variable,Location)

Computes the length weighted integral of the variable on the specified line.

=cut
sub lengthInt {
 my ($var,$loc) = @_;
 my $result = calculate("lengthInt",$var,$loc);

 if (verboseOn() && defined($result)) {
   print "The length integral of '$var' on '$loc' is $result\n";
 }
 return $result;

} #end lengthInt

=head2 minVal(Variable, Location)

  real minVal(Variable, Location)

Returns the minimum value of the specified variable on the specified locator.

=cut

sub minVal {
 my ($var,$loc) = @_;
 my $result = calculate("minVal",$var,$loc);

  if (verboseOn() && defined($result)) {
   print "The minimum value of '$var' on '$loc' is $result\n";
 }
 return $result;

} #end minVal

=head2 maxVal(Variable, Location)

  real maxVal(Variable, Location)

Returns the maximum value of the specified variable on the specified locator.

=cut

sub maxVal {
 my ($var,$loc) = @_;
 my $result = calculate("maxVal",$var,$loc);

  if (verboseOn() && defined($result)) {
   print "The maximum value of '$var' on '$loc' is $result\n";
 }
 return $result;

} #end maxVal

=head2 range(Variable, Location)

  real range(Variable, Location)

Returns the range of the specified variable on the specified locator as a
two element list.

=cut

sub range {
 my ($var,$loc) = @_;
 my $minVal = minVal($var,$loc);
 my $maxVal = maxVal($var,$loc);

  if (verboseOn() && defined($minVal) && defined($maxVal)) {
   print "The range of '$var' on '$loc' is $minVal to $maxVal\n";
 }
 return ($minVal,$maxVal);

} #end maxVal

=head2 probe(Variable, Location)

  real probe(Variable, Location)

Returns the value of the specified variable on the specified point.

=cut

sub probe {
 my ($var,$loc) = @_;
 my $result = calculate("probe",$var,$loc);

  if (verboseOn() && defined($result)) {
   print "The value of '$var' at '$loc' is $result\n";
 }
 return $result;

} #end probe

=head2 force(Location,Axis)

  real force(Location,Axis)

Returns the force on the specified locator in the direction of the specified axis.

=cut

sub force {
 my ($loc,$axis) = @_;
 my $result = calculate("force",$loc,$axis);

  if (verboseOn() && defined($result)) {
   print "The force on '$loc' in the direction '$axis' is $result\n";
 }
 return $result;

} #end force

=head2 forceNorm(Location,Axis)

  real forceNorm(Location,Axis)

Returns the per unit width force on the specified line in the direction of the specified axis.

=cut

sub forceNorm {
 my ($loc,$axis) = @_;
 my $result = calculate("forceNorm",$loc,$axis);

  if (verboseOn() && defined($result)) {
   print "The normalised force on '$loc' in the direction '$axis' is $result\n";
 }
 return $result;

} #end forceNorm

=head2 torque(Location,Axis)

  real torque(Location,Axis)

Returns the torque on the specified locator about the specified axis.

=cut

sub torque {
 my ($loc,$axis) = @_;
 my $result = calculate("torque",$loc,$axis);

  if (verboseOn() && defined($result)) {
   print "The torque on '$loc' about '$axis' is $result\n";
 }
 return $result;

} #end torque

=head1 UTILITY FUNCTIONS

Various utility functions used by the system

=head2 verboseOn()

Returns 1 or 0 depending if the Perl variable $verbose is set to 1.

=cut

sub verboseOn {
  if (defined($verbose) && $verbose == 1) {
   return 1;
  } else {
   return 0;
  }
} #end verboseOn

=head2 getExprString()

Returns the passed expression as a value-units pair (in base units)

=cut
sub getExprString {
 ($expr) = @_;

 ($val,$units) = evaluate($expr);
 return sprintf "%12g %s", $val, $units;
}

=head2 getExprVal()

Returns the value portion of the passed expression in base units

=cut
sub getExprVal {
 ($expr) = @_;

 ($val,$units) = evaluate($expr);
 return $val;
}


=head2 copyFile(string source, string target)

Copies source file to target file with NT/Unix dependancies taken into
consideration.  Current assumes Unix.

=cut
sub copyFile {
  my ($source,$target) = @_;
  system("cp $source $target");
}


=head2 exprExists(parameter)

Returns 1 if CEL parameter exists, null overwise.

=cut
sub exprExists {
  my ($expr) = @_;

# Get comma separated list of expressions
  my $list = getParameters('/LIBRARY/CEL/EXPRESSIONS');
  return ($list =~ m/^${expr},|,${expr},|,${expr}$|^${expr}$/);
}


=head2 getObjectName(ObjectPath)

Extract object name part from a path

=cut
sub getObjectName {
  my $path = shift;

  $path =~ s!.*/+!!;
  $path =~ s!.*:+!!;

  return $path;
}

1;
