function result = obtainProjectionDataForVector(dec, hE, zerotol)
% extract projection matrices and validity regions
%
% THIS IS NO USER FUNCTION

% 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/>.

%% catch problems
if ~dec.isProper
    error('elk:decomposition:numericalError', ['Developer uses wrong ' ...
        'function. This should not happen.']);
end

%% identify valid/invalid facet groups
% violated constraints
violatedIndexVector = find((dec.confinementMappingData.A * hE) > zerotol)';
% violated facet groups
invalidFacetGroupVector = dec.confinementMappingData.responsibleVector(...
    violatedIndexVector);

%% initialize output
result.constraintMatrix = zeros(0, length(hE));
result.projectionMatrix = eye(length(hE));
result.constraintList = cell([1, length(violatedIndexVector)]);
result.projectionList = cell([1, length(violatedIndexVector)]);
result.violatedConstraintIndexVector = violatedIndexVector;
result.invalidFacetGroupVector = invalidFacetGroupVector;
result.projectionIndexVector = 0*invalidFacetGroupVector;

%% trivial case
% everything is valid, no corrective projection would be found in the 
%   following
if isempty(invalidFacetGroupVector)
    result.constraintMatrix = dec.confinementMappingData.A;
    %! DEV: This should not apply:
%     result.constraintList{1} = dec.confinementMappingData.A;
%     result.projectionList{1} = eye(length(hE));      
    %/
    
    % immideate return, there is no projection that could be found.
    return
end

%% identify projections
% Note that we might identify the same projection multiple times if more
%   than one boundary of a group validity cone is violated. But this does
%   not matter for the result and timing is not crucial.
for iConstraint = 1:length(invalidFacetGroupVector)
    projectionData = dec.confinementMappingData.projectionData(...
        invalidFacetGroupVector(iConstraint));
    
    [dump thisProjectionIndex thisConstraintMatrixList] = ...
        projectFromData(hE, projectionData, zerotol, 1);
    thisProjectionMatrix = projectionData.projectionList{thisProjectionIndex};
    
    % evaluate / concatenate
    result.constraintMatrix = [result.constraintMatrix; ...
                               thisConstraintMatrixList{1}];
    result.projectionMatrix = result.projectionMatrix * ...
                              thisProjectionMatrix;
    result.constraintList{iConstraint} = thisConstraintMatrixList{1};
    result.projectionList{iConstraint} = thisProjectionMatrix;
    result.projectionIndexVector(iConstraint) = thisProjectionIndex;
end