#
# <one line to give the library's name and an idea of what it does.>
# Copyright (C) 2014  <copyright holder> <email>
# 
# 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/>.
# 
#
import logging
import networkx
import mergerinterface
import grafon.constants as constants

class BaseGraphMerger(mergerinterface.MergerInterface):
  """!
  Merger for any graphs. 
  
  Mergs the graphs based on the same node into both. Uses the compose mrthod
  from networkx to do it.
  """
  
  def __init__(self, bg):
    super(BaseGraphMerger, self).__init__('BaseGraphMerger', bg)
    """!
    Store the base graph only as a member
    @param bg: base graph
    """
    self.bg = bg

  def merge(self, g1, g2):
    """!
    Merge two graphs into one. Uses compose method to merge both into one.
    
    @param g1: newtowrkx graph f.e. networkx.DiGraph()
    @param g2: newtowrkx graph f.e. networkx.DiGraph()
    @return new merged graph, also with networx type
    """
    logging.info('~\t merger {}'.format(str(self)))

    ng = networkx.MultiDiGraph()
    # merge nodes
    ng.add_nodes_from(g1.nodes(data=True))
    for node, node_attr in g2.nodes(data=True):
      if ng.has_node(node):
        # copy tokens
        #ng.node[node][constants.NODE_TOKENS].extend(
        #  node_attr[constants.NODE_TOKENS])
        # increase node count
        ng.node[node][constants.NODE_COUNT] += \
          node_attr[constants.NODE_COUNT]
      else:
        ng.add_node(node, attr_dict=node_attr)

    # copy edges from first graph
    # ng.add_edges_from(g1.edges(data=True))
    for (fn, tn, edge_attr) in g1.edges(data=True):
      ng.add_edge(fn, tn, key=edge_attr['label'], attr_dict=edge_attr)

    # copy edges from second graph
    for (fn, tn, edge_attr) in g2.edges(data=True):
      if ng.has_edge(fn, tn, key=edge_attr[constants.EDGE_LABEL]):
        ng[fn][tn][edge_attr[constants.EDGE_LABEL]][constants.EDGE_COUNT] += \
          edge_attr[constants.EDGE_COUNT]
      else:
        ng.add_edge(fn, tn, 
                    key=edge_attr[constants.EDGE_LABEL],
                    attr_dict=edge_attr)
    return ng
