function resample(tsin,timevec,varargin)
%RESAMPLE  Redefine a time series object on a new time vector
%
%   RESAMPLE(TS,TIMEVEC) resamples the time series object TS on the new
%   time vector TIMEVEC. When the time vector is numeric, it is assumed 
%   to be specified relative to the StartDate property in the same units as
%   the time-series object. When the time vector is an array of date 
%   strings then the absolute time vectors are combined. 
%
%   RESAMPLE(TS,TIMEVEC,INTERPOLATION_METHOD) resamples the time series
%   object using the interpolation method given by the string
%   INTERPOLATION_METHOD. Valid interpolation methods are 'linear' and
%   'zoh'.
%
%   RESAMPLE(TS,TIMEVEC,INTERPOLATION_METHOD,INTERPOLATION_CODE) resamples 
%   the time series object using the interpolation method given by the 
%   string INTERPOLATION_METHOD. Valid interpolation methods are 'linear' 
%   and 'zoh'. The integer INTERPOLATION_CODE is a user-defined indicator
%   of the quality of the interpolation.
%
%   See also TSDATA.TIMESERIES/MERGE, TSDATA.TIMESERIES/TIMESERIES

%   Authors: James G. Owen
%   Copyright 1986-2004 The MathWorks, Inc.
%   $Revision: 1.1.6.1 $  $Date: 2004/12/26 21:35:14 $
 
%% Get abs time reference and convert datastrs to a relative numeric
%% time vector
if iscell(timevec) || ischar(timevec)
    try
        ref = datenum(tsin.timeInfo.Startdate);
        t = tsunitconv(tsin.timeInfo.Units, 'days')*(datenum(timevec) - ref);
    catch
        error('timeseries:resample:norel', ...
            'Resampling using datestrs requires that the time-series object with an absolute time vector')
    end
%% Numeric time vector
elseif isnumeric(timevec) && length(timevec)>1
    t = timevec;
%% Time interval has been specified    
elseif isnumeric(timevec) && length(timevec)==1  
    if timevec<=0 
        error('timeseries:resample:interval', ...
            'Time interval has zero or negative length')
    end
    t = tsin.timeInfo.Start:timevec:tsin.timeInfo.End;
else
    error('timeseries:resample:badtime','Invalid time vector')
end

%% Parse additional inputs
if nargin>=3 && ~isempty(varargin{1})
    if ischar(varargin{1}) % Interpolation method specified by a string
        interpobj = tsdata.interpolation(varargin{1});
    elseif isa(varargin{1},'tsdata.interpolation')
        interpobj = varargin{1};
    else
        error('timeseries:interp:invinterp',...
            'Invalid specification of interpolation method')
    end
else
    interpobj = tsin.dataInfo.Interpolation;
end
if nargin>=4 && ~isempty(varargin{2})
    if isempty(tsin.Quality)
        error('timeseries:resample:noqual','Quality vector must be initialized')
    end
    if isnumeric(varargin{2}) && isscalar(varargin{2}) && varargin{2}>=0
        if floor(varargin{2})-varargin{2}<0
            warning('Data status code has been converted to an integer')
        end
        modcode = floor(varargin{2});
    else
        error('timeseries:resample:invcode','Invalid data status code')
    end
else
    modcode = [];
end

%% Check that the specified quality code is valid
if ~isempty(modcode) && ~any(modcode==tsin.QualityInfo.Code)
    error('timeseries:interp:absentcode',...
        'Data status code has not been defined in the qualitymetadata')
end

%% Cast data as doubles to avoid non-double arithmetic
if isa(tsin.data,'tsdata.ArrayAdaptor') || ~isfloat(tsin.data)
    tsin.data = double(tsin.data);
end

%% Interpolate, taking into account the dimension aligned with time
if tsin.dataInfo.GridFirst
    dataout = interpobj.interpolate(tsin.time, ...
        tsin.data,t);
else
    dataout = interpobj.interpolate(tsin.time, ...
        tsin.data,t,ndims(tsin.data));
end
 
%% Update the quality vector
if ~isempty(modcode)
    newqual = utQualityVector(tsin,dataout,t,modcode);
else
    newqual = utQualityVector(tsin,dataout,t);
end

%% Build output time series of whatever class
if tsin.getGridSize(1)~=length(t)
    tsin.init(dataout,t);
else
    set(tsin,'Time',t,'Data',dataout)
end

tsin.Quality = newqual;


