from qt import *
from qttable import *
from releaseStatusWizardBA import ReleaseStatusWizardBA
from constants import *
import logging
import os
from ReleaseDataVO import ReleaseDataVO
from messageQueue import progressMessageQueue
from workerThread import WorkerThread
from help import Help
import time
from utf8 import from_utf8, to_utf8

try:
    # python2.4
    set = set
except:
    # python2.3 compatibility
    from sets import Set
    set = Set

debug = logging.getLogger("releaseWizard").debug
error = logging.getLogger("releaseWizard").error


### edit release listview constants

COL_RELEASENAME           = 0
COL_RELEASEID             = 1
COL_RELEASESTATUS         = 2
COL_RELEASEORIGINALSTATUS = 3
# COL_RELEASEORIGNALNAME    = 4 # update numCols in QtDesigner

WIZARD_PAGE_STATUS   = 0
WIZARD_PAGE_PROGRESS = 1

# helper class to ensure that release names are aligned to the left
# since a release name "0.7" would align to the right based on QTable
# however "0.7.1" would align to the left.
class LeftTextItem(QTableItem):
    def __init__(self, table, et, text=""):
        QTableItem.__init__(self, table, et, from_utf8(text))
        
    def alignment(self):
        return Qt.AlignLeft | Qt.AlignVCenter
        

