# Path: crumbs/utils/optional_modules.py
# NCBIXML = create_fake_class(MSG + BIO)
# 
# Path: crumbs/utils/tags.py
# SUBJECT = 'subject'
# 
# QUERY = 'query'
# 
# ELONGATED = 'elongated'
# 
# Path: crumbs/utils/segments_utils.py
# def merge_overlaping_segments(segments, merge_segments_closer=1):
#     '''Given a list of segments it returns the overlapped segments.
# 
#        segments 1  -------        ----->    -----------
#        segments 2       ------
#        returns     -----------    ------    -----------
#        merge_segments_closer is an integer. Segments closer than the given
#        number of residues will be merged.
#     '''
# 
#     # we collect all start and ends
#     limits = []
#     for segment in segments:
#         start = segment[0]
#         end = segment[1]
#         if start > end:  # a reversed item
#             start, end = end, start
#         limit_1 = (START, start)
#         limit_2 = (END, end)
#         limits.append(limit_1)
#         limits.append(limit_2)
# 
#     # sort by secondary key: start before end
#     limits.sort(key=itemgetter(0))
#     # sort by location (primary key)
#     limits.sort(key=itemgetter(1))
# 
#     # merge the ends and start that differ in only one base
#     filtered_limits = []
#     previous_limit = None
#     for limit in limits:
#         if previous_limit is None:
#             previous_limit = limit
#             continue
#         if (previous_limit[0] == END and limit[0] == START and
#             previous_limit[1] >= limit[1] - merge_segments_closer):
#             # These limits cancelled each other
#             previous_limit = None
#             continue
#         filtered_limits.append(previous_limit)
#         previous_limit = limit
#     else:
#         filtered_limits.append(limit)
#     limits = filtered_limits
# 
#     # now we create the merged hsps
#     starts = 0
#     segments = []
#     for limit in limits:
#         if limit[0] == START:
#             starts += 1
#             if starts == 1:
#                 segment_start = limit[1]
#         elif limit[0] == END:
#             starts -= 1
#             if starts == 0:
#                 segment = (segment_start, limit[1])
#                 segments.append(segment)
#     return segments


import itertools
import copy
import os
from math import log10
from crumbs.utils.optional_modules import NCBIXML
from crumbs.utils.tags import SUBJECT, QUERY, ELONGATED
from crumbs.utils.segments_utils import merge_overlaping_segments
def elongate_match_part_till_global(match_part, query_length, subject_length,
                                    align_completely):
    '''It streches the match_part to convert it in a global alignment.

    We asume that the subject or the query should be completely aligned and we
    strech the match part to do it.
    The elongated match_parts will be marked unless the segment added is
    shorter than the mark_strech_longer integer.

    '''
    assert align_completely in (SUBJECT, QUERY)
    # start and ends
    if match_part['subject_start'] <= match_part['subject_end']:
        subject_start = match_part['subject_start']
        subject_end = match_part['subject_end']
        subject_rev = False
    else:
        subject_start = match_part['subject_end']
        subject_end = match_part['subject_start']
        subject_rev = True
    if match_part['query_start'] <= match_part['query_end']:
        query_start = match_part['query_start']
        query_end = match_part['query_end']
        query_rev = False
    else:
        query_start = match_part['query_end']
        query_end = match_part['query_start']
        query_rev = True

    # how much do we elongate?

# Path: crumbs/utils/optional_modules.py
# NCBIXML = create_fake_class(MSG + BIO)
# 
# Path: crumbs/utils/tags.py
# SUBJECT = 'subject'
# 
# QUERY = 'query'
# 
# ELONGATED = 'elongated'
# 
# Path: crumbs/utils/segments_utils.py
# def merge_overlaping_segments(segments, merge_segments_closer=1):
#     '''Given a list of segments it returns the overlapped segments.
# 
#        segments 1  -------        ----->    -----------
#        segments 2       ------
#        returns     -----------    ------    -----------
#        merge_segments_closer is an integer. Segments closer than the given
#        number of residues will be merged.
#     '''
# 
#     # we collect all start and ends
#     limits = []
#     for segment in segments:
#         start = segment[0]
#         end = segment[1]
#         if start > end:  # a reversed item
#             start, end = end, start
#         limit_1 = (START, start)
#         limit_2 = (END, end)
#         limits.append(limit_1)
#         limits.append(limit_2)
# 
#     # sort by secondary key: start before end
#     limits.sort(key=itemgetter(0))
#     # sort by location (primary key)
#     limits.sort(key=itemgetter(1))
# 
#     # merge the ends and start that differ in only one base
#     filtered_limits = []
#     previous_limit = None
#     for limit in limits:
#         if previous_limit is None:
#             previous_limit = limit
#             continue
#         if (previous_limit[0] == END and limit[0] == START and
#             previous_limit[1] >= limit[1] - merge_segments_closer):
#             # These limits cancelled each other
#             previous_limit = None
#             continue
#         filtered_limits.append(previous_limit)
#         previous_limit = limit
#     else:
#         filtered_limits.append(limit)
#     limits = filtered_limits
# 
#     # now we create the merged hsps
#     starts = 0
#     segments = []
#     for limit in limits:
#         if limit[0] == START:
#             starts += 1
#             if starts == 1:
#                 segment_start = limit[1]
#         elif limit[0] == END:
#             starts -= 1
#             if starts == 0:
#                 segment = (segment_start, limit[1])
#                 segments.append(segment)
#     return segments


# Path: crumbs/seq/alignment_result.py
import itertools
import copy
import os
from math import log10
from crumbs.utils.optional_modules import NCBIXML
from crumbs.utils.tags import SUBJECT, QUERY, ELONGATED
from crumbs.utils.segments_utils import merge_overlaping_segments

def elongate_match_part_till_global(match_part, query_length, subject_length,
                                    align_completely):
    '''It streches the match_part to convert it in a global alignment.

    We asume that the subject or the query should be completely aligned and we
    strech the match part to do it.
    The elongated match_parts will be marked unless the segment added is
    shorter than the mark_strech_longer integer.

    '''
    assert align_completely in (SUBJECT, QUERY)
    # start and ends
    if match_part['subject_start'] <= match_part['subject_end']:
        subject_start = match_part['subject_start']
        subject_end = match_part['subject_end']
        subject_rev = False
    else:
        subject_start = match_part['subject_end']
        subject_end = match_part['subject_start']
        subject_rev = True
    if match_part['query_start'] <= match_part['query_end']:
        query_start = match_part['query_start']
        query_end = match_part['query_end']
        query_rev = False
    else:
        query_start = match_part['query_end']
        query_end = match_part['query_start']
        query_rev = True

    # how much do we elongate?

    if align_completely == SUBJECT: