#!/usr/bin/python

#######################################################################
#                                                                     #
# Author:      Elena Kochetkova                                       #
# Supervisor:  Alexander Kozik                                        #
# Date:        December 15, 2003                                      #
# Description: This program extracts specified substrings             #
#                                                                     #
####################################################################### 

###################################################
import os
import sys
import string
import re
import copy
from string import *
##################################################

class _cls:
    def __init__(self):
        if sys.platform in ('linux-i386', 'linux2'):
            self._command = 'clear'
        elif sys.platform in ('win32', 'dos') or \
             sys.platform.startswith('ms-dos'):
            self._command = 'cls'
        else:
            self._command = None

    def __call__(self):
        """Clears the screen."""
        if self._command:
            os.system(self._command)

clear_screen = _cls()

global input_filename, output_filename

def ask_filename(prompt):
   global input_filename
   
   input = strip(raw_input(prompt))
   return input
 
def file_open_err(file_name):
   print "Error opening file ","\"",file_name,"\""

def would_you_like_prompt(prompt_line): 
   ans =""
   ans = lstrip(raw_input(prompt_line))
   while ans == "":
       print "\nEnter y or n."             
       ans = lstrip(raw_input(prompt_line))
   return ans

def fileExists(f):
   try:
      file = open (f)
   except IOError:
      exists = 0
   else:
      exists = 1
   return exists
 
def open_inputfile(prompt):
   global input_filename
   proper_name = 1   
   while proper_name != 0: 
     try:        
        # ask for input file name
        input_filename = ask_filename(prompt)
        # open the input file
        fp_in = open(input_filename, "rb")
        proper_name = 0
     except:
        file_open_err(input_filename) 
        prompt_line = "\nWould you like to continue (y/n)? "   
        ans = would_you_like_prompt(prompt_line)
        if ans[0] == "n" or ans[0] == "N":
           sys.exit(0)
   return fp_in  
 
def open_outputfile():
   global input_filename, output_filename, output_dir  
   output_filename = "overlapping_seqs.txt"
   output_dir = "overlapping_seqs.dir"
   print "Your default destination file is: ", output_filename 
   # open the output file
   if fileExists(output_filename) == 1:
      print  "\nFile",output_filename,"already exists.\n"
      prompt_line = "\nWould you like to overwrite it (y/n)? "
      ans = would_you_like_prompt(prompt_line)
      print "\n\n"
      if ans[0] == "n" or ans[0] == "N":  
          output_filename = lstrip(raw_input("\n\nEnter the DESTINATION file name: "))
          fp_out = open(output_filename, "wb")
      else:
          fp_out = open(output_filename, "wb") 
   else:
      try: 
         fp_out = open(output_filename, "wb")
      except:
         file_open_err(output_filename)
         print "\nTry again later...\n\n"
         sys.exit (1)
   os.mkdir(output_dir)  
   return fp_out


def get_data(fp_in, flag1, flag2): 

   global dupl_array1
   global dupl_array2
   global dupl_array3
   global dupl_array4

   dupl_array = []
   bad_array  = []
   dupl_count = 0

   data_sub_arr = []
   data_array = []
   count = 0
   while 1:
      data  = strip(fp_in.readline())      
      if not data:   # end of file   
         break
      if flag1 == 0:
         if data[0] == ">":
            data_info = data.split(" ")
	    query_id = data_info[0][1:]
	    # print query_id
            name = data_info[7][1:]
            # CHECK FOR DUPLICATES
            if name in dupl_array:
               print dupl_count
               # print name
               # print "DUPLICATION"
               bad_array.append(name)
               dupl_count = dupl_count + 1
            dupl_array.append(name)
            ############################
            idx = data_info[8].find('-')
            begin = data_info[8][:idx]
            end = data_info[8][idx+1:-1]
            data_sub_arr.append(name)
            data_sub_arr.append(begin)
            data_sub_arr.append(end)
	    data_sub_arr.append(query_id)
	    # print data_sub_arr
         else:
            data_sub_arr.append(data)
            data_array.insert(count, data_sub_arr)
            data_sub_arr = []
      if flag1 == 1:
         if data[0] == ">":
            data_info = data.split(" ")
            name = data_info[0][1:]
            # CHECK FOR DUPLICATES
            if name in dupl_array:
               print dupl_count
               # print name
               # print "DUPLICATION"
               bad_array.append(name)
               dupl_count = dupl_count + 1
            dupl_array.append(name)
            ############################
	    subject_id = name
            idx = data_info[6].find('-')
            begin = data_info[6][:idx]
            end = data_info[6][idx+1:]
            data_sub_arr.append(name)
            data_sub_arr.append(begin)
            data_sub_arr.append(end)
	    data_sub_arr.append(subject_id)
	    # print data_sub_arr
         else:
            data_sub_arr.append(data)
            data_array.insert(count, data_sub_arr)
            data_sub_arr = []
      count += 1 
   if flag2 == 1:
        dupl_array1 = bad_array
        print dupl_array1
   if flag2 == 2:
        dupl_array2 = bad_array
        print dupl_array2
   if flag2 == 3:
        dupl_array3 = bad_array
        print dupl_array3
   if flag2 == 4:
        dupl_array4 = bad_array
        print dupl_array4
   return data_array

