#
#
#

"""Parse the FD type file"""
__author__ = "Magdalena A. Jonikas"
__version__ = "1.0"
__date__ = "Date"

import sys

class Tertiary:
    def __init__(self, line, pieces):
        cols = line.split()
        self.name = cols[0]
        pair = cols[1].split(',')
        self.res1 = int(pair[0])
        self.res2 = int(pair[1])
        self.res1name = pieces.res2name[self.res1]
        self.res2name = pieces.res2name[self.res2]
        if self.res1name==self.res2name:
            self.resList = []
            self.res1list = []
            self.res2list = []
            self.longResList = []
            return
        self.resList = []
        self.res1list = self.getResList(self.res1name, pieces)
        self.res2list = self.getResList(self.res2name, pieces)
        self.longResList = []
        self.longResList.extend(self.res1list)
        self.longResList.extend(self.res2list)

    def getResList(self, name, pieces):
        if name[0]=='H':
            list = pieces.helices[name].resList
            self.resList.extend(list)
            return list
        elif name[0]=='L':
            list = pieces.loops[name].shortResList
            self.resList.extend(list)
            return list
        elif name[0]=='J':
            list = pieces.junctions[name].shortResList
            self.resList.extend(list)
            return list
        elif name[0]=='E':
            list = pieces.ends[name].resList
            self.resList.extend(list)
            return list

    def printTertInfo(self):
        print "residues", self.res1, self.res2
        print "fragment 1", self.res1list
        print "fragment 2", self.res2list

        

class Helix:
    def __init__(self, line, pieces):
        if line[0]!='H':
            print "Error, this is not a helix"
            print line
            sys.exit(1)
        cols0 = line.split()
        self.name = cols0[0]
        cols1 = cols0[1].split(',')
        H1 = cols1[0].split(':')
        H2 = cols1[1].split(':')
        self.H1start = int(H1[0])
        self.H1end = int(H1[1])
        self.H2start = int(H2[0])
        self.H2end = int(H2[1])
        self.H1resList = range(self.H1start, self.H1end+1)
        self.H2resList = range(self.H2start, self.H2end+1)
        self.resList = self.H1resList+self.H2resList
        for res in self.resList:
            pieces.res2name[res]=self.name
        self.longResList = self.resList

    def printHelixInfo(self):
        print "5' end ", self.H1resList
        self.H2resList.reverse()
        print "3' end ", self.H2resList
        self.H2resList.reverse()

    def printLongResList(self):
        print self.name, self.resList

class Loop:
    def __init__(self, line, pieces):
        if line[0]!='L':
            print "Error, this is not a loop"
            print line
            sys.exit(1)
        cols = line.split()
        self.name = cols[0]
        self.helixName = cols[1]
        self.helix = pieces.helices[self.helixName]
        self.shortStart = self.helix.H1end+1
        self.shortEnd = self.helix.H2start-1
        self.shortResList = range(self.shortStart, self.shortEnd+1)
        self.o1ResList = range(self.shortStart-1, self.shortEnd+2)
        self.resList = self.shortResList
        self.longStart = self.helix.H1start
        self.longEnd = self.helix.H2end
        self.longResList = range(self.longStart, self.longEnd+1)
        for res in self.shortResList:
            pieces.res2name[res]=self.name

    def printLoopInfo(self):
        print "5' end ", self.helix.H1resList
        print "loop          ", self.shortResList
        self.helix.H2resList.reverse()
        print "3' end ", self.helix.H2resList
        self.helix.H2resList.reverse()

    def printLongResList(self):
        print self.name, self.longResList

class End:
    def __init__(self, line, pieces):
        cols = line.split()
        self.name = cols[0]
        cols = cols[1].split(':')
        helix = cols[0]
        self.end = cols[1][0]
        length = int(cols[1][1:])
        h = pieces.helices[helix]
        if self.end=='5': 
            if length>0: 
                self.resList = range(h.H1end+1, h.H1end+length+1)
                self.o1ResList = range(h.H1end, h.H1end+length+1)
            else: 
                self.resList = range(h.H1start+length, h.H1start)
                self.o1ResList = range(h.H1start+length, h.H1start+1)
            self.overlap = h.H1resList
            self.longResList = h.H1resList+self.resList
            self.longResList.sort()
        else:
            if length>0: 
                self.resList = range(h.H2end+1, h.H2end+length+1)
                self.o1ResList = range(h.H2end, h.H2end+length+1)
            else: 
                self.resList = range(h.H2start+length, h.H2start)
                self.o1ResList = range(h.H2start+length, h.H2start+1)
            self.overlap = h.H2resList
            self.longResList = h.H2resList+self.resList
            self.longResList.sort()
        for res in self.resList:
            pieces.res2name[res]=self.name
        self.shortResList = self.resList

    def printEndInfo(self):
        print "end", self.resList
        print "overlapping helix    ", self.overlap

    def printLongResList(self):
        print self.name, self.longResList

        
