function varargout = edit(varargin)

if isempty(varargin)
   ff = gcf();
   h = getappdata(ff,'handles');
   range = getappdata(ff,'range');
   varargout{1} = tseries(range,get(h.table,'data'));
   return
end

varname = varargin{1};
x = evalin('base',varname);
varargin{1} = [];
range = x.start : x.start + size(x.data,1) - 1;
data = x.data(:,:);
rowname = dat2str(range);

colname = x.Comment(1,:);
ncol = size(colname,2);

xsize = size(x.data);
tempsize = xsize;
tempsize(1) = 1;
pos = cell([1,length(tempsize)]);
[pos{:}] = ind2sub(tempsize,(1:prod(tempsize)).');
pos = [pos{2:end}];
for i = 1 : ncol
   colname{i} = ...
      [varname,'(:',sprintf(',%g',pos(i,:)),') ',sprintf('\n'),colname{i}];
end
colwidth = cell([1,ncol]);
colwidth(:) = {90};

ff = figure('menuBar','none');
tt = uitable('units','normalized', ...
   'position',[0.05,0.05,0.9,0.9], ...
   'data',data, ...
   'columnWidth',colwidth, ...
   'columnEditable',true, ...
   'columnFormat',{'numeric','numeric'}, ...
   'rowName',rowname, ...
   'columnName',colname);

handles = struct();
handles.table = tt;
setappdata(ff,'handles',handles);

setappdata(tt,'range',range);
setappdata(tt,'varName',varname);
setappdata(tt,'selection',[NaN,NaN]);
c = contextmenu_();
set(tt,'cellEditCallback',@updateoutside_, ...
   'cellSelectionCallback',@selected_, ...
   'uicontextmenu',c);
end

function updateoutside_(tt,event)
   if ~isnan(event.NewData)
      varname = getappdata(tt,'varName');
      format = '%s.data(%g,%g) = %.16f;';
      expression = sprintf(format, ...
         varname,event.Indices(1),event.Indices(2),event.NewData);
      evalin('base',expression);
   else
      keyboard
   end
end

function selected_(tt,event)
   selection = event.Indices;
   setappdata(tt,'selection',selection);
end

function c = contextmenu_()
   c = uicontextmenu();
   uimenu(c,'label','Paste','callback',@paste_);
end

function paste_(uu,event)
   ff = gcf();
   handle = getappdata(ff,'handles');
   tt = handle.table;
   selection = getappdata(tt,'selection');
   newdata = clipboard('paste');
   newdata = str2num(newdata);
   varname = getappdata(tt,'varName');
   format = '%s.data(%g,%g) = %.16f;';
   expression = sprintf(format, ...
      varname,selection(1),selection(2),newdata);
   evalin('base',expression);
   data = get(tt,'data');
   data(selection(1),selection(2)) = newdata;
   set(tt,'data',data);
end