function thisTab = timepnl(view,h)

import com.mathworks.toolbox.timeseries.*;

%% Build time panel
TimePnl = tsDomainTimePanel;
thisTab = struct('Name','Domain','Handles',[]);
h.Handles.TimePnl = TimePnl;
thisTab.Name = 'Domain';
h.Tabs = [h.Tabs; thisTab];
h.Handles.TabPane.add('Define Domain',TimePnl);     

%% Get time/date format
[formatstrs,absstatus] = tsgetDateFormat;
relformats = [get(findtype('TimeUnits'),'String');formatstrs(~[absstatus{:}])];
absformats = formatstrs([absstatus{:}]);
TimePnl.relformats = relformats;
TimePnl.absformats = absformats;

%% Get the initial state of the view
[isformatted,absflag] = tsIsDateFormat(view.TimeFormat);
if strcmp(view.Absolutetime,'off')
    % Set relative time
    %TimePnl.RADIORelTime.setSelected(true);
    % Set the units/format
    if ~absflag
        ind = find(strcmp(view.TimeFormat,relformats));    
    elseif isformatted
        ind = find(strcmp(view.TimeUnits,relformats));
    else
        ind = 1;
    end
    TimePnl.setabstimemode(false,ind-1);
    %TimePnl.COMBformatunits.setSelectedIndex(ind-1);
else
    % Set abs time
    %TimePnl.RADIOAbsTime.setSelected(true);
    % Set the units/format
    if absflag && isformatted
        ind = find(strcmp(view.TimeFormat,absformats));    
    else
        ind = 1;
    end
    TimePnl.setabstimemode(true,ind-1);
end    
    
%% Set the callbacks
set(handle(TimePnl.TXTEndTime,'callbackproperties'),...
    'ActionPerformedCallback',{@localTimeUpdate h view})
set(handle(TimePnl.TXTEndTime,'callbackproperties'),...
    'FocusLostCallback',{@localTimeUpdate h view})
set(handle(TimePnl.TXTStartTime,'callbackproperties'),...
    'ActionPerformedCallback',{@localTimeUpdate h view})
set(handle(TimePnl.TXTStartTime,'callbackproperties'),...
    'FocusLostCallback',{@localTimeUpdate h view})
set(handle(TimePnl.RADIOStartTime,'callbackproperties'),...
    'ActionPerformedCallback',{@localTimeUpdate h view})
set(handle(TimePnl.RADIOStartEvent,'callbackproperties'),...
    'ActionPerformedCallback',{@localTimeUpdate h view})
set(handle(TimePnl.RADIOEndTime,'callbackproperties'),...
    'ActionPerformedCallback',{@localTimeUpdate h view})
set(handle(TimePnl.RADIOEndEvent,'callbackproperties'),...
    'ActionPerformedCallback',{@localTimeUpdate h view})
set(handle(TimePnl.BTNStartCal,'callbackproperties'),...
    'ActionPerformedCallback',{@localCalendar h 'start' view})
set(handle(TimePnl.BTNEndCal,'callbackproperties'),...
    'ActionPerformedCallback',{@localCalendar h 'end' view})
set(handle(TimePnl.RADIOAbsTime,'callbackproperties'),...
    'ActionPerformedCallback',{@localAbsRelChange h view})
set(handle(TimePnl.RADIORelTime,'callbackproperties'),...
    'ActionPerformedCallback',{@localAbsRelChange h view})
set(handle(TimePnl.COMBformatunits,'callbackproperties'),...
    'ActionPerformedCallback',{@localUnitChange h view})


%% Fire the time type button group callback
if strcmp(view.Absolutetime,'on')
   view.settimemode(h,'absolute') 
else
   view.settimemode(h,'relative')
end

%% Get time axes limits
view.updatetime(h)


function localTimeUpdate(eventSrc,eventData,h,view)

%% Callback for start and end time edit boxes which updates the AxesGrid

%% If in abs time mode re-format the datstrs
if h.Handles.TimePnl.RADIOAbsTime.isSelected
    % Get the selected format
    thisformat = h.Handles.TimePnl.COMBformatunits.getSelectedItem;
    
    % Try to parse any datastrs
    [junk,absflag] = tsIsDateFormat(thisformat);
    try
        if ~isempty(view.TimeFormat)
            starttime = (datenum(char(h.Handles.TimePnl.TXTStartTime.getText),view.TimeFormat)...
                 -datenum(view.Startdate))*tsunitconv(view.TimeUnits,'days');
        else    
            starttime = (datenum(char(h.Handles.TimePnl.TXTStartTime.getText))...
                 -datenum(view.Startdate))*tsunitconv(view.TimeUnits,'days');
        end
    catch 
        errordlg('Invalid start time','Time Series Tool','modal')
        return
    end    
    try
        if ~isempty(view.TimeFormat)
             endtime = (datenum(char(h.Handles.TimePnl.TXTEndTime.getText),view.TimeFormat)...
                 -datenum(view.Startdate))*tsunitconv(view.TimeUnits,'days');           
        else
             endtime = (datenum(char(h.Handles.TimePnl.TXTEndTime.getText))...
                 -datenum(view.Startdate))*tsunitconv(view.TimeUnits,'days');
        end
    catch
       errordlg('Invalid end time','Time Series Tool','modal')
       return
    end
