function [f]=idgt2(c,g1,p3,p4,p5)
%IDGT2  2D Inverse discrete Gabor transform
%   Usage: f=idgt2(c,g,a);
%          f=idgt2(c,g1,g2,a);
%          f=idgt2(c,g1,g2,[a1 a2]);
%          f=idgt2(c,g,a,Ls);
%          f=idgt2(c,g1,g2,a,Ls);
%          f=idgt2(c,g1,g2,[a1 a2],Ls);
%
%   Input parameters:
%         c       : Array of coefficients.
%         g,g1,g2 : Window function(s).
%         a,a1,a2 : Length(s) of time shift.
%         Ls      : Length(s) of reconstructed signal (optional).
%
%   Output parameters:
%         f       : Output data, matrix.
%
%   `idgt2(c,g,a,M)` will calculate a separable two dimensional inverse
%   discrete Gabor transformation of the input coefficients *c* using the
%   window *g* and parameters *a*, along each dimension. The number of channels
%   is deduced from the size of the coefficients *c*.
%
%   `idgt2(c,g1,g2,a)` will do the same using the window *g1* along the first
%   dimension, and window *g2* along the second dimension.
%
%   `idgt2(c,g,a,Ls)` or `idgt2(c,g1,g2,a,Ls)` will cut the signal to size *Ls*
%   after the transformation is done.
%
%   The parameters *a* and *Ls* can also be vectors of length 2.
%   In this case the first element will be used for the first dimension
%   and the second element will be used for the second dimension. 
%
%   See also:  dgt2, gabdual

%   AUTHOR : Peter L. Søndergaard

complainif_argnonotinrange(nargin,3,5,mfilename);

if ndims(c)<4 || ndims(c)>5
  error('c must be 4 or 5 dimensional.');
end;

doLs=0;

switch nargin
  case 3
    g2=g1;
    a=p3;
  case 4
    if prod(size(p3))>2
      % Two windows was specified.
      g2=p3;
      a=p4;
    else
      g2=g1;
      a=p3;
      Ls=p4;
      doLs=1;
    end;
  case 5
    g2=p3;
    a=p4;
    Ls=p5;
    doLs=1;
end;

if size(g1,2)>1
  if size(g1,1)>1
    error('g1 must be a vector');
  else
    % g1 was a row vector.
    g1=g1(:);
  end;
end;

if size(g2,2)>1
  if size(g2,1)>1
    error('g2 must be a vector');
  else
    % g2 was a row vector.
    g2=g2(:);
  end;
end;

if prod(size(a))>2 || prod(size(a))==0
  error('a must be a scalar or 1x2 vector');
end;

if length(a)==2
  a1=a(1);
  a2=a(2);
else
  a1=a;
  a2=a;
end;

Lwindow1=size(g1,1);
Lwindow2=size(g2,1);

M1=size(c,1);
N1=size(c,2);
M2=size(c,3);
N2=size(c,4);
W=size(c,5);

L1=a1*N1;
L2=a2*N2;

% Length of window must be dividable by M.
% We cannot automically zero-extend the window, as it can
% possible break some symmetry properties of the window, and we don't
% know which symmetries to preserve.
if rem(Lwindow1,M1)~=0
  error('Length of window no. 1 must be dividable by M1.')
end;

if rem(Lwindow2,M2)~=0
  error('Length of window no. 2 must be dividable by M2.')
end;
    


% --- first dimension

% Change c to correct shape.
c=reshape(c,M1,N1,M2*N2*W);

c=comp_idgt(c,g1,a1,[0 1],0,0);

% Check if Ls was specified.
if doLs
  c=postpad(c,Ls(1));
else
  Ls(1)=L1;
end;

% Change to correct size
c=reshape(c,Ls(1),M2*N2,W);

% Exchange first and second dimension.
c=permute(c,[2,1,3]);

% --- second dimension

% Change c to correct shape.
c=reshape(c,M2,N2,Ls(1)*W);

c=comp_idgt(c,g2,a2,[0 1],0,0);

% Check if Ls was specified.
if doLs
  c=postpad(c,Ls(2));
else
  Ls(2)=L2;
end;

% Change to correct size
c=reshape(c,Ls(2),Ls(1),W);

% Exchange first and second dimension.
f=permute(c,[2,1,3]);

