function polySum = addMinkowskiPolytope(varargin)
% calculate the Minkowski sum of polytopes
%
% Syntax: polySum = addMinkowskiPolytope(poly1, poly2, ..)
%
% The output is returned in the representation of the first input polytope.
%
% Please consider using V-representation only, because Minkowski addition 
%   is only efficiently performed in this representation.
%
% You can specify the zerotol for addMinkowskiVrep by an option/value pair:
%     addMinkowskiPolytope('zerotol', 1e-8, ..).
%   this zerotol is applied for all additions that follow the definition of
%   zerotol. Default: see elkZerotol.
% 
% See also: convertPolytope, obtainPolytope, addMinkowskiVrep

% The elk-library: convex geometry applied to crystallization modeling.
%   Copyright (C) 2012 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/>.

%! ToDo: Zerotol option.

zerotol = elkZerotol;
jumpLoop = 0;
firstPoly = 1;
for iInput = 1:nargin
    
    %% Handle possible options
    if jumpLoop
        jumpLoop = 0;
        continue;
    end
    
    if strcmpi(varargin{iInput}, 'zerotol')
        jumpLoop = 1;
        firstPoly = firstPoly + 2;
        zerotol = varargin{iInput+1};
        continue;
    end
    
    %% Input handling
    infoInput = identifyPolytope(varargin{iInput});
    
    if iInput == firstPoly
        repOut = infoInput.rep;
        switch infoInput.rep
            case 'Vrep'
                vrepSum = varargin{iInput};
            case 'Hrep'
                vrepSum = convertHrepToVrep(varargin{iInput}, zerotol, inf);
        end
        continue
    end
    
    switch infoInput.rep
        case 'Vrep'
            vrepSum = addMinkowskiVrep(vrepSum, varargin{iInput});
        case 'Hrep'
            vrepSum = addMinkowskiVrep(vrepSum, ...
                convertHrepToVrep(varargin{iInput}, zerotol, inf));
    end
end

switch repOut
    case 'Vrep'
        polySum = vrepSum;
    case 'Hrep'
        polySum = convertVrepToHrep(vrepSum, zerotol);
end

end
