function varargout = arrayviewfunc(whichcall, varargin)
%ARRAYVIEWFUNC  Support function for Array Editor component

%   Copyright 1984-2004 The MathWorks, Inc.
%   $Revision: 1.1.6.10 $  $Date: 2004/10/22 19:42:54 $

varargout = cell(1, 1);
  switch whichcall
    case 'getdata',
      varargout{1} = getData(varargin{1}, varargin{2});
    case 'setdata',
      varargout{1} = setData(varargin{1}, varargin{2}, varargin{3});
    case 'setvarwidth',
      varargout{1} = setVarWidth(varargin{1}, varargin{2});
    case 'setvarheight',
      varargout{1} = setVarHeight(varargin{1}, varargin{2});
    case 'removerowsorcolumns',
      varargout{1} = removeRowsOrColumns(varargin{:});
    case 'insertrowsorcolumns',
      varargout{1} = insertRowsOrColumns(varargin{:});
    case 'renamefield',
      varargout{1} = renameField(varargin{1}, varargin{2}, varargin{3});
    case 'valueHasAppropriateIndexing',
      varargout{1} = valueHasAppropriateIndexing(varargin{:});
    case 'isPossibleIndexedEntityName',
        varargout{1} = isPossibleIndexedEntityName(varargin{:});
    case 'getBaseVariableName',
        varargout{1} = getBaseVariableName(varargin{1});
    case 'assignmentPassthrough',
        varargout{1} = assignmentPassthrough(varargin{1});
    case 'createSpreadsheetValues',
        varargout{1} = createSpreadsheetValues(varargin{1});
    otherwise
      error('MATLAB:arrayviewfunc:UnknownOption', ...
          ['Unknown command option ' upper(whichcall)]);
  end

%********************************************************************
function result = getData(x, format)
  if (ischar(x))
	% First, make sure that there aren't a newline in the string.
	% If there are, we can't display it properly.
	if ~isempty(findstr(x, char(10))) || ~isempty(findstr(x, char(13)))
	  result = [];
	  return;
	end
    result = sprintf('%s', x);
  elseif iscellstr(x)
	% First, make sure that there are no newlines in the strings.
	% If there are, we can't display them properly.
	for i = 1:length(x)
	  if ~isempty(findstr(x{i}, char(10))) || ~isempty(findstr(x{i}, char(13)))
		result = [];
		return;
	  end
    end
    % have to pad with a space so java tokenizer will function
    % properly when a cell contains an empty string.
    result = sprintf('%s \n', x{:});
  elseif iscell(x)
    result = [];
  else
    oldFormat = get(0, 'format');
    oldSpacing = get(0, 'formatspacing');

    set(0, 'format', format);
    set(0, 'formatspacing', 'compact');

    if length(x) > 1
        result = evalc('disp(x(:))');
    else
        result = evalc('disp(x)');
    end
    

    set(0, 'format', oldFormat);
    set(0, 'formatspacing', oldSpacing);
  end;

%********************************************************************
function newRef = setData(var, coord, expr)
  try
    if ischar(var),
      var = expr;
    elseif iscellstr(var),
      var{coord{:}} = expr;
    else
      var(coord{:}) = eval(expr);
    end;

    newRef = system_dependent(45, var);
  catch
    newRef = lasterr;
  end;

%********************************************************************
function newRef = setVarWidth(var, width)
  try
    sz = size(var);
    oldWidth = sz(2);

    if iscellstr(var),
      repl = {''};
    else
      repl = 0;
    end;

    if width > oldWidth,
      var(:,end+1:width) = repl;
    elseif width < oldWidth,
      var(:,width+1:end) = [];
    end;

	newRef = system_dependent(45, var);
  catch
    newRef = lasterr;
  end;

