function tspanel(h)

localBuildPanel(h);
h.addlisteners(handle.listener(h.getRoot.Tsviewer.Tsnode,'ObjectChildAdded',...
    {@localUpdateTables h}));
h.addlisteners(handle.listener(h.getRoot.Tsviewer.Tsnode,'ObjectChildRemoved',...
    {@localUpdateTables h}));


h.addlisteners(handle.listener(h,'tschanged',...
    {@localUpdateTsBoxes h}));
localUpdateTsBoxes([],[],h)
localUpdateTables([],[],h)

function localBuildPanel(h)

import javax.swing.*;

%% X axis panel
h.Handles.PNLXts = uipanel('Parent',h.Handles.PNLTs,'Units','Characters','Bordertype','none');
h.Handles.LBLtsxlabel = uicontrol('Style','text','String','Time series aligned with X axis',...
    'HorizontalAlignment','left','Parent',h.Handles.PNLXts,'Units','characters');
h.Handles.BTNtsx= uicontrol('Style','pushbutton','String','Select',...
    'Parent',h.Handles.PNLXts,'Units','characters');
h.Handles.TXTtsx = uicontrol('Style','edit','HorizontalAlignment','left',...
    'Parent',h.Handles.PNLXts,'Units','characters','Backgroundcolor',[1 1 1]);
set(h.Handles.TXTtsx,'Callback',{@localAddTs h.Handles.TXTtsx h 'x'})
[h.Handles.tsTableX, h.Handles.PNLTsTableX] = tsuitable(cell(0,2),...
    {'Name','Number of Columns'},'Parent',ancestor(h.Handles.PNLXts,'figure'));
h.Handles.tsTableX.Editable = false;
set(h.Handles.PNLTsTableX,'Parent',h.Handles.PNLXts,'Units','Characters')
set(h.Handles.BTNtsx,'Callback',{@localSelectTs h.Handles.tsTableX h.Handles.TXTtsx})   
%% Y axis panel
h.Handles.PNLYts = uipanel('Parent',h.Handles.PNLTs,'Units','Characters','Bordertype','none');
h.Handles.LBLtsylabel = uicontrol('Style','text','String','Time series aligned with Y axis',...
    'HorizontalAlignment','left','Parent',h.Handles.PNLYts,'Units','characters');
h.Handles.BTNtsy= uicontrol('Style','pushbutton','String','Select',...
    'Parent',h.Handles.PNLYts,'Units','characters');
h.Handles.TXTtsy = uicontrol('Style','edit','HorizontalAlignment','left',...
    'Parent',h.Handles.PNLYts,'Units','characters','Backgroundcolor',[1 1 1]);
set(h.Handles.TXTtsy,'Callback',{@localAddTs h.Handles.TXTtsy h 'y'});
[h.Handles.tsTableY, h.Handles.PNLTsTableY] = tsuitable(cell(0,2),...
    {'Name','Number of Columns'},'Parent',ancestor(h.Handles.PNLYts,'figure'));
h.Handles.tsTableY.Editable = false;
set(h.Handles.PNLTsTableY,'Parent',h.Handles.PNLYts,'Units','Characters')
set(h.Handles.BTNtsy,'Callback',{@localSelectTs h.Handles.tsTableY h.Handles.TXTtsy}) 
%drawnow
set(h.Handles.PNLXts,'ResizeFcn',{@localXYPnlResize h.Handles.LBLtsxlabel ...
    h.Handles.BTNtsx h.Handles.TXTtsx h.Handles.PNLTsTableX})
set(h.Handles.PNLYts,'ResizeFcn',{@localXYPnlResize h.Handles.LBLtsylabel ...
    h.Handles.BTNtsy h.Handles.TXTtsy h.Handles.PNLTsTableY})


%% Customize tables

awtinvoke(h.Handles.tsTableX.getTable,'setSelectionMode(I)',...
    ListSelectionModel.SINGLE_SELECTION);
awtinvoke(h.Handles.tsTableX.getTable,'setCellSelectionEnabled(Z)',false);
awtinvoke(h.Handles.tsTableX.getTable,'setRowSelectionAllowed(Z)',true);
awtinvoke(h.Handles.tsTableX.getTable,'setAutoResizeMode(I)',...
    JTable.AUTO_RESIZE_ALL_COLUMNS);
% awtinvoke(h.Handles.tsTableX.getTable,'setColumnEditable',0,0);
% awtinvoke(h.Handles.tsTableX.getTable,'setColumnEditable',1,0);
h.Handles.tsTableX.getTable.setColumnEditable(0,0);
h.Handles.tsTableX.getTable.setColumnEditable(1,0);
tsCustomizeUitable(h.Handles.tsTableX);
awtinvoke(h.Handles.tsTableY.getTable,'setSelectionMode(I)',...
    ListSelectionModel.SINGLE_SELECTION);