class Junction:
    def __init__(self, line, pieces):
        cols = line.split()
        self.name = cols[0]
        helixNames = cols[1].split(',')
        helix1 = helixNames[0].split(':')
        self.H1name = helix1[0]
        self.H1side = helix1[1]
        helix2 = helixNames[1].split(':')
        self.H2name = helix2[0]
        self.H2side = helix2[1]
        self.Hlist = [(self.H1name, self.H2name), (self.H2name, self.H1name)]

        if self.H1side=='5': self.end5resList = pieces.helices[self.H1name].H1resList
        else: self.end5resList = pieces.helices[self.H1name].H2resList
        if self.H2side=='5': self.end3resList = pieces.helices[self.H2name].H1resList
        else: self.end3resList = pieces.helices[self.H2name].H2resList

        self.shortResList = range(self.end5resList[-1]+1, self.end3resList[0])
        if self.shortResList == []: 
            self.shortResList = [self.end5resList[-1]+1, self.end3resList[0]]
        if len(self.shortResList)==1:
            self.o1ResList = range(self.end5resList[-1]-1, self.end3resList[0]+2)
        elif len(self.shortResList)==2:
            self.o1ResList = range(self.end5resList[-1]-2, self.end3resList[0]+3)
        else: 
            self.o1ResList = range(self.end5resList[-1], self.end3resList[0]+1)
        self.resList = self.shortResList
        self.longResList = self.end5resList+self.shortResList+self.end3resList
        self.overlapList = []
        for i in range(len(self.longResList)):
            res = self.longResList[i]
            if res not in self.resList:
                self.overlapList.append(i)

        for res in self.shortResList:
            pieces.res2name[res]=self.name

    def printJunctionInfo(self):
        print "5' end ", self.end5resList
        print "junction        ", self.shortResList
        print "3' end ", self.end3resList

    def printLongResList(self):
        print self.name, self.longResList


class Pieces:
    def __init__(self, dataIn):
        self.helices = {}
        self.junctions = {}
        self.nonredj = []
        self.loops = {}
        self.ends = {}
        self.tertiary = {}
        self.res2name = {}
        for line in dataIn:
            if line[0]=='H': 
                thisHelix = Helix(line, self)
                self.helices[thisHelix.name] = thisHelix
            if line[0]=='L':
                thisLoop = Loop(line, self)
                self.loops[thisLoop.name] = thisLoop
            if line[0]=='J':
                thisJunction = Junction(line, self)
                if len(self.nonredj)==0: self.nonredj.append(thisJunction.name)
                else: 
                    hlist = thisJunction.Hlist
                    good = 1
                    for jname in self.nonredj:
                        if self.junctions[jname].Hlist[0] in hlist: good = 0
                    if good: self.nonredj.append(thisJunction.name)
                self.junctions[thisJunction.name] = thisJunction
            if line[0]=='E':
                thisEnd = End(line, self)
                self.ends[thisEnd.name]=thisEnd
            if line[0]=='T':
                thisTert = Tertiary(line, self)
                self.tertiary[thisTert.name]=thisTert

            
            

def parseFD(dataIn):
    pieces = {}

    return pieces

if __name__=='__main__':
    dataIn = open(sys.argv[1]).readlines()

    pieces = Pieces(dataIn)
    resList = []


    for helix in pieces.helices.keys():
        thisHelix = pieces.helices[helix]
        print "Helix", thisHelix.name
        thisHelix.printHelixInfo()
        resList.extend(thisHelix.resList)
        print  


    for loop in pieces.loops.keys():
        thisLoop = pieces.loops[loop]
        print "Loop", thisLoop.name
        thisLoop.printLoopInfo()
        resList.extend(thisLoop.shortResList)
        print   


    for junction in pieces.junctions.keys():
        thisJunction = pieces.junctions[junction]
        print "Junction", thisJunction.name
        thisJunction.printJunctionInfo()
        resList.extend(thisJunction.shortResList)
        print    


    for end in pieces.ends.keys():
        thisEnd = pieces.ends[end]
        print "End", thisEnd.name
        thisEnd.printEndInfo()
        resList.extend(thisEnd.shortResList)
        print   

    for tert in pieces.tertiary.keys():
        thisTert = pieces.tertiary[tert]
        print "added tert", thisTert.name
        thisTert.printTertInfo()
        print


    resList.sort()
    lastRes = 0
    for i in range(len(resList)):
        thisRes = resList[i]
        if thisRes!=(lastRes+1):
            print lastRes, thisRes, "The following are missing", range(lastRes+1,thisRes)
        lastRes = thisRes