%********************************************************************
function newRef = setVarHeight(var, height)
  try
    sz = size(var);
    oldHeight = sz(1);

    if iscellstr(var),
      repl = {''};
    else
      repl = 0;
    end;

    if height > oldHeight,
      var(end+1:height,:) = repl;
    elseif height < oldHeight,
      var(height+1:end,:) = [];
    end;

	newRef = system_dependent(45, var);
  catch
    newRef = lasterr;
  end;

%********************************************************************
function out = removeRowsOrColumns(orig, rowindices, colindices, direction)

% Take care of the easy cases first
if isa(orig, 'char')
    % A char array (guaranteed to be 1xN)
    orig = '';
elseif strcmp(rowindices, ':')
    % Entire columns.  Rip them out.
    orig(:, colindices) = [];
elseif strcmp(colindices, ':')
    % Entire rows.  Rip them out.
    orig(rowindices, :) = [];
else
    % User specified only CERTAIN cells.  More complicated.
    % We'll be removing the selected cells, and moving the
    % "neighbors" up or left, depending on the user's choice.
    empty = 0;
    if isa(orig, 'cell')
        empty = {[]};
    end
    [lastRow lastCol] = size(orig);
    numberOfRows = length(rowindices);
    numberOfCols = length(colindices);
    if strcmp(direction, 'up/down')    
        for destRow = rowindices(1):lastRow
            sourceRow = destRow + numberOfRows;
            for colCounter = 1:numberOfCols
                destCol = colindices(colCounter);
                newValue = empty;
                if (sourceRow <= lastRow)
                    newValue = orig(sourceRow, destCol);
                end
                orig(destRow, destCol) = newValue;
            end
        end
    elseif strcmp(direction, 'left/right')
        for destCol = colindices(1):lastCol
            sourceCol = destCol + numberOfCols;
            for rowCounter = 1:numberOfRows
                destRow = rowindices(rowCounter);
                newValue = empty;
                if (sourceCol <= lastCol)
                    newValue = orig(destRow, sourceCol);
                end
                orig(destRow, destCol) = newValue;
            end
        end
    end
end
if numel(orig) == 0 && isnumeric(orig) && sum(size(orig)) > 0
    % Reduces the array to a 0x0 without changing its class.
    orig = repmat(orig, 0, 0);
end
out = orig;

%********************************************************************
function out = insertRowsOrColumns(orig, rowindices, colindices, direction)

empty = 0;
if isa(orig, 'cell')
    empty = {[]};
else if isa(orig, 'struct')
        empty = createEmptyStruct(orig);
    end
end

[height width] = size(orig);

% Take care of the easy cases first
if isa(orig, 'char')
    % A char array (guaranteed to be 1xN)
    orig = '';
