package attenuation;

# Everything related to measured attenuation values and extinction functions

#require 5.000;
#require Exporter;

use strict;
use warnings;
use vars qw(@ISA);
#use Carp;

use PDL;
use PDL::Core;
use PDL::Math;
use PDL::Primitive;
use PDL::Complex;

#@ISA = qw(Exporter);
#@EXPORT = qw(read_Kext);
#@ISA=qw(Wx::Frame);

sub new {
  my( $this ) = shift;
  my $class = ref($this) || $this;
  my $newInst={};

  $newInst->{F} = pdl[1];
  $newInst->{KA}= pdl[1];
  $newInst->{KEXT}= pdl[1];
  $newInst->{ALPHA}= (pdl[1]);
  $newInst->{ALPHA_0}= (pdl[1]);
  $newInst->{KEXT_ERROR} =  pdl[1];
  $newInst->{C_F}=1;
  $newInst->{PHI}= 1;
  bless($newInst, $class);
  $newInst->Initialize;
  return $newInst;
}

sub Initialize {
  my ($this) = @_;
  #printf "Initialize $this\n";
  $this->{F} = pdl [0];
  $this->{KA}= pdl [0];
  $this->{KEXT}= pdl [0];
  $this->{ALPHA}=pdl [0];
  $this->{ALPHA_0}=pdl [0];
  $this->{KEXT_ERROR} =  pdl[0];
  $this->{C_F}=0;
  $this->{PHI}=0;
}

sub f {
  my $this = shift;
  if (@_) {
    $this->{F} = pdl @_;}
  return $this->{F};
}

sub f_elem {
  my ($this,$index,$value) = @_;
  #printf $this . "\n";
  if ($value) { $this->{F}->slice("$index") .= $value }
  return $this->{F}->slice("$index")->sclr;
}

sub ka {
  my $this = shift;
  if (@_) { $this->{KA} = pdl @_; }
  return $this->{KA};
}

sub ka_elem {
  my ($this,$index,$value) = @_;
  if ($value) { $this->{KA}->slice("$index") .= $value }
  return $this->{KA}->slice("$index")->sclr;
}

sub alpha {
  my $this = shift;
  if (@_) {
    $this->{ALPHA} =pdl @_;
  }
  return $this->{ALPHA};
}

sub alpha_elem {
  my ($this,$index,$value) = @_;
  if ($value) { $this->{ALPHA}->slice("$index") .= $value;
  #printf("Here: ");
  #printf $value . "\n"
  }
  return $this->{ALPHA}->slice("$index")->sclr;
}

sub alpha_0 {
  my $this = shift;
  if (@_) { $this->{ALPHA_0} = pdl @_; }
  return $this->{ALPHA_0};
}

sub alpha_0_elem {
  my ($this,$index,$value) = @_;
  if ($value) { $this->{ALPHA_0}->slice("$index") .= $value;
  }
  return $this->{ALPHA_0}->slice("$index")->sclr;
}



sub Kext {
  my $this = shift;
  if (@_) { $this->{KEXT} = pdl @_; }
  return $this->{KEXT};
}

sub Kext_elem {
  my ($this,$index,$value) = @_;
  if ($value) { $this->{KEXT}->slice("$index") .= $value }
  return $this->{KEXT}->slice("$index")->sclr;
}


sub Kext_error {
  my $this = shift;
  if (@_) { $this->{KEXT_ERROR} = pdl @_; }
  return $this->{KEXT_ERROR};
}

sub Kext_error_elem {
  my ($this,$index,$value) = @_;
  if ($value) { $this->{KEXT_ERROR}->slice("$index") .= $value }
  return $this->{KEXT_ERROR}->slice("$index")->sclr;
}

sub c_f {
  my $this = shift;
  if (@_) { $this->{C_F} = shift }
  return $this->{C_F};
}


sub phi {
  my $this = shift;
  if (@_) { $this->{PHI} = shift }
  return $this->{PHI};
}



# This function can be used to read Values from a file

