function [ut t G c]= timedec10(tk, delta, Omega, b, method, htext_msg)
%timedec10.m
%Anmo Kim
%June 26th, 2007
%time decoding machine with integrate and fire model with R=\infty in
%if an ISI longer than the required one for perfect recovery, 'divide uniformly' 
%input is assumed to be absolutely positive and has an infimum $a >0$
%tk : sequence of spike timings
%delta : a spike threshold
%Omega : the bandwidth of u(t); i.e. $u(t) \in PW(\Omega)$
%a : infimum of u(t)
%method : 'riemann' - computing integral with Riemann sum
%         'quad' - use 'adaptive Simpson quadrature' method for
%                  computing integral
%         if nothing designated, 'quad' is to be used




%initialization part ------------------------------------------------------
ut=[]; t=[]; G=[]; Ginv=[]; c=[];
if(nargin<6)
    htext_msg=[];
end

if(nargin<4)
   warn6('timedec10: wrong input argumnents\n u = timedec10(sk, delta, Omega, a, algorithm)', htext_msg);
   return;
end


if(nargin==4)
   method='riemann';
elseif(~strcmpi(method,'riemann'))
   method='quad';
end


% if(delta > a*pi/Omega)
%    warn6('timedec10: delta value does not satisfy the perfect recovery condition',htext_msg);
% end


if(length(tk) < 2)
   warn6('timedec10: a single spike cannot be decoded',htext_msg);
   return;
end

if(size(tk,2)==1) tk=tk'; end %tk becomes a row vector

dt = pi/Omega/200; % 200 samples per a zero-to-zero interval of g(.)

maxisi=pi/Omega*.9; %perfect recovery condition

%making the size of delta the same as the length of tk
if(length(delta)>length(tk)) delta=delta(1:(length(tk)));
else
   delta((end+1):(length(tk)))=delta(end);
end

if(size(delta,1)>1) delta=delta'; end



tk0=tk;
isi=diff(tk0);
underk=find(isi>maxisi);
while(~isempty(underk))
    for i=1:length(underk)
        if(underk(i)==1 || underk(i)==length(tk0)-1)
            tk=[tk(1:(underk(i)-1+i)) (tk(underk(i)-1+i)+tk(underk(i)+i))/2 tk(((underk(i)+i)):end)];
        else
            %linear interpolation
            tk=[tk(1:(underk(i)+i-1)) (tk0(underk(i))+isi(underk(i))*...
                (tk0(underk(i))-tk0(underk(i)-1))/(tk0(underk(i)+2)-...
                tk0(underk(i)+1)+tk0(underk(i))-tk0(underk(i)-1))) tk(((underk(i)+i)):end)];
        end
        delta=[delta(1:(underk(i)-1+i)) delta(underk(i)+i)/2 delta(underk(i)+i)/2 delta(((underk(i)+i+1)):end)];
    end
    tk0=tk;
    isi=diff(tk0);
    underk=find(isi>maxisi);
end



% k=1;
% tk0=tk;
% k0=1;
% while(k<length(tk))
%    if(tk(k+1)-tk(k)>maxisi)
%        if(k==1 || k==length(tk))
%           tk=[tk(1:k) (tk(k)+tk(k+1))/2 tk((k+1):end)];
%        else
%            %linear interpolation
%           tk=[tk(1:k) tk(k)+(tk(k0)-tk(k0-1))/(tk(k0+2)-tk(k0+1)+tk(k0)-tk(k0-1)) tk((k+1):end)];
%        end
%       delta=[delta(1:(k-1)) delta(k)/2 delta(k)/2 delta((k+1):end)];
%       %k=k; %check it back whether new intervals are appropriate
%    else
%       k=k+1;k0=k0+1;
%    end
% end



%sk = (tk(1:(end-1))+tk(2:end))./2;
sk=linspace((tk(2)+tk(1))./2, (tk(end)+tk(end-1))/2, ceil(Omega/pi*(tk(end)-tk(1))));

%t=max(0,tk(1)-3*pi/Omega):dt:(tk(end)+3*pi/Omega);
t=(tk(1)-3*pi/Omega):dt:(tk(end)+3*pi/Omega);
lent=length(t);


if(strcmp(method,'quad'))
%use 'adaptive Simpson quadrature' method for
%                  computing integral

warn6('timedec10:simpson quadrature integration not implemented yet', htext_msg);

else
   t0 = t(1):dt:(2*tk(end)-tk(1)+3*pi/Omega+1);
   gsk0 = sinc(Omega./pi.*(t0-sk(end))).*Omega./pi; %g(sk(end))
  
   GSK0 = cumsum(gsk0).* dt;
%    GSK0=sinint(Omega.*(t0-sk(end)))./Omega;
   ti = round((tk-t0(1))/dt)+1;
%   si = round((ti(1:(end-1))+ti(2:end))./2);
   si=round((sk-t0(1))/dt)+1;   
   for k=1:length(si)
      G(:,k)=(GSK0(ti(2:end)+si(end)-si(k))-GSK0(ti(1:(end-1))+si(end)-si(k)))';
   end
   Ginv = pinv(G); %Moore-penrose pseudo inverse matrix
   if(size(tk,2)>1) tk=tk';end
   q=delta(2:end)'-b*diff(tk);

   c = Ginv*q;

   ut=zeros(size(t));
   
   for k=1:length(si)
      ut = ut +c(k).*gsk0((1:length(t))+si(end)-si(k));
   end
end


% gsk3 = repmat(gsk, [1 1 length(sk)]);
% 
% 
% onoff=zeros([1 size(gsk,2) size(gsk,1)]);
% for k=1:length(sk)
%   onoff(1, (round(tk(k)/dt):round(tk(k+1)/dt)), k)=1;
% end
% 
% onoff3 = repmat(onoff, [length(sk) 1 1]);



%display warning either on matlab command prompt or on text_msg gui control
function warn6(s,htext_msg)
if(nargin<1) return; end
if(isempty(s)) return; end

if(nargin<2)
   disp(s,htext_msg);
   return;
end

if(isempty(htext_msg))
   disp(s);
   return;
end

if(ishandle(htext_msg))
   set(htext_msg, 'String',s);
else
   disp(s);
end