class ReleaseStatusWizard(ReleaseStatusWizardBA):
    def __init__(self, parent, settings, sf_comm, projectVO, packageVO):
        ReleaseStatusWizardBA.__init__(self)
            
        self.parent = parent
        self.settings = settings
        self.sf_comm = sf_comm
        self.projectVO = projectVO
        self.packageVO = packageVO
                        
        self.group_id = projectVO.getGroupId()
        self.package_id = packageVO.getPackageId()

        self.setTitle(self.page(WIZARD_PAGE_STATUS),
                      "Releases for: %s - %s" % (projectVO.getProjectName(),
                                                 packageVO.getPackageName()))

        self.timer = QTimer(self)
        self.connect(self.timer, SIGNAL("timeout()"),
                     self.getProgressMsg)

        
        self.selected_files = set() #????

        #self.releaseStatusTable.setColumnReadOnly(COL_RELEASENAME, True)
        self.releaseStatusTable.setColumnReadOnly(COL_RELEASEID, True)
        self.releaseStatusTable.setLeftMargin(0)

        self.releaseStatusTable.hideColumn(COL_RELEASEORIGINALSTATUS)
        
        self.table_font_metrics = QFontMetrics(self.releaseStatusTable.font()) #???
        
        self.thread = None
        self.eventDict = {EVENT_RELEASE_STATUS: self.updateStatus,
                          EVENT_GET_RELEASES: self.populateReleases,
                          EVENT_RELEASE_UPDATED: self.update}

        self.successful_completion = False
        self.cancelled = False
        self.update_list = None
        self.current_idx = 0
        #self.__resizeComboTableItems()

        self.show()
        self.getReleases()


    def customEvent(self, event):
        data = event.data()
        etype = event.type()
        #print etype
        event_action = self.eventDict.get(etype)
        if event_action: event_action(data)



    def __wait(self):
        if not self.thread: return
        while self.thread.running():
            debug("waiting for thread to complete...")
            time.sleep(0.25)
            

    def getProgressMsg(self):
        # read the message queue.  If an item exists,
        # populate the progress label with it.
        msg = progressMessageQueue.get()
        if msg:
            self.progressTextLabel.setText(msg)
            self.progressBar.setProgress(self.progressBar.progress()+1)


    def next(self):
        ReleaseStatusWizardBA.next(self)
        self.updateStatus()


    def hideSelected(self):
        self.setSelected("Hidden")

    def activateSelected(self):
        self.setSelected("Active")

    def setSelected(self, status):
        numsel = self.releaseStatusTable.numSelections()

        for i in range(numsel):
            tsel = self.releaseStatusTable.selection(i)
            for rownum in range(tsel.topRow(), tsel.bottomRow()+1):
                statusCombo = self.releaseStatusTable.item(rownum, COL_RELEASESTATUS)
                statusCombo.setCurrentItem(status)
    

    def updateStatus(self):
        numrows = self.releaseStatusTable.numRows()
        update_list = []
        for i in range(numrows):
            statusCombo = self.releaseStatusTable.item(i, COL_RELEASESTATUS)
            curr_value = str(statusCombo.currentText())
            orig_value = str(self.releaseStatusTable.text(i, COL_RELEASEORIGINALSTATUS))
            if curr_value == orig_value: continue
            release_id = str(self.releaseStatusTable.text(i, COL_RELEASEID))
            release_name = to_utf8(self.releaseStatusTable.item(i, COL_RELEASENAME).text())

            update_list.append( (release_id, release_name, curr_value) )
        debug("update_list: %s", update_list)

        if not update_list:
            self.progressTextLabel.setText("Nothing to update")
            self.update_list = None
            return
        else:
            self.update_list = update_list
            self.current_idx = 0
            self.startUpdate()


    def getReleases(self):
        self.setNextEnabled(self.page(WIZARD_PAGE_STATUS), False)

        self.setCursor(Qt.waitCursor)
        self.thread = WorkerThread(self,
                                   EVENT_GET_RELEASES,
                                   self.sf_comm.get_releases,
                                   self.group_id,
                                   self.package_id)        
        self.thread.start()


    def populateReleases(self, releases):
        if not releases:
            QMessageBox.warning(self,
                                "Releases not found",
                                "There are no current releases\nfor the selected package")
            self.reject()

        rownum = 0
        releases.reverse() # most recent releases first
        for release in releases:
            #debug("release: %s", release)
            self.releaseStatusTable.setNumRows(rownum + 1)
            release_item = LeftTextItem(self.releaseStatusTable,
                                        QTableItem.Never,  # see note
                                        release[0].strip())

            # note: in the future, if release_names can be edited:
            #       change this to "QTableItem.Any" and also add a column
            #       for original release name.  When submitting the updates
            #       check to see if release name and/or status has been changed

            self.releaseStatusTable.setItem(rownum, COL_RELEASENAME, release_item)
            self.releaseStatusTable.setText(rownum, COL_RELEASEID, release[1])
            self.releaseStatusTable.setText(rownum,
                                            COL_RELEASEORIGINALSTATUS,
                                            release[2])
                                    
            statusData = self.__getStatusComboData()
            statusCombo = QComboTableItem(self.releaseStatusTable,
                                          statusData)
            statusCombo.setCurrentItem(release[2])
            self.releaseStatusTable.setItem(rownum, COL_RELEASESTATUS, statusCombo)

            rownum += 1

        self.setNextEnabled(self.page(WIZARD_PAGE_STATUS), True)
        self.setCursor(Qt.arrowCursor)


    def __getStatusComboData(self):
        qlist = QStringList()
        qlist.append("Active")
        qlist.append("Hidden")
        return qlist


    def startUpdate(self):
        self.progressBar.setProgress(-1)
        self.current_idx = 0
        self.progressBar.setTotalSteps(len(self.update_list))
        self.update()

    
    def update(self, data=None):

        if self.current_idx >= len(self.update_list):
            self.endUpdate()
            return

        release_id, release_name, status = self.update_list[self.current_idx]
        self.progressTextLabel.setText(from_utf8(release_name))
        self.progressBar.setProgress(self.current_idx + 1)

        self.current_idx += 1
        
        self.thread = WorkerThread(self,
                                   EVENT_RELEASE_UPDATED,
                                   self.sf_comm.update_release,
                                   self.group_id,
                                   self.package_id,
                                   release_id,
                                   release_name,
                                   status)        
        self.thread.start()


    def endUpdate(self):
        self.current_idx = 0
        self.setFinishEnabled(self.page(WIZARD_PAGE_PROGRESS), True)
        self.setBackEnabled(self.page(WIZARD_PAGE_PROGRESS), False)


    def help(self):
        self._help = Help(self, "release_status.html")
