#! /usr/bin/env python
"""
This program takes one DNA sequence as an argument, prints the reverse-complement.
Weronika Patena, nov2008
"""

import complement

### The actual reverse-complement function:
def reverse_complement(input_sequence,input_type=''):
    # use the complement function from the complement module
    complement_seq = complement.complement(input_sequence,input_type)
    # easy reverse method: full list slice with a step of -1
    reverse_complement_seq = complement_seq[::-1]
    return reverse_complement_seq

### If called directly:
# try reading the argument; if none given, read from stdin (which is what makes it work with pipes (echo ctcgag | script.py) and when called on a selection in vi and such). 
if __name__ == '__main__':
    import read_input,transform_sequence_input,parse_fasta
    # check if input is a list of files (i.e. if first arg is a valid filename - good enough)
    input = read_input.read_input()
    # transform_sequence_input takes an input AND the function to apply to it - in this case rev-compl
    for line in transform_sequence_input.transform_sequence_input(input,reverse_complement):
        parse_fasta.print_seq(line)
    for seq_type in DNA, RNA:
        complement_table[seq_type] = string.maketrans(
            original_bases[seq_type], complement_bases[seq_type])
    return complement_table


# When called/imported, always set up the complement table
complement_table = complement_table_setup()


### The actual complement function
def complement(input_sequence, input=''):
    # if input type isn't given, detect RNA/DNA sequence type (default to DNA)
    if input == 'DNA': input_type = DNA
    elif input == 'RNA': input_type = RNA
    else:
        if input_sequence.count('U') > 0: input_type = RNA
        elif input_sequence.count('u') > 0: input_type = RNA
        else: input_type = DNA
    complement_seq = input_sequence.translate(complement_table[input_type])
    return complement_seq


### If called directly, read, parse and complement the input.
if __name__ == '__main__':
    import read_input, transform_sequence_input, parse_fasta
    input = read_input.read_input()
    for line in transform_sequence_input.transform_sequence_input(
            input, complement):
        parse_fasta.print_seq(line)
# as an argument), process them, and keep the remaining content.
# Otherwise just transform each line.
def transform_sequence_input(full_input, transform_function):
    output = []
    # check whether the input is fasta-formatted or just sequence
    # full_input is a list of lines, so convert it to string or this won't work
    if str(full_input).count('>')>0:    fasta = True
    else:                               fasta = False
    if debug: print '\n\t### INPUT:\n%s\t### END_INPUT\n'%full_input
    if fasta:
        for (header,seq) in parse_fasta.parse_fasta(full_input):
            output.append((header,transform_function(seq)))
    else:
        for line in full_input:
            output.append(transform_function(line))
    if debug:   print '\n\t######### FINAL OUTPUT: #########'%output
    return output

### Just a basic swapcase function to test the transform_sequence_input function
def swap_case(line):
    return line.swapcase()

### If called directly, test everything
if __name__ == '__main__':
    input = read_input()
    # use nice printing for fasta (header,seq) tuples, or normal for text lines
    try:                
        for (header,seq) in transform_sequence_input(input,swap_case):  parse_fasta.print_seq(header,seq)
    except ValueError:   
        for line in transform_sequence_input(input,swap_case):          print line