#
# <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 corpus2
import edgebuiderinterface

class ChunkRelEdgeBuilder(edgebuiderinterface.EdgeBuiderInterface):
  """
  Builds the edgees based on the chunk relations.
  It uses the output from chunkrel as the relations.
  """
  
  def __init__(self, str_name = 'iob', chan_name = 'chunk_vp'):
    """Only calls parent's constructor"""
    super(ChunkRelEdgeBuilder, self).__init__(str_name,chan_name)

  def add_edges(self, base_graph):
    """
    Based on the chunkrel relation adds edges between two nodes representing
    tokens from text. The nodes are connected with tokens from text between
    which occurs chunkrel relation. New edge is labbeled in accordance with 
    chunkrel relation name.
    
    @param base_graph: Object of grafon.graphs.BaseGraph
    """
    # dictionary of sentence id to relations in given channel
    drels = dict()
    for r in base_graph.document.relations():
      pfrom = r.rel_from()
      if not pfrom.channel_name() == self._chan_name:
        continue
      if not drels.has_key(pfrom.sentence_id()):
        drels[pfrom.sentence_id()] = []
      drels[pfrom.sentence_id()].append(r)

    for paragraph in base_graph.document.paragraphs():
      for sentence in paragraph.sentences():
        rels = drels.get(sentence.id(), None)
        if not drels:
          continue
        g = base_graph.graph_dict[sentence.id()]
        asent = corpus2.AnnotatedSentence.wrap_sentence(sentence)
        for r in rels:
          chan_from = asent.get_channel(r.rel_from().channel_name())
          for i, seg in enumerate([s for s in chan_from.segments()]):
            if chan_from.is_head_at(i) and seg == \
              r.rel_from().annotation_number():
              token_from = asent.tokens()[i]

          chan_to = asent.get_channel(r.rel_to().channel_name())
          for i, seg in enumerate([s for s in chan_to.segments()]):
            if chan_to.is_head_at(i) and seg == r.rel_to().annotation_number():
              token_to = asent.tokens()[i]

          if base_graph.skip_token(token_from) or \
            base_graph.skip_token(token_to):
            continue

          from_nodes = base_graph.node_converter.key(token_from)
          to_nodes = base_graph.node_converter.key(token_to)
          for fn in from_nodes:
            if not g.has_node(fn):
                continue
            for tn in to_nodes:
              if not g.has_node(tn):
                continue
              if fn and tn:
                if self.exists_edge(g, fn, tn, self._str_name):
                    g[fn][tn][self._str_name][constants.EDGE_COUNT] += 1
                else:
                  g.add_edge(
                    fn, tn, key=self._str_name, attr_dict = {
                      constants.EDGE_LABEL: self._str_name, 
                      constants.EDGE_RELNAME: r.rel_name,
                      constants.EDGE_COUNT: 1})

