#!/usr/bin/env python

import wx, wx.html
import sys, os
import chkfasta, pro2dpc, svm_classify

SB_INFO = 0
CAT_CODE = ""

aboutText = """<p><b>il10Pred</b> is a standalone software used to predict whether the peptides
 are il10 inducing or not.</p>""" 

class HtmlWindow(wx.html.HtmlWindow):
    def __init__(self, parent, id, size=(600,400)):
        wx.html.HtmlWindow.__init__(self,parent, id, size=size)
        if "gtk2" in wx.PlatformInfo:
            self.SetStandardFonts()

    def OnLinkClicked(self, link):
        wx.LaunchDefaultBrowser(link.GetHref())
        
class AboutBox(wx.Dialog):
    def __init__(self):
        wx.Dialog.__init__(self, None, -1, "About il10Pred Standalone Software",
            style=wx.DEFAULT_DIALOG_STYLE|wx.THICK_FRAME|wx.RESIZE_BORDER|
                wx.TAB_TRAVERSAL)
        hwin = HtmlWindow(self, -1, size=(400,200))
        vers = {}
        vers["python"] = sys.version.split()[0]
        vers["wxpy"] = wx.VERSION_STRING
        hwin.SetPage(aboutText % vers)
        btn = hwin.FindWindowById(wx.ID_OK)
        irep = hwin.GetInternalRepresentation()
        hwin.SetSize((irep.GetWidth()+25, irep.GetHeight()+10))
        self.SetClientSize(hwin.GetSize())
        self.CentreOnParent(wx.BOTH)
        self.SetFocus()

