# Path: seal/lib/mr/hit_processor_chain_link.py
# class HitProcessorChainLink(object):
#     def __init__(self, next_link = None):
#         self.next_link = next_link
# 
#     def set_next(self, link):
#         self.next_link = link
#         return link
# 
#     def process(self, original, aligned_pair):
#         """
#         Identity action.  Passes to the next link, if any.
#         """
#         if self.next_link:
#             self.next_link.process(original, aligned_pair)


from seal.lib.mr.hit_processor_chain_link import HitProcessorChainLink
class FilterLink(HitProcessorChainLink):
    def __init__(self, monitor, next_link = None):
        super(FilterLink, self).__init__(next_link)
        self.min_hit_quality = 0
        self.remove_unmapped = False # if true, all unmapped are removed regardless of hit quality
        self.event_monitor = monitor

    @staticmethod
    def _remove_i(pair, i):
        pair[i] = None
        other_hit = pair[i^1]
        if other_hit:
            other_hit.remove_mate()
        return pair

    def process(self, original, aligned_pair):
        if len(aligned_pair) != 2:
            raise ValueError("pair length != 2 (it's %d)" % len(aligned_pair))
        pair = list(aligned_pair) # tuples can't be modified
        for i in 0, 1:
            if self.remove_unmapped and pair[i].is_unmapped():
                pair = self._remove_i(pair, i)
                self.event_monitor.count("reads filtered: unmapped")
            elif pair[i].qual < self.min_hit_quality:
                pair = self._remove_i(pair, i)
                self.event_monitor.count("reads filtered: low quality")

        if self.next_link and any(pair):
            self.next_link.process(original, tuple(pair)) # forward pair to next element in chain


# Path: seal/lib/mr/hit_processor_chain_link.py
# class HitProcessorChainLink(object):
#     def __init__(self, next_link = None):
#         self.next_link = next_link
# 
#     def set_next(self, link):
#         self.next_link = link
#         return link
# 
#     def process(self, original, aligned_pair):
#         """
#         Identity action.  Passes to the next link, if any.
#         """
#         if self.next_link:
#             self.next_link.process(original, aligned_pair)


# Path: seal/lib/mr/filter_link.py
from seal.lib.mr.hit_processor_chain_link import HitProcessorChainLink

class FilterLink(HitProcessorChainLink):
    def __init__(self, monitor, next_link = None):
        super(FilterLink, self).__init__(next_link)
        self.min_hit_quality = 0
        self.remove_unmapped = False # if true, all unmapped are removed regardless of hit quality
        self.event_monitor = monitor

    @staticmethod
    def _remove_i(pair, i):
        pair[i] = None
        other_hit = pair[i^1]
        if other_hit:
            other_hit.remove_mate()
        return pair

    def process(self, original, aligned_pair):
        if len(aligned_pair) != 2:
            raise ValueError("pair length != 2 (it's %d)" % len(aligned_pair))
        pair = list(aligned_pair) # tuples can't be modified
        for i in 0, 1:
            if self.remove_unmapped and pair[i].is_unmapped():
                pair = self._remove_i(pair, i)
                self.event_monitor.count("reads filtered: unmapped")
            elif pair[i].qual < self.min_hit_quality:
                pair = self._remove_i(pair, i)
                self.event_monitor.count("reads filtered: low quality")

        if self.next_link and any(pair):
            self.next_link.process(original, tuple(pair)) # forward pair to next element in chain


class RapiFilterLink(HitProcessorChainLink):