awtinvoke(h.Handles.tsTableY.getTable,'setCellSelectionEnabled(Z)',false);
awtinvoke(h.Handles.tsTableY.getTable,'setRowSelectionAllowed(Z)',true);
awtinvoke(h.Handles.tsTableY.getTable,'setAutoResizeMode(I)',JTable.AUTO_RESIZE_ALL_COLUMNS);
% awtinvoke(h.Handles.tsTableY.getTable,'setColumnEditable',0,0);
% awtinvoke(h.Handles.tsTableY.getTable,'setColumnEditable',1,0);
h.Handles.tsTableY.getTable.setColumnEditable(0,0);
h.Handles.tsTableY.getTable.setColumnEditable(1,0);
tsCustomizeUitable(h.Handles.tsTableY);
%% Set resize behavior
set(h.Handles.PNLTs,'ResizeFcn',{@localTsPanelResize h.Handles.PNLXts h.Handles.PNLYts})
localTsPanelResize(h.Handles.PNLXts,[],h.Handles.PNLXts,h.Handles.PNLYts)

function localXYPnlResize(thisPnl,ed,LBLts,BTNts,TXTts,PNLTsTable)

%% XY Panel resize callback

%% Make the table and edit box take up all the horizontal space
pos = get(thisPnl,'Position');
set(LBLts,'Position',[2 max(1,pos(4)-3.25) 35 1.5]);
set(TXTts,'Position',[35 max(1,pos(4)-3) max(1,pos(3)-38-17) 1.5]);
set(PNLTsTable,'Position',[2 2 max(1,pos(3)-23) max(1,pos(4)-6)]);
set(BTNts,'Position',[max(1,pos(3)-18) 2 15 1.5]);
%drawnow

function localTsPanelResize(PNLts,ed,PNLXts,PNLYts)

%% Resize fcn for the time series pane;

%% Get sizes and margins
bmargin = 1;
pos = get(PNLts,'Position');
pnlheight = (max(1,pos(4)-3*bmargin))/2;

%% Set positions
set(PNLXts,'Position',[bmargin 2*bmargin+pnlheight max(1,pos(3)-2*bmargin) pnlheight]);
set(PNLYts,'Position',[bmargin bmargin max(1,pos(3)-2*bmargin) pnlheight]);

function localUpdateTables(es,ed,h)

if ~isempty(ed) && strcmp(ed.Type,'ObjectChildRemoved')
    tsnodes = setdiff(h.getRoot.Tsviewer.Tsnode.getChildren,ed.Child);
else
    tsnodes = h.getRoot.Tsviewer.Tsnode.getChildren;
end
tableData = cell(size(tsnodes,1),2);
tableData = cell(size(tsnodes,1),2);
for k=1:length(tsnodes)
    tableData(k,:) = {tsnodes(k).Label sprintf('%d',size(tsnodes(k).Timeseries.Data,2))};
end    
h.Handles.tsTableY.setData(tableData);
h.Handles.tsTableX.setData(tableData);

function localSelectTs(es,ed,tsTable,TXTts)

selectedRow = tsTable.getTable.getSelectedRow+1;
if selectedRow>0 % Use {} so that 'default' will show
    set(TXTts,'String',{tsTable.Data(selectedRow,1)})
end
returncallback = get(TXTts,'Callback');
feval(returncallback{1},[],[],returncallback{2:end});

function localAddTs(es,ed,TXTts,h,pos)

%% Callback for x and y time series text boxes
tsnodes = h.getRoot.Tsviewer.Tsnode.getChildren;
ind = find(strcmp(deblank(get(TXTts,'String')),get(tsnodes,{'Label'})));
if ~isempty(ind)
    h.addTs(tsnodes(ind(1)).Timeseries,pos);
elseif strcmpi(pos,'x') && ~isempty(h.Timeseries1)
    h.removets(h.Timeseries1)
elseif strcmpi(pos,'y') && ~isempty(h.Timeseries2)
    h.removets(h.Timeseries2)
end

function localUpdateTsBoxes(es,ed,h)

%% Callback for the listeners to the Timeseries1 and Timeseries2 properties
%% which update the edit boxes
if ~isempty(h.Timeseries2)
    set(h.Handles.TXTtsy,'String',{h.Timeseries2.Name});
else
    set(h.Handles.TXTtsy,'String','');
end
if ~isempty(h.Timeseries1)
    set(h.Handles.TXTtsx,'String',{h.Timeseries1.Name});
else
    set(h.Handles.TXTtsx,'String','');
end