class Frame(wx.Frame):
    def __init__(self, title):
        wx.Frame.__init__(self, None, title=title, pos=(150,150), size=(1000,600), style=wx.CLOSE_BOX)
        self.Bind(wx.EVT_CLOSE, self.OnClose)

        menuBar = wx.MenuBar()
        menu = wx.Menu()
        m_exit = menu.Append(wx.ID_EXIT, "&Exit\tAlt-X", "Close window and exit program.")
        self.Bind(wx.EVT_MENU, self.OnClose, m_exit)
        m_save = menu.Append(wx.ID_SAVE, "&Save\tCtrl-S", "Save the result.")
        self.Bind(wx.EVT_MENU, self.OnFileSave, m_save)
        m_saveas = menu.Append(wx.ID_SAVEAS, "&Save As\tCtrl-Shift-S", "Save the result.")
        self.Bind(wx.EVT_MENU, self.OnFileSaveAs, m_saveas)
        menuBar.Append(menu, "&File")
        menu = wx.Menu()
        m_about = menu.Append(wx.ID_ABOUT, "&About", "Information about il10Pred")
        self.Bind(wx.EVT_MENU, self.OnAbout, m_about)
        menuBar.Append(menu, "&Help")
        self.SetMenuBar(menuBar)
        
        self.statusbar = self.CreateStatusBar()

        panel = wx.Panel(self)

        htmlhead = wx.html.HtmlWindow(panel, id=-1, pos=(1,1), size=(1000,150))
        htmlhead.SetPage("<html><body><img src='imageil10.jpg'/></body></html>")

        box = wx.BoxSizer(wx.VERTICAL)
        m_text = wx.StaticText(panel, -1, "\n\n\n\n\n\n\n\n\n    Browse the input FASTA file")
        m_text.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD))
        m_text.SetSize(m_text.GetBestSize())
        box.Add(m_text, 0, wx.ALL, 10)

        fileCtrl = wx.FilePickerCtrl(panel, pos=(30,180), wildcard="*.fasta;*.fa;*.txt;*.fas")

        choices = ["-0.9", "-0.8", "-0.7", "-0.6", "-0.5", "-0.4", "-0.3", "-0.2", "-0.1", "0", "0.1", "0.2", "0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9"]
        models = ["SVM", "RANDOM FOREST", "IBk"]
        modelspath = {'SVM':'model', 'RANDOM FOREST':'model2', 'IBk':'model3'}

        box = wx.BoxSizer(wx.VERTICAL)
        m_text = wx.StaticText(panel, -1, "\n\n\n\n\n\n\n\n\n\n\n\n\n    Select the Model")
        m_text.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD))
        m_text.SetSize(m_text.GetBestSize())
        m_text.SetSize(m_text.GetBestSize())
        box.Add(m_text, 0, wx.ALL, 10)

        combo = wx.ComboBox(panel, id=-1, value=models[0], pos = (40,260), choices=models, name="Model")
        combo.SetToolTip(wx.ToolTip("Select the model"))

        box = wx.BoxSizer(wx.VERTICAL)
        m_text = wx.StaticText(panel, -1, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n Select the Threshold")
        m_text.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD))
        m_text.SetSize(m_text.GetBestSize())
        m_text.SetSize(m_text.GetBestSize())
        box.Add(m_text, 0, wx.ALL, 10)

        combo1 = wx.ComboBox(panel, id=-1, value=choices[10], pos = (40,340), choices=choices, name="Threshold")
        combo1.SetToolTip(wx.ToolTip("Increasing the threshold will increase the probability of correct prediction"))

        #m_close = wx.Button(panel, wx.ID_CLOSE, "Close")
        #m_close.Bind(wx.EVT_BUTTON, self.OnClose)
        #box.Add(m_close, 0, wx.ALL, 10)

        html1 = wx.html.HtmlWindow(panel, id=-1, pos=(250,160), size=(730,380))
        html1.SetPage("<html><body><p align=center><font size=5><b>Result Window.</b></font></p></body></body>")

		######### CLEAR BUTTON ###############
        clrbutton = wx.Button(panel, id=-1, label='Clear', pos=(10, 400), size=(80, 80))
        clrbutton.Bind(wx.EVT_BUTTON, lambda event, filecontrol=fileCtrl, combo=combo, combo1=combo1, html1=html1: self.clrfunc(event, filecontrol, combo, combo1, html1) )

		########### SUBMIT BUTTON ############
        button=wx.Button(panel,label="Submit",pos=(120,400),size=(80,80))
        button.Bind(wx.EVT_BUTTON, lambda event, filecontrol=fileCtrl, combo=combo, combo1=combo1, modelspath=modelspath, html1=html1: self.runIl10pred(event, filecontrol, combo, combo1, modelspath, html1) )
        

        self.dirName = ""
        self.fileName = ""


        panel.SetSizer(box)
        panel.Layout()

    def clrfunc(self, event, filecontrol, combo, combo1, html1):
        filecontrol.SetPath("")
        #combo.SetLabel("SVM")
        #combo1.SetLabel("0.1")
        combo.SetSelection(0)
        combo1.SetSelection(10)
        html1.SetPage("<html><body><p align=center><font size=5><b>Result Window.</b></font></p></body></body>")

    def OnClose(self, event):
        self.Destroy()
        #dlg = wx.MessageDialog(self, 
        #    "Do you really want to close this application?",
        #    "Confirm Exit", wx.OK|wx.CANCEL|wx.ICON_QUESTION)
        #result = dlg.ShowModal()
        #dlg.Destroy()
        #if result == wx.ID_OK:
        #    self.Destroy()

    def OnFileSave(self, e):
        """ File|Save event - Just Save it if it's got a name. """
        #print CAT_CODE
        if (self.fileName != "") and (self.dirName != ""):
            try:
                with open(os.path.join(self.dirName, self.fileName), 'w') as f:
                    f.write(CAT_CODE)
                return True
            except:
                print >> sys.stderr, "Error in saving file."
                return False
        else:
            ### - If no name yet, then use the OnFileSaveAs to get name/directory
            return self.OnFileSaveAs(e)


    def OnFileSaveAs(self, e):
        """ File|SaveAs event - Prompt for File Name. """
        ret = False
        dlg = wx.FileDialog(self, "Save As", self.dirName, self.fileName,
                           "Text Files (*.txt)|*.txt|All Files|*.*", wx.SAVE)
        if (dlg.ShowModal() == wx.ID_OK):
            self.fileName = dlg.GetFilename()
            self.dirName = dlg.GetDirectory()
            ### - Use the OnFileSave to save the file
            if self.OnFileSave(e):
                self.SetTitle("Save Results of Il10Pred" + " - [" + self.fileName + "]")
                ret = True
        dlg.Destroy()
        return ret


    def OnAbout(self, event):
        dlg = AboutBox()
        dlg.ShowModal()
        dlg.Destroy() 
	
    def runIl10pred(self, event, filecontrol, combo, combo1,modelspath, html1):
        filepath = filecontrol.GetPath()
        model = combo.GetValue()
        modelfilepath = modelspath[model]
        thres = combo1.GetValue()
        if not os.path.exists(modelfilepath):
            #htmlcode = "<html><body><br><p align=center>Result Window.</p><br><p>Error!!! %s model doesn't exists.</p></body></html>" % model
            #html1.SetPage(htmlcode)
            print >> sys.stderr, "Error!!! %s model doesn't exists." % model
        elif filepath == "":
            print >> sys.stderr, "Error!!! No file selected as input. Please select an input file using Browse button"
        elif not chkfasta.checkfasta(filepath):
            print >> sys.stderr, "Error!!! Input file is not in correct fasta format. Make sure the input file is in correct format and use only 20 standard amino acid codes to represent amino acids"
        else:
            #print "model is %s and thres is %s and modelfile path is %s" % (model, thres, modelfilepath)
            #print filepath
            #print "Calculating Dipeptide Composition"
            (inpsvm, seqlist) = pro2dpc.dpcsvm(filepath)
            #print seqlist
            #print "Running il10Pred..."
            scores = svm_classify.runsvmclassify(inpsvm,"model")
            #print scores
            prediction = ["<font color=blue><b>Il10-inducer</b></font>" if x >= float(thres) else "<b>Non-inducer</b>" for x in scores]
            prediction1 = ["Il10-inducer" if x >= float(thres) else "Non-inducer" for x in scores]
            #print prediction
            global CAT_CODE
            CAT_CODE = ""
            catcode = ""
            for x in range(len(prediction)):
                xx = x+1
                #print "%3s%50s%12s" % (xx,seqlist[x],prediction[x])
                #print "{0} {1} {2}".format(xx,seqlist[x],prediction[x])
                #print "{:<5}{:<51}{:<13}\n".format(xx, seqlist[x], prediction[x])
                savecode = "{:<5}{:<51}{:<13}\n".format(xx, seqlist[x], prediction[x])
                savecode1 = "{:<5}{:<51}{:<13}\n".format(xx, seqlist[x], prediction1[x])
                CAT_CODE = CAT_CODE + savecode1
                catcode = catcode + savecode
            htmlcode = "<html><body><br><p align=center><font size=5><b>Result Window.</b></font></p><pre>%s</pre></body></html>" % catcode
            html1.SetPage(htmlcode)


app = wx.App(redirect=True)   # Error messages go to popup window
top = Frame("il10Pred Standalone Software")
top.Show()
app.MainLoop()