sub read_Kext {
  my ($this,$kext_file)=@_;
#  my @Kext;
#  my @Kext_error;
#  my @ka;
#  my @f;
#  my $c_F=0;
#  my $phi;
  # KExt - Datei einlesen
  open(FILE,$kext_file) or return 0;

  # Header lesen
  # = Zeilen einlese, bis die Zeile den gewünschten Text ("Kext_avg") enthält.
  my $linebuf;
  my @fields=[0];
  do {
    $linebuf=<FILE>;                                # get one line of input
    chomp($linebuf);
  } until (($linebuf =~ "alpha_avg") || eof(FILE));

  # bestimme die Position der ka-Spalte und der Spalte von KExt_avg;
  @fields = split("\t", $linebuf);
  my $i=0;
  while ( ($i<=$#fields) && ($fields[$i] ne "# f [MHz]") ) {$i++;}
  my $f_pos=$i;
  #printf("f: $i\n");
  while ( ($i<=$#fields) && ($fields[$i] ne "ka") ) {$i++;}
  my $ka_pos=$i;
  while ( ($i<=$#fields) && ($fields[$i] ne "alpha_0") ) {$i++;}
  my $alpha_0_pos=$i;
  while ( ($i<=$#fields) && ($fields[$i] ne "alpha_avg") ) {$i++;}
  my $alpha_pos=$i;
  #printf("ka: $i\n");
  while ( ($i<=$#fields) && ($fields[$i] ne "KExt_avg") ) {$i++;}
  my $KExt_pos=$i;
  #printf("KExt: $i\n");

  # Datenzeilen einlesen und Daten (f, ka, Kext) extrahieren.
  $i=0;
  my @alpha;
  my @alpha_0;
  my @kext;
  my @kext_error;
  my @ka;
  my @f;
  do {
    $linebuf=<FILE>;
    chomp($linebuf);
    @fields = split("\t", $linebuf);
    #printf("@fields\n");
    unless ($fields[$KExt_pos] eq "-") {
      #printf $this . " " . $this->{ALPHA} . "\n";
      $alpha[$i]= $fields[$alpha_pos];
      $alpha_0[$i]= $fields[$alpha_0_pos];
      $kext[$i]=$fields[$KExt_pos];
      $kext_error[$i]=$fields[$KExt_pos+1];
      $ka[$i]=$fields[$ka_pos];
      $f[$i]=$fields[$f_pos];
      $i++;
    }
  } until ( eof(FILE));
  close(FILE);
  $this->{ALPHA}= pdl (@alpha);
  $this->{ALPHA_0}= pdl (@alpha_0);
  $this->{KEXT}= pdl (@kext);
  $this->{KEXT_ERROR}= pdl (@kext_error);
  $this->{KA}= pdl (@ka);
  $this->{F}= pdl (@f);
  return 1;
}

sub write_alpha {
  my ($this, $attenuation_file) = @_;
  open(FILE,">$attenuation_file") or return(0);
  # This is done to be compatible with older versions of kext reading functions
  # Dummy entries
  print FILE ("# x50=\t\t\n");
  print FILE ("# phi=\t\t\n");
  print FILE ("# cm=\t\t\n");
  print FILE ("# c=\t\t\n\n");
  # Header:
  print FILE ("# f [MHz]\tka\t");
  print FILE ("alpha_0\t");
  print FILE ("alpha_avg\t");
  print FILE ("KExt_avg\tKExt_var\n");
  # Data
  for(my $i=0;$i<$this->f->getdim(0);$i++) {
    my $dummy =$this->f_elem($i);
    print FILE ("$dummy\t0\t");
    $dummy =$this->alpha_0_elem($i);
    print FILE ("$dummy\t");
    $dummy =$this->alpha_elem($i);
    print FILE ("$dummy\t");
#    $dummy =$this->Kext_elem($i);
    $dummy =0;
#    my $dummy2 =$this->Kext_error_elem($i);
    my $dummy2 =0;
    print FILE ("$dummy\t$dummy2\n");
  }
  close(FILE);
  return 1;
}

sub output_alpha {
  my ($this,$process) = @_;
  #open(STDOUT,$process->GetOutputStream) or return(0);
  #write $process->GetOutputStream . "test\n";
  # Header
  my $a =$process->GetOutputStream();
  print $a "Begin of attenuation data\n";
  # Data
  for(my $i=0;$i<$this->f->getdim(0);$i++) {
    my $dummy1 =$this->f_elem($i);
    my $dummy2 =$this->alpha_0_elem($i);
    my $dummy3 =$this->alpha_elem($i);
    print $a "$dummy1\t$dummy2\t$dummy3\n";
  }
  # "Footer"
  print $a "End of attenuation data\n";
  #close(STDOUT);
  return 1;
}


1;