elseif strcmp(rowindices, ':')
    % Entire columns.  Shift all higher columns down and fill the selection
    % with 'empty' (whatever's appropriate for the data type).
    if strcmp(colindices, ':')
        colindices = 1:width;
    end
    numToShift = length(colindices);
    for i = (width + numToShift):-1:max([colindices numToShift+1])
        orig(:, i) = orig(:, i-numToShift);
    end
    for i = colindices
        orig(:, i) = empty;
    end
elseif strcmp(colindices, ':')
    % Entire rows.  Shift all higher rows to the left and fill the selection
    % with 'empty' (whatever's appropriate for the data type).
    if strcmp(rowindices, ':')
        rowindices = 1:width;
    end
    numToShift = length(rowindices);
    for i = (height + numToShift):-1:max([rowindices numToShift+1])
        orig(i, :) = orig(i-numToShift, :);
    end
    for i = rowindices
        orig(i, :) = empty;
    end
else
    % User specified only CERTAIN cells.  More complicated.
    % We'll be moving the selected cells and their "neighbors"
    % down or to the right, depending on the user's choice.
    % Fill in the selected cells with 'empty' (whatever's 
    % appropriate for the data type).
    
    % Move things around
    [lastRow lastCol] = size(orig);
    lastRowOfSelection = rowindices(end);
    lastColOfSelection = colindices(end);
    numberOfRows = length(rowindices);
    numberOfCols = length(colindices);
    if strcmp(direction, 'up/down')    
        for sourceRow = lastRow:-1:rowindices(1)
            destRow = sourceRow + numberOfRows;
            for colCounter = 1:numberOfCols
                destCol = colindices(colCounter);
                newValue = empty;
                if (destRow > lastRowOfSelection)
                    newValue = orig(sourceRow, destCol);
                end
                orig(destRow, destCol) = newValue;
            end
        end
    elseif strcmp(direction, 'left/right')
        for sourceCol = lastCol:-1:colindices(1)
            destCol = sourceCol + numberOfCols;
            for rowCounter = 1:numberOfRows
                destRow = rowindices(rowCounter);
                newValue = empty;
                if (destCol > lastColOfSelection)
                    newValue = orig(destRow, sourceCol);
                end
                orig(destRow, destCol) = newValue;
            end
        end
    end
    
    % Zero out the selection...
    orig(rowindices, colindices) = empty;
    
    % "Patch up" cell arrays to preserve the char array nature of empties.
    if isa(orig, 'cell')
        [l, w] = size(orig);
        for i = 1:l
            for j = 1:w
                if isempty(orig{i, j})
                    orig(i, j) = {[]};
                end
            end
        end
    end
end
out = orig;

%********************************************************************
function in = renameField(in, oldFieldName, newFieldName)
if ~strcmp(oldFieldName, newFieldName)
  allNames = fieldnames(in);
  % Is the user renaming one field to be the name of another field?
  % Remember this.
  isOverwriting = ~isempty(find(strcmp(allNames, newFieldName)));
  matchingIndex = find(strcmp(allNames, oldFieldName));
  if ~isempty(matchingIndex)
    allNames{matchingIndex(1)} = newFieldName;
    in.(newFieldName) = in.(oldFieldName);
    in = rmfield(in, oldFieldName);
    if (~isOverwriting)
      % Do not attempt to reorder if we've reduced the number
      % of fields.  Bad things will result.  Let it go.
      in = orderfields(in, allNames);
    end
  end
end

%********************************************************************
function out = createEmptyStruct(in)
fields = fieldnames(in);
args = cell(1, 2*length(fields));
for inc = 1:length(fields)
  args{2*inc-1} = fields{inc};
  args{2*inc} = [];
end
out = struct(args{:});

%********************************************************************
function out = valueHasAppropriateIndexing(name, value)
out = false;
if length(name) < 3
    return;
end
special = getIndicesOfIndexingChars(name);
if length(special) > 0 && special(1) ~= 1
    try
        le = lasterror;
        eval(['local_noop(value' name(special(1):end) ');']);
        out = true;
    catch
        lasterror(le);
    end
end

%********************************************************************
function out = getBaseVariableName(name)
out = '';
if isempty(name)
    return;
end
if isvarname(name)
    out = name;
    return;
end

special = getIndicesOfIndexingChars(name);
if length(special) > 0
    out = name(1:special(1)-1);
end

%********************************************************************
function local_noop(unused)
% Do absolutely nothing.

%********************************************************************
function out = isPossibleIndexedEntityName(in)
out = false;
if length(in) < 3
  return;
end
special = getIndicesOfIndexingChars(in);
if ~isempty(special)
    out = special(1) ~= 1 && special(end) ~= length(in);
end
  
%********************************************************************
function out = getIndicesOfIndexingChars(in)
out = [];
if length(in) < 2
  return;
end
dots = strfind(in, '.');
parens = strfind(in, '(');
curleys = strfind(in, '{');

out = sort([dots parens curleys]);

%********************************************************************
function result = assignmentPassthrough(in)
result = in;

%********************************************************************
function out = createSpreadsheetValues(in)
s = size(in);
out = cell(s);
for i = 1:s(1)
    for j = 1:s(2)
        try
            eval(['out{i, j} = ' in{i, j} ';']);
        catch
            out{i, j} = in{i, j};
        end
    end
end
    
