from wxPython.wx import *
import os, sys, threading
from xrflib import getKey
from prefs import *

# Find the installation dir of snarfzilla
if sys.path[0] == "":
    snarfdir = "."
else:
    snarfdir = sys.path[0]

''' Recent CHANGES

Change color to wxBLUE after opening file
Strip \n\n for Windoze in wxListCtl
'''

class paneldownload(wxPanel):
    """
    This class starts a getKey thread to download a key.
    This has replaced using wxProcess, pipes, and download.py

    """

    def __init__(self, parent, sb):
        wxPanel.__init__(self, parent, -1)
        self.parent=parent
        self.sb = sb # Statusbar
        self.que = {} # Dictionary to hold row information with keys, status, filesize etc.

        # Make the controls

        #----------------------------------------------------------------------------------
        # Options at top (Box 1)
        #----------------------------------------------------------------------------------
        smartnid = wxNewId()
        htlid = wxNewId()
        spinId = wxNewId()
        self.smartnames = wxCheckBox(self, smartnid, "Filenames from Keys", style=wxNO_BORDER)
        box1 = wxBoxSizer(wxHORIZONTAL)
        box1.Add(self.smartnames, 1, wxEXPAND|wxALL, 0)
        self.smartnames.SetValue(true)
        EVT_CHECKBOX(self, smartnid, self.OnSmartNames)

        #----------------------------------------------------------------------------------
        # "list" wxListCtrl log window (Box 2)
        #----------------------------------------------------------------------------------
        listID = wxNewId()
        self.list= wxListCtrl(self, listID, size=wxDefaultSize,style=wxLC_REPORT|wxSUNKEN_BORDER)
        self.list.InsertColumn(0,"Key")
        self.list.InsertColumn(1,"Status")
        self.list.InsertColumn(2,"Size")
        self.list.SetColumnWidth(0, 540)
        self.list.SetColumnWidth(1, 70)
        self.list.SetColumnWidth(2, 110)

        box2 = wxBoxSizer(wxHORIZONTAL)
        box2.Add(self.list, 1, wxEXPAND|wxALL,0)
        #Events:

        # for wxMSW
        EVT_COMMAND_RIGHT_CLICK(self.list, listID, self.OnRightClick)

        # for wxGTK
        EVT_RIGHT_UP(self.list, self.OnRightClick)
        EVT_RIGHT_DOWN(self.list, self.OnRightDown)

        self.lblRequesting = wxStaticText(self, -1, 'Saving as: ') # Placeholder for "Saving as: "
        self.inpRequesting = wxStaticText(self, -1, '')
        box3top = wxBoxSizer(wxHORIZONTAL)
        box3top.Add(self.lblRequesting, 0, wxLEFT)
        box3top.Add(self.inpRequesting, 1, wxEXPAND|wxALL)
        self.lblRequesting.SetLabel('')

        #----------------------------------------------------------------------------------
        # Filename input  box  wxListCtrl (Box 3)
        #----------------------------------------------------------------------------------
        self.lblFilename = wxStaticText(self, -1, 'Filename   ')
        self.inpFilename = wxTextCtrl(self, -1, "")

        self.lblhtl= wxStaticText(self, -1, " Hops to Live: ")
        self.htl = wxTextCtrl(self, htlid, '50', wxDLG_PNT(self, 10, 10), wxDLG_SZE(self, 15, 12)) #, wxSize(30, 20)
        self.htl.Enable(true)
        self.spin = wxSpinButton(self, spinId, wxPoint(20,20), wxSize(20,20), wxSP_VERTICAL)
        self.spin.SetRange(1, 200)
        self.spin.SetValue(50)
        EVT_SPIN(self, spinId, self.OnSpin)


        box3 = wxBoxSizer(wxHORIZONTAL)
        box3.Add(self.lblFilename, 0, wxLEFT)
        box3.Add(self.inpFilename, 1, wxEXPAND|wxALL)
        box3.Add(self.lblhtl, 0, wxRIGHT)
        box3.Add(self.htl, 0, wxRIGHT)
        box3.Add(self.spin, 0, wxRIGHT)

        #--------------------------------------------------------------------------------
        #Bottom input boxes, buttons (Box4)
        #---------------------------------------------------------------------------------
        self.inp = wxTextCtrl(self, -1, '', style=wxTE_PROCESS_ENTER)
        self.txt = wxStaticText(self, -1, 'Key Name ')
        self.sndBtn = wxButton(self, -1, 'Request')

        #--------------------------------------------------------------------
        # Leaving off the Cancel button until we're sure it works
        #--------------------------------------------------------------------

        # self.termBtn = wxButton(self, -1, 'Cancel')
        self.inpFilename.Enable(false) # smartnames checked by default, don't let them enter filename on startup
        self.lblFilename.Enable(false)
        self.inp.Enable(true)
        self.sndBtn.Enable(true)
        #self.termBtn.Enable(false)
        # Hook up the events
        EVT_BUTTON(self, self.sndBtn.GetId(), self.OnSendText)
        EVT_TEXT_ENTER(self, self.inp.GetId(), self.OnSendText)
        EVT_LIST_ITEM_SELECTED(self, listID, self.OnItemSelected)
        box4 = wxBoxSizer(wxHORIZONTAL)
        box4.Add(self.txt, 0, wxALIGN_CENTER)
        box4.Add(self.inp, 1, wxALIGN_CENTER)
        box4.Add(self.sndBtn, 0, wxLEFT, 5)
        #box4.Add(self.termBtn, 0, wxLEFT, 5)
        sizer = wxBoxSizer(wxVERTICAL)
        sizer.Add(box1, 0, wxEXPAND|wxALL, 0) #wxEXPAND|wxALL
        #sizer.Add(self.out, 1, wxEXPAND|wxALL, 0)
        sizer.Add(box2, 1, wxEXPAND|wxALL, 0)
        sizer.Add(box3top, 0, wxEXPAND|wxALL, 5)
        sizer.Add(box3, 0, wxEXPAND|wxALL, 5)
        sizer.Add(box4, 0, wxEXPAND|wxALL, 5)
        self.SetSizer(sizer)
        self.SetAutoLayout(true)
        self.inp.SetFocus()

    def OnSpin(self, event):
        self.htl.SetValue(str(event.GetPosition()))

    def OnSmartNames(self, event):
        # Smart Names Checkbox check or uncheck
        n = self.smartnames.GetValue()
        if n == 1:
            self.inpFilename.Enable(false)
            self.lblFilename.Enable(false)
        else:
            self.inpFilename.Enable(true)
            self.lblFilename.Enable(true)

    def OnItemSelected(self, event):
        self.currentItem = event.m_itemIndex

    def OnRightDown(self, event):
        self.x = event.GetX()
        self.y = event.GetY()
        #self.log.add("RightDown x, y = %s\n" % str((self.x, self.y)))
        event.Skip()

    def OnRightClick(self, event):
        # if Debug:
        #print self.list.GetItemText(self.currentItem)
        #print "Length:"
        #print len(self.list.GetItemText(self.currentItem))
        #self.log.add("OnRightClick %s\n" % self.list.GetItemText(self.currentItem))
        menu = wxMenu()
        forceId = wxNewId()
        openId = wxNewId()
        clearId = wxNewId()
        clearAllId = wxNewId()
        menu.Append(forceId, "Download")
        menu.Append(openId, 'Open')
        menu.Append(clearId, 'Remove Key from Queue')
        menu.Append(clearAllId, 'Remove All Keys from Queue')
        EVT_MENU(self, forceId, self.OnForceDownload)
        EVT_MENU(self, openId, self.OnLaunch)
        EVT_MENU(self, clearId, self.OnClear)
        EVT_MENU(self, clearAllId, self.OnClearAll)
        self.PopupMenu(menu, wxPoint(self.x, self.y))
        menu.Destroy()
        event.Skip()

    def OnClearAll(self, event):
        self.list.DeleteAllItems()

    def OnForceDownload(self, event):
        nbr = self.list.GetItemCount() - 1
        busy = 0
        while nbr > -1:
            item = self.list.GetItem(nbr, 1)
            col1 = item.GetText()
            nbr = nbr -1
        n = self.list.GetItemText(self.currentItem)
        self.inp.SetValue(n)
        i = self.currentItem
        self.list.DeleteItem(i) #Delete the item we're on because it gets added again in OnSendText
        self.OnSendText(self) # Send to download tab, start downloading or be queued

    def OnLaunch(self, event):
        keyname = self.list.GetItemText(self.currentItem)
        keyname = (r'%s' % keyname)
        f = string.replace(keyname, '\\', '/', 20)
        f = string.replace(f, '@', '/', 20)
        if string.find(f, '/') != -1:
            dirname, filename = os.path.split(f)
        else:
            filename = keyname # plain kay like 'test'
        try:
            #win32
            cmd = ('"%s" file://C:/snarfzilla/download/%s' % (helper, filename))
            print cmd
            os.system(cmd)
            #os.system("%s %s%sdownload%s%s &" % (helper, snarfdir, os.sep, os.sep, filename))
            item = self.list.GetItem(self.currentItem)
            item.SetTextColour(wxBLUE)
            self.list.SetItem(item)

        except:
            if debug == '1':
                print sys.exc_type, sys.exc_value
            msg = ("Can't open file %s\n Check your 'Helper App' setting in 'Snarfzilla Preferences'" % filename)
            dlg = wxMessageDialog(self, msg, 'Error opening file',
            wxOK | wxICON_INFORMATION)
            dlg.ShowModal()
            dlg.Destroy()

    def OnClear(self, event):
        try:
            self.list.DeleteItem(self.currentItem)
        except:
            pass # No items to delete

    #def __del__(self):
    #    print '__del__ called!'
    #    sys.exit(0)

    def OnSendText(self, evt):
        keyname = self.inp.GetValue()
        keyname = string.strip(keyname)
        nbr = self.list.GetItemCount() - 1
        self.AddKeyToRow(keyname, 'Queued')

    def AddKeyToRow(self, keyname, status ):
        keyname = string.strip(keyname)
        status = string.strip(status)
        filename = self.inpFilename.GetValue()
        s = self.smartnames.GetValue()
        # If smartnames checked, make filename from key like KSK@mp3/britney/iloverob.mp3 to iloverob.mp3
        if s == 1:
            keyname = (r'%s' % keyname)
            f = string.replace(keyname, '\\', '/')
            f = string.replace(f, '@', '/')
            if string.find(f, '/') != -1:
                dirname, filename = os.path.split(f)
            else:
                filename = keyname # plain kay like 'test'
        hops = self.htl.GetValue()
        #self.inpRequesting.SetLabel("%s/download/%s" % (snarfdir, filename))
        server = '127.0.0.1'
        port = 6690
        self.inp.SetValue('')
        dir = 'download'
        xrf = getKey(self, server, port, keyname, filename, hops, dir)
        try:
            xrf.start()
        except:
            print 'Error with XML-RPC transfer!\n'
        if debug == '1':
            threadlist = threading.enumerate()
        row = 0
        self.list.InsertStringItem(row, keyname)
        self.list.SetStringItem(row, 1, status)
        self.inp.SetValue('')
        self.inpFilename.SetValue('')
        nbrRows = len(self.que)

    def UpdateRow(self, keyname, status, filesize, ttlFileSize):
        if ttlFileSize == -1: #Fail
            size = ''
            status = 'Failed'
        else:
            size = ('%s/%s' % (filesize, ttlFileSize))
        row = 0
        while 1:
            if self.list.GetItemText(row) == keyname:
                self.que[keyname] = [status, filesize]
                self.list.SetStringItem(row, 1, status)
                self.list.SetStringItem(row, 2, size)
                self.list.Refresh()
                break
            row = row + 1
            nbrRows = self.list.GetItemCount()
            if row > nbrRows:
                break