## Copyright (C) 2024 David Legland
## All rights reserved.
## 
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions are met:
## 
##     1 Redistributions of source code must retain the above copyright notice,
##       this list of conditions and the following disclaimer.
##     2 Redistributions in binary form must reproduce the above copyright
##       notice, this list of conditions and the following disclaimer in the
##       documentation and/or other materials provided with the distribution.
## 
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS''
## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
## 
## The views and conclusions contained in the software and documentation are
## those of the authors and should not be interpreted as representing official
## policies, either expressed or implied, of the copyright holders.

function varargout = mergeGraphs(varargin)
%MERGEGRAPHS Merge two graphs, by adding nodes, edges and faces lists.
%
%   
%

% ------
% Author: David Legland 
% E-mail: david.legland@inrae.fr
% Created: 2004-08-09
% Copyright 2004-2023 INRA - TPV URPOI - BIA IMASTE

simplify = false;

edges = {}; edges2 = {};
faces = {}; faces2 = {}; 

%% process input arguments

% extract simplify tag
var = varargin{nargin};
if ischar(var)
	if strcmp(var, 'simplify')
        simplify = true;
        varargin = varargin(1:length(varargin)-1);
	end
end


%% extract data of first graph

var = varargin{1};
if iscell(var)
    % graph is stored as a cell array : first cell is nodes, second one is
    % edges, and third is faces
    nodes = var{1};
    if length(var)>1
        edges = var{2};
    end
    if length(var)>2
        faces = var{3};
    end
    varargin = varargin(2:length(varargin));
    
elseif isstruct(var)
    % graph is stored as a structure, with fields 'nodes', 'edges', and
    % eventually 'faces'.
    nodes = var.nodes;
    edges = var.edges;
    if isfield(var, 'faces')
        faces = var.faces;
    end
    varargin = varargin(2:length(varargin));
    
elseif length(varargin)>2
    % graph is stored as set of variables : nodes, edges, and eventually
    % faces
    nodes = varargin{1};
    edges = varargin{2};
    
    if length(varargin)==3
        % last argument describe graph 2
        varargin = varargin(3);
    else
        if length(varargin)~=4 || ~isnumeric(varargin{4})
            % third argument is faces of graph 1
            faces = varargin{3};
            varargin = varargin(4:length(varargin));
        else
            varargin = varargin(3:length(varargin));
        end
    end
    
else
    error('Error in passing arguments in mergeGraphs');
end


%% extract data of second graph

var = varargin{1};
if iscell(var)
    % graph is stored as a cell array : first cell is nodes, second one is
    % edges, and third is faces
    nodes2 = var{1};
    if length(var)>1
        edges2 = var{2};
    end
    if length(var)>2
        faces2 = var{3};
    end
    
elseif isstruct(var)
    % graph is stored as a structure, with fields 'nodes', 'edges', and
    % eventually 'faces'.
    nodes2 = var.nodes;
    edges2 = var.edges;
    if isfield(var, 'faces')
        faces2 = var.faces;
    end
    
elseif length(varargin)>1
    % graph is stored as set of variables : nodes, edges, and eventually
    % faces
    nodes2 = varargin{1};
    edges2 = varargin{2};
    
    if length(varargin)>2
        % last argument describe graph 2
        faces2 = varargin{3};
    end
    
else
    error('Error in passing arguments in mergeGraphs');
end


%% Main algorithm

% eventually convert faces
if ~iscell(faces)
    f = cell(size(faces, 1), 1);
    for i = 1:size(faces, 1)
        f{i} = faces(i,:);
    end
    faces = f;
end

edges = [edges ; edges2 + size(nodes, 1)];
if iscell(faces2)
	for i = 1:length(faces2)
        faces{length(faces)+1} = faces2{i} + size(nodes, 1); %#ok<AGROW>
	end
else
    % TODO
end
nodes = [nodes; nodes2];

if simplify
    if ~isempty(faces)
        [nodes, edges, faces] = grSimplifyBranches(nodes, edges, faces);
    else
        [nodes, edges] = grSimplifyBranches(nodes, edges);
    end
end


%% process output depending on how many arguments are needed

if nargout == 1
    graph.nodes = nodes;
    graph.edges = edges;
    if ~isempty(faces)
        graph.faces = faces;
    end
    varargout{1} = graph;
end

if nargout == 2
    varargout{1} = nodes;
    varargout{2} = edges;
end

if nargout == 3
    varargout{1} = nodes;
    varargout{2} = edges;
    varargout{3} = faces;
end


