function [hcMatrix filterToZero] = mapToConfinementCone(hcMatrix, dec, ...
    zerotol)
% map a hC vector to the cone of confined hC-vectors
%
% Syntax: hcMapped = mapToConfinementCone(hcMatrix, dec)
%
% Map all input hC-vectors in hcMatrix (each column a hC-vector) to 
%   confined hC-vectors while preserving their shape. For improper
%   representations, this mapping is performed via the embedding proper
%   representation. For proper representation, this operation is equivalent
%   to mapToValidityCone.
%
% With mapToConfinementCone(hcMatrix, dec, zerotol) you can also set the
%   applied tolerance for determining whether hC-vectors are confined or
%   not.
%
% [hcMatrix, filterToZero] = mapToValidCone(..) returns a logical row 
%   vector filterToZero that contains true for empty polytopes. Note that
%   empty polytopes (empty sets of points {}) cannot be represented by a 
%   valid vector so that they must be represented by the origin, the set 
%   {0}.
%
% See also: obtainDec, validateDec, mapToValidityCone

% The elk-library: convex geometry applied to crystallization modeling.
%   Copyright (C) 2013 Alexander Reinhold
%
% This program is free software: you can redistribute it and/or modify it 
%   under the terms of the GNU General Public License as published by the 
%   Free Software Foundation, either version 3 of the License, or (at your 
%   option) any later version.
%
% This program is distributed in the hope that it will be useful, but 
%   WITHOUT ANY WARRANTY; without even the implied warranty of 
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
%   General Public License for more details.
%
% You should have received a copy of the GNU General Public License along 
%   with this program.  If not, see <http://www.gnu.org/licenses/>.

%% Input handling
% define zerotol, if not provided
if ~exist('zerotol', 'var') || isempty(zerotol)
    zerotol = elkZerotol;
end

%% fallback: validity mapping
% immediate jump to validity mapping
if dec.isProper
    if nargout >= 2
        [hcMatrix filterToZero] = mapToValidityCone(hcMatrix, dec, ...
            zerotol);
    else
        hcMatrix = mapToValidityCone(hcMatrix, dec, zerotol);
    end
    % and thats it, already
    return
end

%% general input handling
% try to correct size of input
if size(hcMatrix, 1) ~= dec.nC
    hcMatrix = hcMatrix';
end
% define zerotol, if not provided
if ~exist('zerotol', 'var') || isempty(zerotol)
    zerotol = elkZerotol;
end
% throw error for incomplete representations
if isfield(dec, 'isComplete') && ~dec.isComplete
    error('elk:decomposition:inputError', ['Confinement mapping for ' ...
        'incomplete decompositions is not possible']);
end

%% determine required processing
% filter which vectors must be processed
if dec.isOrdinary
    filterProcessThem = max(dec.confinementCone.A * hcMatrix, [], 1) > zerotol;
else
    filterProcessThem = max(dec.confinementConeHull.A * hcMatrix, [], 1) > zerotol;
end
% return if there is nothing to do
if isempty(hcMatrix) || ~any(filterProcessThem)
    if nargout >= 2,filterToZero = [];end
    return
end

%% Mapping via proper representation
filterToZero = zeros(1, size(hcMatrix, 2));
[heMatrix filterToZero(filterProcessThem)] = ...
    mapToValidityCone(dec.properData.mappingNewToProper * ...
      hcMatrix(:, filterProcessThem), dec.properData, 0);
% map back to hC-representation - we don't provide partition data so it is
%   computed by mapFromProperEmbedding
hcMatrix(:, filterProcessThem) = mapFromProperEmbedding(heMatrix, dec, ...
    zerotol + 10*eps);

%% handle output
if nargout < 2
    clear filterToZero
end