function [THIS,INDEX] = select(THIS,ROWSELECT,COLSELECT)
% select  Select submatrix by referring to row names and column names.
%
% Syntax
% =======
%
%     [X,INDEX] = select(X,ROWSELECT,COLSELECT)
%     [X,INDEX] = select(X,SELECT)
%
% Input arguments
% ================
% 
% * `X` [ namedmat ] - Matrix or array with named rows and columns.
%
% * `ROWSELECT` [ char | cellstr ] - Selection of row names.
%
% * `COLSELECT` [ char | cellstr ] - Selection of column names.
%
% * `SELECT` [ char | cellstr ] - Selection of names that will be applied
% to both rows and columns.
%
% Output arguments
% =================
%
% * `X` [ namedmat ] - Submatrix with named rows and columns.
%
% Description
% ============
%
% Example
% ========

% -IRIS Toolbox.
% -Copyright (c) 2007-2012 Jaromir Benes.

%**************************************************************************

lumped = false;
if ~exist('COLSELECT','var')
    if iscell(ROWSELECT) && length(ROWSELECT) == 2 ...
            && iscell(ROWSELECT{1}) && iscell(ROWSELECT{2})
        COLSELECT = ROWSELECT{2};
        ROWSELECT = ROWSELECT{1};
    else
        COLSELECT = ROWSELECT;
        lumped = true;
    end
end

if ischar(ROWSELECT)
    ROWSELECT = regexp(ROWSELECT,'[\w\{\}\(\)\+\-]+','match');
end

if ischar(COLSELECT)
    COLSELECT = regexp(COLSELECT,'[\w\{\}\(\)\+\-]+','match');
end

%**************************************************************************

removelogfunc = @(x) regexprep(x,'log\((.*?)\)','$1');
rowselect = removelogfunc(ROWSELECT(:).');
colselect = removelogfunc(COLSELECT(:).');
rownames = removelogfunc(THIS.Rownames);
colnames = removelogfunc(THIS.Colnames);

nrowselect = length(rowselect);
ncolselect = length(colselect);

rowindex = nan(1,nrowselect);
colindex = nan(1,ncolselect);

for i = 1 : length(rowselect)
    pos = find(strcmp(rownames,rowselect{i}),1);
    if ~isempty(pos)
        rowindex(i) = pos;
    end
end

for i = 1 : length(colselect)
    pos = find(strcmp(colnames,colselect{i}),1);
    if ~isempty(pos)
        colindex(i) = pos;
    end
end

dochknotfound();

rownames = THIS.rownames;
colnames = THIS.colnames;
THIS = double(THIS);
s = size(THIS);
THIS = THIS(:,:,:);
THIS = THIS(rowindex,colindex,:);
if length(s) > 2
    THIS = reshape(THIS,[nrowselect,ncolselect,s(3:end)]);
end
THIS = namedmat(THIS,rownames(rowindex),colnames(colindex));

INDEX = {rowindex,colindex};

% Nested functions.

%**************************************************************************
    function dochknotfound()
        if lumped
            notfound = isnan(rowindex) | isnan(colindex);
            if any(notfound)
                utils.error('namedmat', ...
                    'This is not a valid row or column name: ''%s''.', ...
                    ROWSELECT{notfound});
            end
        else
            rownotfound = isnan(rowindex);
            if any(rownotfound)
                utils.error('namedmat', ...
                    'This is not a valid row name: ''%s''.', ...
                    ROWSELECT{rownotfound});
            end
            
            colnotfound = isnan(colindex);
            if any(colnotfound)
                utils.error('namedmat', ...
                    'This is not a valid column name: ''%s''.', ...
                    COLSELECT{colnotfound});
            end
        end
    end
% dochknotfound().

end