# Path: unicycler/misc.py
# def get_nice_header(header):
#     """
#     For a header with a SPAdes/Velvet format, this function returns a simplified string that is
#     just NODE_XX where XX is the contig number.
#     For any other format, this function trims off everything following the first whitespace.
#     """
#     if is_header_spades_format(header):
#         return 'NODE_' + header.split('_')[1]
#     else:
#         return header.split()[0]
# 
# def dim(text):
#     return DIM + text + END_FORMATTING
# 
# def line_iterator(string_with_line_breaks):
#     """Iterates over a string containing line breaks, one line at a time."""
#     prev_newline = -1
#     while True:
#         next_newline = string_with_line_breaks.find('\n', prev_newline + 1)
#         if next_newline < 0:
#             break
#         yield string_with_line_breaks[prev_newline + 1:next_newline]
#         prev_newline = next_newline
# 
# def range_overlap(x1, x2, y1, y2):
#     """
#     Returns true if the range (x1, x2) overlaps with the range (y1, y2).
#     """
#     return x1 < y2 and y1 < x2
# 
# def range_is_contained(test_range, other_ranges):
#     """
#     Returns True if test_range is entirely contained within any range in other_ranges.
#     """
#     start, end = test_range
#     for other_range in other_ranges:
#         if other_range[0] <= start and other_range[1] >= end:
#             return True
#     return False
# 
# def range_overlap_size(test_range, other_ranges):
#     start, end = test_range
#     max_overlap = 0
#     for other_range in other_ranges:
#         max_overlap = max(max_overlap, min(end, other_range[1]) - max(start, other_range[0]))
#     return max_overlap
# 
# def simplify_ranges(ranges):
#     """
#     Collapses overlapping ranges together. Input ranges are tuples of (start, end) in the normal
#     Python manner where the end isn't included.
#     """
#     fixed_ranges = []
#     for int_range in ranges:
#         if int_range[0] > int_range[1]:
#             fixed_ranges.append((int_range[1], int_range[0]))
#         elif int_range[0] < int_range[1]:
#             fixed_ranges.append(int_range)
#     starts_ends = [(x[0], 1) for x in fixed_ranges]
#     starts_ends += [(x[1], -1) for x in fixed_ranges]
#     starts_ends.sort(key=lambda x: x[0])
#     current_sum = 0
#     cumulative_sum = []
#     for start_end in starts_ends:
#         current_sum += start_end[1]
#         cumulative_sum.append((start_end[0], current_sum))
#     prev_depth = 0
#     start = 0
#     combined = []
#     for pos, depth in cumulative_sum:
#         if prev_depth == 0:
#             start = pos
#         elif depth == 0:
#             combined.append((start, pos))
#         prev_depth = depth
#     return combined


import os
import sys
from collections import defaultdict
from .misc import get_nice_header, dim, line_iterator, range_overlap, range_is_contained, \
    range_overlap_size, simplify_ranges
from . import log
from . import settings
    from .cpp_wrappers import minimap_align_reads

class MinimapAlignment(object):

    def __init__(self, paf_line=None):
        if paf_line is None:
            self.paf_line = ''
            self.read_name = ''
            self.read_length = 0
            self.read_start = 0
            self.read_end = 0
            self.read_strand = '+'
            self.ref_name = ''
            self.ref_length = 0
            self.ref_start = 0
            self.ref_end = 0
            self.matching_bases = 0
            self.num_bases = 0
            self.minimiser_count = 0
            self.read_end_gap = 0

        else:
            self.paf_line = paf_line.strip()
            line_parts = self.paf_line.split('\t')

            self.read_name = line_parts[0]
            self.read_length = int(line_parts[1])
            self.read_start = int(line_parts[2])
            self.read_end = int(line_parts[3])
            self.read_strand = line_parts[4]


# Path: unicycler/misc.py
# def get_nice_header(header):
#     """
#     For a header with a SPAdes/Velvet format, this function returns a simplified string that is
#     just NODE_XX where XX is the contig number.
#     For any other format, this function trims off everything following the first whitespace.
#     """
#     if is_header_spades_format(header):
#         return 'NODE_' + header.split('_')[1]
#     else:
#         return header.split()[0]
# 
# def dim(text):
#     return DIM + text + END_FORMATTING
# 
# def line_iterator(string_with_line_breaks):
#     """Iterates over a string containing line breaks, one line at a time."""
#     prev_newline = -1
#     while True:
#         next_newline = string_with_line_breaks.find('\n', prev_newline + 1)
#         if next_newline < 0:
#             break
#         yield string_with_line_breaks[prev_newline + 1:next_newline]
#         prev_newline = next_newline
# 
# def range_overlap(x1, x2, y1, y2):
#     """
#     Returns true if the range (x1, x2) overlaps with the range (y1, y2).
#     """
#     return x1 < y2 and y1 < x2
# 
# def range_is_contained(test_range, other_ranges):
#     """
#     Returns True if test_range is entirely contained within any range in other_ranges.
#     """
#     start, end = test_range
#     for other_range in other_ranges:
#         if other_range[0] <= start and other_range[1] >= end:
#             return True
#     return False
# 
# def range_overlap_size(test_range, other_ranges):
#     start, end = test_range
#     max_overlap = 0
#     for other_range in other_ranges:
#         max_overlap = max(max_overlap, min(end, other_range[1]) - max(start, other_range[0]))
#     return max_overlap
# 
# def simplify_ranges(ranges):
#     """
#     Collapses overlapping ranges together. Input ranges are tuples of (start, end) in the normal
#     Python manner where the end isn't included.
#     """
#     fixed_ranges = []
#     for int_range in ranges:
#         if int_range[0] > int_range[1]:
#             fixed_ranges.append((int_range[1], int_range[0]))
#         elif int_range[0] < int_range[1]:
#             fixed_ranges.append(int_range)
#     starts_ends = [(x[0], 1) for x in fixed_ranges]
#     starts_ends += [(x[1], -1) for x in fixed_ranges]
#     starts_ends.sort(key=lambda x: x[0])
#     current_sum = 0
#     cumulative_sum = []
#     for start_end in starts_ends:
#         current_sum += start_end[1]
#         cumulative_sum.append((start_end[0], current_sum))
#     prev_depth = 0
#     start = 0
#     combined = []
#     for pos, depth in cumulative_sum:
#         if prev_depth == 0:
#             start = pos
#         elif depth == 0:
#             combined.append((start, pos))
#         prev_depth = depth
#     return combined


# Path: unicycler/minimap_alignment.py
import os
import sys
from collections import defaultdict
from .misc import get_nice_header, dim, line_iterator, range_overlap, range_is_contained, \
    range_overlap_size, simplify_ranges
from . import log
from . import settings
    from .cpp_wrappers import minimap_align_reads


class MinimapAlignment(object):

    def __init__(self, paf_line=None):
        if paf_line is None:
            self.paf_line = ''
            self.read_name = ''
            self.read_length = 0
            self.read_start = 0
            self.read_end = 0
            self.read_strand = '+'
            self.ref_name = ''
            self.ref_length = 0
            self.ref_start = 0
            self.ref_end = 0
            self.matching_bases = 0
            self.num_bases = 0
            self.minimiser_count = 0
            self.read_end_gap = 0

        else:
            self.paf_line = paf_line.strip()
            line_parts = self.paf_line.split('\t')

            self.read_name = line_parts[0]
            self.read_length = int(line_parts[1])
            self.read_start = int(line_parts[2])
            self.read_end = int(line_parts[3])
            self.read_strand = line_parts[4]


            self.ref_name = get_nice_header(line_parts[5])