function [imptext, implatex, impseq, impseqlatex, impeqnarray, impeqnseq] = imp2latex(h, N, offset, strch)
% IMP2LATEX prints impulse response in text and LaTeX
%
%   [impt1, impl1, imps1, imps2, impe1, impe2] = imp2latex(h, N, offset, string)
%
%    imptext     h[n] as text: h[n] = delta[n] ...
%    implatex    h[n] as LaTeX code: $h[n] = \delta[n] ...
%    impseq      h[n] as a sequence: h[n] = {_1_, ...
%    impseqlatex h[n] as a sequence: $h[n] = {\underline{1}, ...$
%    impeqarrayx h[n] as with delta: h[n] &=& \delta[n] + ... \\
%    impeqnseq   h[n] as a sequence: h[n] &=& \{\underline{1}, ...
%    h           impulse response
%    N           number of samples in IIR h[n] shown;
%                if vector, then N = length(N), and offset = N(1)
%    offset      first nonzero element (from left) is h[offset];
%                if vector, then offset(1) is offset value above
%    strch       char, symbol of the sequence, default 'h'
%
% IMP2LATEX does NOT compute values of impulse response,
% that must be done in advance by using IMPZ.
%
% IMP2LATEX can be used to print any sequence with delta
% notation.
%
% The additional dots "..." are added if length(h) > N,
% i.e. having an infinite long sequence,
% probably the case when having IIR. 
% 
% Example:
%    x = randn(100,1);          % random sequence
%    imp2latex(x, 50, 6)        % 50 *first* samples starting from 6
%    imp2latex(x(1:50), 50, -2) % 50 samples starting from -2
%
% Example:
%    h = [1  -2 0 1];               % FIR
%    n = [-1  0 1 2];
%    stem(n, h);                    % plot
%    imp2latex(h, 10, -1)           % either max 10 samples ...
%    [txt, ltxt] = imp2latex(h, n)  % or using "n"
%
% Example:
%    B = [1 0 0 1];
%    A = [1 0.5];                   % B & A --> IIR
%    impz(B, A, 10);                % plot
%    [h,n] = impz(B, A, 10)         % compute values into h
%    imp2latex(h, n(1:9))
%    [txt, ltxt] = imp2latex(h, 5)
%
% Example:
%    [txt, ltxt] = imp2latex([3 2 4 5], 4, -1, 'x');
%                                   % x[n] = ...
%
% Jukka Parviainen, 16.2.2007 - 25.1.2007 - 2004


%%%%%%%%%%%%%%%%%%%%%%%%
%

% display('3.arg. antaa vaarin: kopsaa viimeisen luvun?!?!');

if nargin < 2
  error('Too few arguments');
elseif nargin == 2
  offset = 0;
  strch  = 'h';
end;

if nargin == 3
  strch  = 'h';
end;

if strcmp(class(strch), 'char')
  % strch = strch(1);   % halutaan usein 'x_1'
else
  error('4th argument "strch" must be char value, e.g. ''x''');
end;


lenH = length(h);

if (prod(size(N)) > 1)
  % N is a vector, actually n = [min_index ... max_index]
  % Now N = length(N) and offset = N(1), overrides possible third arg.
  offset = N(1);  
  N = length(N);
end;
% N is a scalar
% Now offset is set by third argument, 
%   by previous setting or by default 0 
if (lenH < N)
  % N is needed in the end, so copy the value to LN
  LN = lenH;
else
  LN = N;
end;
  
if (length(size(offset)) > 2)
  error('Offset has to be a scalar or a vector');
end;
if (prod(size(offset)) > 1)
  % offset is a vector
  offset = offset(1);
end;
% offset is now a scalar

% any zeros in the beginning of sequence?
dummy = find(h ~= 0);
if (dummy(1) > 1)
  % there are zeros in the beginning
  foo = min(dummy);
  % remove all zeros and update the counters
  h = h(foo:end);
  offset = offset + foo - 1;
  LN = LN - foo + 1;
end;

% First value
ind  = offset;

% Find a correct +/- for argument of delta[]
if (ind < 0)
  markS = ['+' num2str(abs(ind))];
elseif (ind > 0)
  markS = ['-' num2str(abs(ind))];
else
  markS = '';
end;
ind = ind+1;

% Write down "h[n] =" and the first non-zero item
if (h(1) == 1)
  Hstr = [strch '[n] = d[n' markS ']'];
  Lstr = [strch '[n] = \delta[n' markS ']'];
elseif (h(1) == -1)
  Hstr = [strch '[n] = -d[n' markS ']'];
  Lstr = [strch '[n] = -\delta[n' markS ']'];
elseif (h(1) < 0)
  Hstr = [strch '[n] = -' num2str(abs(h(1))) ' d[n' markS ']'];
  Lstr = [strch '[n] = -' num2str(abs(h(1))) ' \delta[n' markS ']'];
elseif (h(1) > 0)
  Hstr = [strch '[n] = ' num2str(h(1)) ' d[n' markS ']'];
  Lstr = [strch '[n] = ' num2str(h(1)) ' \delta[n' markS ']'];
elseif (h(1) == 0)
  % should not flow here
  Hstr = [strch '[n] ='];
  Lstr = [strch '[n] ='];
end;

% Write down the other items
for k = [2 : LN]
  tmp   = h(k);
  if (ind < 0)
    markS = ['+' num2str(abs(ind))];
  elseif (ind > 0)
    markS = ['-' num2str(abs(ind))];
  else
    markS = '';
  end;
  ind = ind+1;
    
  if (tmp == 1)
    Hstr = [Hstr ' + d[n' markS ']'];
    Lstr = [Lstr ' + \delta[n' markS ']'];    
  elseif (tmp == -1)
    Hstr = [Hstr ' - d[n' markS ']'];
    Lstr = [Lstr ' - \delta[n' markS ']'];    
  elseif (tmp == 0)
    % skip
    % ... or alternatively tmp>=0 ...?
  elseif (tmp > 0)
    Hstr = [Hstr ' + ', num2str(tmp), ' d[n' , markS ']'];
    Lstr = [Lstr ' + ', num2str(tmp), ' \delta[n' , markS ']'];
  else
    Hstr = [Hstr ' - ', num2str(abs(tmp)), ' d[n' , markS ']'];
    Lstr = [Lstr ' - ', num2str(abs(tmp)), ' \delta[n' , markS ']'];
  end
end;

% Add dots in case of IIR
if (lenH > N)
  Hstr = [Hstr ' + ...'];
  Lstr = [Lstr ' + \ldots'];
end;

% Only sequence
Tstr = [strch '[n] = {'];
% Neljä eri tapausta...
%
% x[n] = {_3_, 3, 3, 1}
% x[n] = {4, 3, -2, _3_}
% x[n] = {_0_, 0, 3, 4, ...}
% x[n] = {3, 4, 1, 0,_0_,...}
% x[n] = {2, _4_, 1}
%
if (offset) == 0
  % x[n] = {_3_, 3, 3, 1}
  Tstr = [Tstr '_' num2str(h(1)) '_, '];
  for k = [2 : length(h)-1]
    Tstr = [Tstr  num2str(h(k)) ', '];
  end;
  Tstr = [Tstr  num2str(h(end)) '}'];
elseif ((offset < 0) & (offset + N <= 0))
  % x[n] = {3, 4, 1, 0,_0_,...}
  Tstr = [Tstr ' '];
  for k = [1 : N]
    Tstr = [Tstr  num2str(h(k)) ', '];
  end;
  for k = [1 : abs(offset)-N]
    Tstr = [Tstr '0, '];
  end;
  Tstr = [Tstr '_0_}'];
elseif ((offset < 0) & (offset + N == 1))
  % x[n] = {4, 3, -2, _3_}
  Tstr = [Tstr ' '];
  for k = [1 : N-1]
    Tstr = [Tstr  num2str(h(k)) ', '];
  end;
  Tstr = [Tstr '_' num2str(h(end)) '_}'];
elseif (offset < 0)   
  % x[n] = {2, _4_, 1}
  for k = [1 : abs(offset)]
    Tstr = [Tstr  num2str(h(k)) ', '];
  end;
  Tstr = [Tstr '_' num2str(h(abs(offset)+1)) '_, '];
  for k = [abs(offset)+2 : N-1]
    Tstr = [Tstr  num2str(h(k)) ', '];
  end;
  Tstr = [Tstr num2str(h(end)) '}'];
elseif (offset > 0)
  % x[n] = {_0_, 0, 3, 4, ...}
  Tstr = [Tstr '_0_, '];
  for k = [2 : offset]
    Tstr = [Tstr  '0, '];
  end;
  for k = [1 : N-1]
    Tstr = [Tstr  num2str(h(k)) ', '];
  end;
  Tstr = [Tstr num2str(h(end)) '}'];
else
  error('Never should flow here');
end;

%% Tehdään Wstr-osio
[pv] = strfind(Tstr,'{');
[pw] = strfind(Tstr,'}');
[pp] = strfind(Tstr,'_');
Vstr = [Tstr(1:pv-1) '\' Tstr(pv:pp(end-1)-1)];  
% nyt ollaan nollakohdan alussa
Vstr = [Vstr '\underline{' Tstr(pp(end-1)+1:pp(end)-1) '}' ];
% nyt ollaan ohitettu nollakohta
Vstr = [Vstr Tstr(pp(end)+1:pw-1) '\' Tstr(pw:end)];

[pc] = strfind(Vstr,',');
pc(end+1) = length(Vstr);
Wstr = [Vstr(1:pc(1))];
for k = 1 :length(pc)-1
  Wstr = [Wstr ' \ ' Vstr(pc(k)+1:pc(k+1))];
end;

%% Tehdään eqnarray-osio deltamerkinälle
[pv] = strfind(Lstr,'$');  % 2kpl
ind = setxor([1:length(Lstr)], pv);
Estr = Lstr(ind);
[pw] = strfind(Estr,'=');  % 1kpl
Estr = [Estr(1:pw(1)-1) '&=&' Estr(pw(1)+1:end)];

%% Tehdään eqnarray-osio jonomerkinälle
[pv] = strfind(Wstr,'$');  % 0-2kpl
ind = setxor([1:length(Wstr)], pv);
Xstr = Wstr(ind);
[pw] = strfind(Xstr,'=');  % 1kpl
Xstr = [Xstr(1:pw(1)-1) '&=&' Xstr(pw(1)+1:end)];


imptext  = Hstr;
implatex = ['$' Lstr '$'];i
impseq = Tstr;
impseqlatex = ['$' Wstr '$'];
impeqnarray = Estr;
impeqnseq = Xstr;
