#!/usr/bin/env python

"""
.. See the NOTICE file distributed with this work for additional information
   regarding copyright ownership.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
"""

import os
import re

class fastqreader:
    """
    Module for reading single end and paired end FASTQ files
    """

    def __init__(self):
        """
        Initialise the module
        """
        self.paired = False

        self.fastq1 = ''
        self.fastq2 = ''

        self.f1_file = None
        self.f2_file = None

        self.f1_eof = False
        self.f2_eof = False

        self.f1_output_file = None
        self.f2_output_file = None

        self.output_tag = ''
        self.output_file_count = 0

    def openFastQ(self, file1, file2=None):
        """
        Create file handles for reading the FastQ files

        Parameters
        ----------
        file1 : str
            Location of the first FASTQ file
        file2 : str
            Location of a paired end FASTQ file.
        """
        self.fastq1 = file1
        self.f1_file = open(self.fastq1, "r")
        self.f1_eof = False

        if file2 is not None:
            self.fastq2 = file2
            self.f2_file = open(self.fastq2, "r")
            self.f2_eof = False
            self.paired = True

    def closeFastQ(self):
        """
        Close file handles for the FastQ files.
        """
        self.f1_file.close()

        if self.paired == True:
            self.f2_file.close()

    def eof(self, side=1):
        """
        Indicate if the end of the file has been reached

        Parameters
        ----------
        side : int
            1 or 2
        """
        if side == 1:
            return self.f1_eof
        elif side == 2:
            return self.f2_eof

        return "ERROR"

    def next(self, side=1):
        """
        Get the next read element for the specific FastQ file pair

        Parameters
        ----------
        side : int
            1 or 2 to get the element from the relevant end (DEFAULT: 1)

        Returns
        -------
        dict
            id : str
                Sequence ID
            seq : str
                Called sequence
            add : str
                Plus sign
            score : str
                Base call score
        """
        read_id = ''
        read_seq = ''
        read_addition = ''
        read_score = ''

        if side == 1:
            read_id = self.f1_file.readline()
            read_seq = self.f1_file.readline()
            read_addition = self.f1_file.readline()
            read_score = self.f1_file.readline()
        elif side == 2:
            read_id = self.f2_file.readline()
            read_seq = self.f2_file.readline()
            read_addition = self.f2_file.readline()
            read_score = self.f2_file.readline()
        else:
            return 'ERROR'

        if read_id == '':
            if side == 1:
                self.f1_eof = True
                return False
            if side == 2:
                self.f2_eof = True
                return False
        return {
            'id': read_id.rstrip(),
            'seq': read_seq.rstrip(),
            'add': read_addition.rstrip(),
            'score': read_score.rstrip()
        }

    def createOutputFiles(self, tag=''):
        """
        Create and open the file handles for the output files

        Parameters
        ----------
        tag : str
            Tag to identify the output files (DEFAULT: '')
        """
        if tag != '' and self.output_tag != tag:
            self.output_tag = tag

        f1 = self.fastq1.split("/")
        new_suffix = "." + str(self.output_tag) + "_" + str(self.output_file_count) + ".fastq"
        f1[-1] = re.sub('.fastq$', new_suffix, f1[-1])
        f1.insert(-1, "tmp")

        if os.path.isdir("/".join(f1[0:-1])) is False:
            os.mkdir("/".join(f1[0:-1]))

        self.f1_output_file = open("/".join(f1), "w")

        if self.paired is True:
            f2 = self.fastq2.split("/")
            new_suffix = "." + str(self.output_tag) + "_" + str(self.output_file_count) + ".fastq"
            f2[-1] = re.sub('.fastq$', new_suffix, f2[-1])
            f2.insert(-1, "tmp")
            self.f2_output_file = open("/".join(f2), "w")

    def writeOutput(self, read, side = 1):
        """
        Writer to print the extracted lines

        Parameters
        ----------
        read : dict
            Read is the dictionary object returned from self.next()
        side : int
            The side that the read has coe from (DEFAULT: 1)

        Returns
        -------
        bool
            False if a value other than 1 or 2 is entered for the side.
        """
        line = read["id"] + "\n" + read["seq"] + "\n" + read["add"] + "\n" + read["score"] + "\n"
        if side == 1:
            self.f1_output_file.write(line)
        elif side == 2:
            self.f2_output_file.write(line)
        else:
            return False
        return True

    def closeOutputFiles(self):
        """
        Close the output file handles
        """
        self.f1_output_file.close()

        if self.paired is True:
            self.f2_output_file.close()

    def incrementOutputFiles(self):
        """
        Increment the counter and create new files for splitting the original
        FastQ paired end files.
        """
        self.closeOutputFiles()

        self.output_file_count += 1

        self.createOutputFiles(self.output_tag)

@@ -726,16 +726,24 @@
 tqreader
+(object)
 :%0A    %22%22
@@ -4112,16 +4112,17 @@
        f
+q
 1 = self
@@ -4244,16 +4244,17 @@
        f
+q
 1%5B-1%5D = 
@@ -4284,16 +4284,17 @@
 uffix, f
+q
 1%5B-1%5D)%0A 
@@ -4301,16 +4301,17 @@
        f
+q
 1.insert
@@ -4350,32 +4350,33 @@
 isdir(%22/%22.join(f
+q
 1%5B0:-1%5D)) is Fal
@@ -4410,16 +4410,17 @@
 %22.join(f
+q
 1%5B0:-1%5D)
@@ -4467,16 +4467,17 @@
 %22.join(f
+q
 1), %22w%22)
@@ -4523,16 +4523,17 @@
        f
+q
 2 = self
@@ -4663,16 +4663,17 @@
        f
+q
 2%5B-1%5D = 
@@ -4703,16 +4703,17 @@
 uffix, f
+q
 2%5B-1%5D)%0A 
@@ -4724,16 +4724,17 @@
        f
+q
 2.insert
@@ -4794,16 +4794,17 @@
 %22.join(f
+q
 2), %22w%22)
@@ -4841,19 +4841,17 @@
 ad, side
- = 
+=
 1):%0A    

Fix for formatting