def find_overlap(query, arr, subj_arr1, subj_arr2, fn1, fn2, fn3, fn4, fp_out):

    global dupl_array1
    global dupl_array2
    global dupl_array3
    global dupl_array4

    global output_dir

    for i in range(len(arr)):
        # if At... names are the same
        if query[0]== arr[i][0] and query[0] not in dupl_array1 and query[0] not in dupl_array2 and query[0] not in dupl_array3 and query[0] not in dupl_array4:
            if (int(query[1]) >= int(arr[i][1]) and int(query[1]) <= int(arr[i][2])) or \
               (int(query[1]) < int(arr[i][1]) and int(query[2]) >= int(arr[i][1])):
                
                if int(query[1]) > int(arr[i][1]):
                    delta_begin_query = 0
                    delta_begin_arr = int(query[1]) - int(arr[i][1])
                elif int(query[1]) < int(arr[i][1]):
                    delta_begin_query = int(arr[i][1]) - int(query[1])
                    delta_begin_arr = 0
                elif int(query[1]) == int(arr[i][1]):
                    delta_begin_query = 0
                    delta_begin_arr = 0
            
                if int(query[2]) > int(arr[i][2]):
                    delta_end_query = -(int(query[2]) - int(arr[i][2]))
                    delta_end_arr = int(len(arr[i][4]))
                elif int(query[2]) < int(arr[i][2]):
                    delta_end_query = int(len(query[4]))
                    delta_end_arr = -(int(arr[i][2]) - int(query[2]))
                elif int(query[2]) == int(arr[i][2]):
                    delta_end_query = int(len(query[4]))
                    delta_end_arr = int(len(arr[i][4]))

                if len(arr[i][4][delta_begin_arr:delta_end_arr])>=60 and \
			len(arr[i][4][delta_begin_arr:delta_end_arr]) == len(query[4][delta_begin_query:delta_end_query]):
 
                    aln_out = open(output_dir + "/" + arr[i][0] + "__" + arr[i][3] + "__" + query[3] + "__.alignment", "wb")
           
                    fp_out.write(">"+arr[i][3]+" "+fn1+" ["+arr[i][1]+"-"+arr[i][2]+"]\n")
                    fp_out.write(arr[i][4][delta_begin_arr:delta_end_arr]+"\n")
                    fp_out.write(">"+query[3]+" "+fn2+" ["+query[1]+"-"+query[2]+"]\n")
                    fp_out.write(query[4][delta_begin_query:delta_end_query]+"\n")

                    aln_out.write(">" + arr[i][3] + "\n")
                    aln_out.write(arr[i][4][delta_begin_arr:delta_end_arr]+"\n")
                    aln_out.write(">" + query[3] + "\n")
                    aln_out.write(query[4][delta_begin_query:delta_end_query]+"\n")

#                   new_seq = arr[i][4][delta_begin:delta_end]
                    for j in range(len(subj_arr1)):
                        if query[0] == subj_arr1[j][0] and \
				len(arr[i][4][delta_begin_arr:delta_end_arr]) == len(subj_arr1[j][4][delta_begin_arr:delta_end_arr]):
                           fp_out.write(">"+subj_arr1[j][0]+" "+fn3+" ["+subj_arr1[j][1]+"-"+subj_arr1[j][2]+"]\n")
                           fp_out.write(subj_arr1[j][4][delta_begin_arr:delta_end_arr]+"\n")
			   fp_out.write("------------------------------------------------------------\n")

                           aln_out.write(">" + subj_arr1[j][0] + "\n")
                           aln_out.write(subj_arr1[j][4][delta_begin_arr:delta_end_arr]+"\n")

                           print `i`
                           break
                    for k in range(len(subj_arr2)):
                        if query[0] == subj_arr2[k][0] and \
				len(arr[i][4][delta_begin_arr:delta_end_arr]) == len(subj_arr2[k][4][delta_begin_query:delta_end_query]):
                            subseq2 = subj_arr2[k][4][delta_begin_query:delta_end_query]
                            if (subj_arr1[j][4][delta_begin_arr:delta_end_arr]!= subseq2):
                                print query[0] + "\n"
                                print " ... TOO BAD ... "
                                break                       
#                           fp_out.write(">"+subj_arr2[k][0]+" "+fn4+" ["+subj_arr2[k][1]+"-"+subj_arr2[k][2]+"]\n")
#                           fp_out.write(subj_arr2[k][4][delta_begin_query:delta_end_query]+"\n")
			    fp_out.write("-=xxx=------------------------------------------------=xxx=-\n")
                            break
                    aln_out.close()
                    break
                
        

###################################################
#                    main                         #
###################################################

clear_screen ()
fp_in1 = open_inputfile("Please enter the name of the query file A: ")
file_name1 = input_filename
fp_in2 = open_inputfile("Please enter the name of the query file B: ")
file_name2 = input_filename
fp_in3 = open_inputfile("Please enter the name of the subject file A: ")
file_name3 = input_filename
fp_in4 = open_inputfile("Please enter the name of the subject file B: ")
file_name4 = input_filename

fp_out = open_outputfile()

global dupl_array1
global dupl_array2
global dupl_array3
global dupl_array4

dupl_array1 = []
dupl_array2 = []
dupl_array3 = []
dupl_array4 = []

arr = []
arr = get_data(fp_in1, 0, 1)
print "  == STEP 1 ==  "
#print arr
fp_in1.close()

query_arr = []
query_arr = get_data(fp_in2, 0, 2)
print "  == STEP 2 ==  "
fp_in2.close()

subj_arr1 = []
subj_arr1 = get_data(fp_in3, 1, 3)
print "  == STEP 3 ==  "
fp_in3.close()


subj_arr2 = []
subj_arr2 = get_data(fp_in4, 1, 4)
print "  == STEP 4 ==  "
fp_in4.close()
#print subj_arr

for i in range(len(query_arr)):
    find_overlap(query_arr[i], arr, subj_arr1, subj_arr2, file_name1, file_name2, file_name3, file_name4, fp_out)

fp_out.close()   # close the output2 file  

# THE END #
