#
# <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 grafon.constants as constants
from grafon.utils import plwnproc
from grafon.utils import sumoproc

class BaseGraph:
  """!
  This class is wrapper for dictionary of networkx.MultiDiGraph(s). 
  In self.graph_dict are stored graphs built for each sentences.
  
  In the self.node_converter is stored the convertwr the node to its key
  representation. All possible converters are into grafon.nodes package.
  
  Method skip_token should be call always before adding node to the graph!
  """

  def __init__(self, node_converter, filters):
      """!
      Constructor initializes the parameters to default values and sets 
      node converter and filters to given into arguments.

      @param node_converter: node converter. Possible converters are into
                              grafon.node package
      @param filters: list of filter which can be used when new node is added 
                       to grah. One filter returns true/false value for node.
      """

      #! Dictionary of graphs built from the analyzed text.
      #! As a key is the sentence ID and as value is MultiDiGraph
      self.graph_dict = {}
      #! Pointer to read document. It also contains relations from this file.
      self.document = None
      #! Tagset used while document reading
      self.tagset = None
      #! node converter
      self.node_converter = node_converter
      #! list of filters
      self.filters = filters
      #! Additional resources into base graph
      self.resources = {}

  def update_resources(self, cfg):
    """
    This method updates dictionary of available resources.
      * adds to dictionary MSRHandle if path is set in config
      * adds plwngraph if plwn merger is set into cfg
      * adds sumograph if sumo merger is set into cfg
    """
    self.resources[constants.RESOURCES_MSR_HNDL] = cfg.msr_handle()
    # Read plwngraph if is necessary
    if cfg.plwn_merger(self) or \
      'PlwnSpikeGraphBuilder' in [str(r) for r in cfg.rebuilders()]:
      self.resources[constants.RESOURCES_PLWN_HNDL] = \
        plwnproc.read_plwn_graph(cfg)
    else:
      self.resources[constants.RESOURCES_PLWN_HNDL] = None
    # Same for SUMO
    if cfg.sumo_merger(self) or \
      'SumoSpikeGraphBuilder' in [str(r) for r in cfg.rebuilders()]:
      self.resources[constants.RESOURCES_SUMO_HNDL] = \
        sumoproc.read_sumo_graph(cfg)
    else:
      self.resources[constants.RESOURCES_SUMO_HNDL] = None

  def skip_token(self, token):
    """!
    This method runs all filters which are stored into self.filters. If one 
    of the filters returns true value, what means that the tokent shuld be skip,
    the result returned by skip_token is True - the given token should be skip.
    Also if token is None then should be skip.

    @param token: tokent to check the skipping
    @returns true/false depends on the results from filters
    """
    if not token:
      return True
    for filter in self.filters:
      if not filter.accept_token_as_node(token):
        return True
    return False