with Flts;
use Flts;

generic
  
  L: in Positive;  --- half period
  
  type Scalar is private;
  type Scalar_Array is array (Integer range <>) of Scalar;
  
  with function IsZero(S: Scalar) return Boolean is <>;
  with procedure SetZero(S: in out Scalar) is <>;
  with procedure Copy(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Assign(R: in Flt; S: in out Scalar) is <>;
  with procedure Mult(R: in Flt; S,Tmp: in out Scalar) is <>;
  with procedure Div(R: in Flt; S,Tmp: in out Scalar) is <>;
  with procedure Neg(S: in out Scalar) is <>;
  with procedure Add(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure AddProd(S1,S2: in Scalar; S3,Tmp: in out Scalar) is <>;
  with procedure ArcCos(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Cos(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Sin(S1: in Scalar; S2: in out Scalar) is <>;
  
package Generic_DFT is
  
  pragma Elaborate_Body;
  
  subtype NRange is Integer range 1 .. L-1;
  subtype XRange is Integer range 1-L .. L;
  subtype Values is Scalar_Array(XRange);
  subtype FPoly is Scalar_Array;           -- range has to include XRange
                                           -- P( n) is coeff of Cos(n*Pi*x/L)
                                           -- P(-n) is coeff of Sin(n*Pi*x/L)
  
  function Even(P: FPoly) return Boolean;
  procedure Val(P: in FPoly; X: in Integer; V,Tmp: in out Scalar);
  procedure Val(P: in FPoly; V: in out Values);
  procedure CosCoeff(N: in Natural; V: in Values; S,Tmp: in out Scalar);
  procedure SinCoeff(N: in Natural; V: in Values; S,Tmp: in out Scalar);
  procedure DFT(V: in Values; P: in out FPoly); -- does Sin and Cos in parallel
  procedure DCT(V: in Values; P: in out FPoly);
  
  generic
    with procedure F(S1: in Scalar; S2: in out Scalar);
  procedure F1(P: in out FPoly);

  generic
    with procedure F(S1: in Scalar; S2: in out Scalar);
  procedure F2(P1: in FPoly; P2: in out FPoly);
  
private
  
  T:     constant Positive := 2*L;         --- period

  ValCos,ValSin: Scalar_Array(0 .. T-1);
  CTmp: Scalar renames ValCos(0);
  STmp: Scalar renames ValSin(0);
  PiOverL: Scalar;
  
end Generic_DFT;