else % Relative mode
    if h.Handles.TimePnl.RADIOStartTime.isSelected
        thisformat =  h.Handles.TimePnl.COMBformatunits.getSelectedItem;
        % Try to parse any datastrs
        if tsIsDateFormat(thisformat)
             starttime = datenum(char(h.Handles.TimePnl.TXTStartTime.getText))...
                 -datenum('00:00:00');
             starttime = tsunitconv(view.TimeUnits,'days')*starttime;
        else
             starttime = str2num(char(h.Handles.TimePnl.TXTStartTime.getText));
             if isempty(starttime)
                errordlg('Invalid start time','Time Series Tool','modal')
                return
             end
        end
    else
        eventlist = view.Parent.getevents;
        thisevent = eventlist(h.Handles.TimePnl.COMBOStartEvent.getSelectedIndex+1);
        starttime = thisevent.Time*tsunitconv(view.TimeUnits,thisevent.Parent.TimeInfo.Units);
    end
    if h.Handles.TimePnl.RADIOEndTime.isSelected
        thisformat =  h.Handles.TimePnl.COMBformatunits.getSelectedItem;
        % Try to parse any datastrs
        if tsIsDateFormat(thisformat)
             endtime = datenum(char(h.Handles.TimePnl.TXTEndTime.getText))...
                 -datenum('00:00:00');
             endtime = tsunitconv(view.TimeUnits,'days')*endtime;
        else
            endtime = str2num(char(h.Handles.TimePnl.TXTEndTime.getText));
             if isempty(endtime)
                errordlg('Invalid end time','Time Series Tool','modal')
                return
             end
        end
    else
        eventlist = view.Parent.getevents;
        thisevent = eventlist(h.Handles.TimePnl.COMBOEndEvent.getSelectedIndex+1);
        endtime = thisevent.Time*tsunitconv(view.TimeUnits,thisevent.Parent.TimeInfo.Units);
    end
end

if endtime>starttime
    view.AxesGrid.setxlim([starttime endtime]);
else
    errordlg('Time vector has zero or negative length','Time Series Tool','modal')
end

function localCalendar(eventSrc,eventData,h,type,view)

%% Calendar button callback

%% The Calendar dialog is a singleton for the @tsnode. If one does not
%% yet exist, create it
if isempty(h.Calendar)
    h.Calendar = tsguis.calendar;
    
    % Add calendar listeners (including the one to this @tsnode being
    % destroyed)
    h.Calendar.Parent = h;
    h.Calendar.generic_listeners
end

%% Parent the calendar to the current @tsnode
h.Calendar.Parent = h;
h.Calendar.Type = type;

%% The opening date is either the start/end date of an absolute time vector or
%% "now" if the time vector is relative
if ~isempty(view.StartDate)
    try
        if strcmp(type,'start')
            h.Calendar.DateNum = datenum(char(h.Handles.TimePnl.TXTStartTime.getText));
        else
            h.Calendar.DateNum = datenum(char(h.Handles.TimePnl.TXTEndTime.getText));
        end
    catch
         h.Calendar.DateNum = datenum(now);
    end
else
    h.Calendar.DateNum = datenum(now);
end


%% Set the updatefcn
h.Calendar.updatefcn = {@localcalendarwrite h type view};

%% Open the calendar
h.Calendar.Visible = 'on';

function localAbsRelChange(es,ed,h,view)

%% Callback to the absolute/relative time radio buttons

if h.Handles.TimePnl.RADIORelTime.isSelected
    view.settimemode(h,'relative')
    view.Absolutetime = 'off';
else
    view.settimemode(h,'absolute');
    view.TimeFormat = 'dd-mmm-yyyy HH:MM:SS';
    if isempty(view.StartDate)
        view.StartDate = datestr(floor(now));
    end
    view.Absolutetime = 'on';
end


%% Refresh
S = warning('off','all'); % Disable "Some data is missing @resppack warn..."
view.draw;
warning(S);

function localcalendarwrite(h,type,view)

%% Update function used by the calendar dialog to update the time domain
%% panel

%% Get the selected format
thisformat = h.Handles.TimePnl.COMBformatunits.getSelectedItem;

%% Write formatted data to the start/end time edit boxes
if strcmp(type,'start')
    h.Handles.TimePnl.TXTStartTime.setText(datestr(h.Calendar.Datenum,thisformat));
else
    h.Handles.TimePnl.TXTEndTime.setText(datestr(h.Calendar.Datenum,thisformat));
end

%% Update the @timeplot with the new limits
localTimeUpdate([],[],h,view)

function localUnitChange(es,ed,h,view)

%% Format/units combo callback. Note that the view change listener will
%% call the refresh method which will update the start and edn edit boxes
%% to the right format

%% Get the selected format
thisformat = h.Handles.TimePnl.COMBformatunits.getSelectedItem;

if ~isempty(view)
     % Set the @timeplot format 
    view.TimeFormat = thisformat;
    if h.Handles.TimePnl.RADIOAbsTime.isSelected  
         % Set the @timeplot format 
         view.TimeFormat = thisformat;
         view.Axesgrid.send('Viewchange')
    else % Relative time mode so set the @timeplot TimeUnits
         if any(strcmp(thisformat,get(findtype('TimeUnits'),'Strings')))
             view.TimeFormat = '';
             view.TimeUnits = thisformat; % thisformat could be a relative datestr
         end
         S = warning('off','all'); % Disable "Some data is missing @resppack warn..."
         view.draw;
         warning(S);
    end
end

