#
# <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 networkx
import similarity
import metasimilaritymeasure
import structuralsimilaritymeasure
import grafon.constants as constants
import grafon.spreading.pagerankspreading as pagerankspreading

class PageRankBhattacharyyaMeasure(
  structuralsimilaritymeasure.StructuralSimilarityMeasure):
  """!
  Imeplemntation of similarity using  Bhattacharyy similarity measure.  For
  a given  two graphs, the PageRank  algorithm is  run . After that, the values
  of  PageRank ranking  are used as the values into elements of created vecors.
  The nodes from graph are  transforms to a flat vector for each graph. Between
  them is run the Bhattacharyya similarity. 
  """

  def __init__(self, options, str_name = 'PageRankBhattacharyyaMeasure'):
    """!
    Constructor
    @param options: a dictionary containing options for this measure
    @para str_name: default value same as the class name 
                    "PageRankBhattacharyyaMeasure"
    """
    super(PageRankBhattacharyyaMeasure, self).__init__(options, str_name)

  def calculate(self, g1, g2):
    """!
    Implementation of abstract calculate function from interface. Calculates
    the BhattacharyyaMeasure between two created vectors, based on the PageRankg 
    ranking. The given graphs are copied into new bewfore running pagerank 
    because the PageRank function is not defined to run on multigraphs.

    @param g1 first graph
    @type g1: networgx.DiGraph/networkx.MultiDiGraph

    @param g2 second graph
    @type g1: networgx.DiGraph/networkx.MultiDiGraph

    @return Bhattacharyya silimarity of two pagerank vectors
    @rtype: double
    """
    if not g1 or not g2:
      return 0
    # metameasure initialized with BhattacharyyaSimilarity similarity
    # and PageRank spreading method
    meta = metasimilaritymeasure.MetaSimilarityMeasure(
      options=self.options(), 
      sim_funcion=similarity.BhattacharyyaSimilarity(),
      spread_method=pagerankspreading.PageRankSpreading(),
      spread_max_it=constants.PAGE_RANK_MAX_ITER,
      spread_max_depth=1,
      init_values=None,
      str_name=self.__str__())

    return meta.calculate(g1, g2)
