function g = lappedwindow(wLength,tailLength,tailFunc,special)
%LAPPEDWINDOW Lapped window used for lapped orthogonal transform
%
% g = lappedwindow(wLength,tailLength,tailFunc,special)
%
% returns the window g used in the lapped orthogonal transform
%
% INPUT:
% - wLength: length of the window
% - tailLength: length of the tail of the overlapping window. 
%
%     ......................
%   |.                      .|
%   .                        .
%  .|                        |.
% . |---------wLength--------| .
%                            |-| 
%                         tailLength
%
% The maximum tailLength cannot exceed half the window length. 
% - tailFunc: either a string or a function handle used to define the tails
% of the overlapping windows. The default is 'sin2' (twicely differentiable
% sinusoidal).
%
% OUTPUT:
% - g: vector containing the window
%
% REFERENCE:
% S. Mallat, A Wavelet Tour of Signal Processing
%
% SEE ALSO
% lappedorthobasis, lappedorthotransform
%
% ----------------------------------------------------------- %
%  Daniele Barchiesi, daniele.barchiesi@eecs.qmul.ac.uk       %
%  Centre for Digital Music, Queen Mary University of London  %
%  Apr. 2011                                                  %
% ----------------------------------------------------------- %

%% Check inputs
error(nargchk(2, 4, nargin, 'struct'));
if ~exist('special','var') || isempty(special), special = []; end
if ~exist('tailFunx','var') || isempty(tailFunc), tailFunc = 'sin2'; end

%check that the window is not too short
if wLength<2*tailLength
    error('the window length must be at least twice as long as the tail length');
end

%manage tail function
if ischar(tailFunc)
    [fname iter] = parsefunctionname(tailFunc);
    switch lower(fname)
        case 'sin'
            tailFunc = @(x)sin((pi/4)*(x+1));
        otherwise
            error('invalid tail function');
    end
    if iter
        for i=1:iter
            tailFun = @(x)tailFun(sin(pi*x/2));
        end
    end
else %if a function handler, check that it corresponds to a valid tail.
    t = linspace(-1,1,1000);
    test = norm((tailFunc(t).^2)+(tailFunc(fliplr(t)).^2)-ones(1,length(t)));
    if test>1e-8
        error('invalid tail function');
    end
end

%% construct the window
if ~isempty(special)
    g = ones(wLength+tailLength,1);
    g(1:2*tailLength) = tailFunc((-tailLength+0.5:tailLength-0.5)'/tailLength);
    if strcmpi(special,'first')
        g = flipud(g);
    end
else
    g = ones(wLength+2*tailLength,1);
    g(1:2*tailLength) = tailFunc((-tailLength+0.5:tailLength-0.5)'/tailLength);
    g(wLength+1:wLength+2*tailLength) = ...
        flipud(tailFunc((-tailLength+0.5:tailLength-0.5)'/tailLength));
end

function [fname iter] = parsefunctionname(tailFunc)
nameLen = length(tailFunc);
for i=1:nameLen
    if real(str2double(tailFunc(i)))>0
        fname = tailFunc(1:i-1);
        iter = uint16(str2double(tailFunc(i:end)));
        return
    end
end
fname = tailFunc;
iter = [];