
from CvPythonExtensions import *
import CvUtil
import ScreenInput
import CvScreenEnums
import BugUtil
import math


# globals
gc = CyGlobalContext()
ArtFileMgr = CyArtFileMgr()
localText = CyTranslator()

class IconData:

    def __init__(self, sImage, iSize, widgetType, iData1, iData2=-1, bEnabled=True):
        self.image = sImage
        self.widgetType = widgetType
        self.data1 = iData1
        self.data2 = iData2
        self.size = iSize
        self.enabled = bEnabled
    
class StackedBarData:

    def __init__(self, fValue, sColor, sText, iFont):
        self.value = fValue
        self.color = sColor
        self.text = sText
        self.font = iFont

class CellData:

    def __init__(self):
        self.icons = []
        self.stackedbar = []
        self.text = ""
        self.font = 3
    
    def addIcon(self, sImage, iSize, widgetType, iData1, iData2=-1, bEnabled=True):
        self.icons.append(IconData(sImage, iSize, widgetType, iData1, iData2, bEnabled))
    
    def setText(self, sText, iFont):
        self.text = sText
        self.font = iFont
    
    def addStackedBar(self, fValue, sColor, sText, iFont):
        self.stackedbar.append(StackedBarData(fValue, sColor, sText, iFont))
    
    
    
class RowData:

    def __init__(self, sRowHeader, sMessage, iFont, iNumColumns):
        self.rowHeader = sRowHeader
        self.message = sMessage
        self.font = iFont
        self.cells = []
        for i in range(iNumColumns):
            self.cells.append(CellData())
    
    def addIcon(self, iColumnIndex, sImage, iSize, widgetType, iData1, iData2=-1, bEnabled=True):
        self.cells[iColumnIndex].addIcon(sImage, iSize, widgetType, iData1, iData2, bEnabled)
    
    def setText(self, iColumnIndex, sText, iFont):
        self.cells[iColumnIndex].setText(sText, iFont)

    def addStackedBar(self, iColumnIndex, fValue, sColor, sText, iFont):
        self.cells[iColumnIndex].addStackedBar(fValue, sColor, sText, iFont)
    
    
    

class ColumnGroup:

    def __init__(self, sLabel, iLength):
        self.label = sLabel
        self.length = iLength

GRID_ICON_COLUMN = 0
GRID_MULTI_LIST_COLUMN = 1
GRID_TEXT_COLUMN = 2
GRID_STACKEDBAR_COLUMN = 3

class IconGrid_BUG:
    
    def __init__(self, sWidgetId, screen, iX, iY, iWidth, iHeight, columns, bUseSmallIcons, bShowRowHeader, bShowRowBorder):
        self.WIDGET_ID = sWidgetId
        self.NEXT_WIDGET_ID = sWidgetId + "IG"
        self.widgetCount = 0
        self.screen = screen
        self.xStart = iX
        self.yStart = iY
        self.width = iWidth
        self.height = iHeight
        self.columns = columns
        self.useSmallIcons = bUseSmallIcons
        self.showRowHeader = bShowRowHeader
        self.showRowBorder = bShowRowBorder
        self.columnGroups = []
        self.header = []
        self.headerFont = []
        self.data = []
        self.scrollPosition = 0
        self.textColWidth = {}
        self.StackedBarColWidth = {}
        
        for i in range(len(self.columns)):
            self.header.append("")
            self.headerFont.append(3)
    
        self.groupTitleHeight = 24
        self.headerHeight = 24
        self.rowHeight = 68
        self.rowHeaderHeight = 17
        self.scrollArrowSize = 24
        self.rowBorderWidth = 3
        self.scrollSpace = 3

        iTemp = [0, 0, 35, 30, 0]
        self.iconColWidth = 55 + iTemp[CyGame().getCurrentLanguage()]

        self.groupBorder = 10
        self.groupLabelOffset = "  "
        self.minColSpace = 3
        self.minRowSpace = 0
        
        self.SCROLL_UP = 1
        self.SCROLL_DOWN = 2
        self.SCROLL_PAGE_UP = 3
        self.SCROLL_PAGE_DOWN = 4
        self.SCROLL_TOP = 5
        self.SCROLL_BOTTOM = 6
        
        self.inputFunctionMap = {
            self.SCROLL_UP: self.scrollUp,
            self.SCROLL_DOWN: self.scrollDown,
            self.SCROLL_PAGE_UP: self.scrollPageUp,
            self.SCROLL_PAGE_DOWN: self.scrollPageDown,
            self.SCROLL_TOP: self.scrollTop,
            self.SCROLL_BOTTOM: self.scrollBottom,
        }
        self.keyFunctionMap = {
            int(InputTypes.KB_UP): self.scrollUp,
            int(InputTypes.KB_DOWN): self.scrollDown,
            int(InputTypes.KB_PGUP): self.scrollPageUp,
            int(InputTypes.KB_PGDN): self.scrollPageDown,
            int(InputTypes.KB_HOME): self.scrollTop,
            int(InputTypes.KB_END): self.scrollBottom,
        }
        

    def setGroupBorder(self, iVal):
        self.groupBorder = iVal
    
        
    def setGroupLabelOffset(self, sVal):
        self.groupLabelOffset = sVal
        
        
    def setMinColumnSpace(self, iVal):
        self.minColSpace = iVal
    
        
    def setMinRowSpace(self, iVal):
        self.minRowSpace = iVal
        
        
    def setSize(self, iWidth, iHeight):
        self.width = iWidth
        self.height = iHeight

    
    def setPosition(self, iX, iY):
        self.xStart = iX
        self.yStart = iY

    
    def getPrefferedWidth(self):
        self.calculateLayout()
        
        prefferedWidth = self.scrollArrowSize + self.scrollSpace + self.minColSpace * (len(self.columns) - 1)
        for colGroup in self.columnGroups:
            if (colGroup.label != ""):
                prefferedWidth += self.groupBorder * 2
        
        for index in range(len(self.columns)):
            if (self.columns[index] == GRID_ICON_COLUMN):
                prefferedWidth += self.iconColWidth
            elif (self.columns[index] == GRID_MULTI_LIST_COLUMN):
                prefferedWidth += self.multiListColWidth
            elif (self.columns[index] == GRID_TEXT_COLUMN):
                prefferedWidth += self.textColWidth[index]
            elif (self.columns[index] == GRID_STACKEDBAR_COLUMN):
                prefferedWidth += self.StackedBarColWidth[index]
        
        if (self.showRowBorder):
            prefferedWidth += self.rowBorderWidth * 2
        return prefferedWidth

            
    
    def getPrefferedHeight(self):
        self.calculateLayout()
        initHeight = self.totalRowHeight * self.numRows + self.minRowSpace * (self.numRows - 1)
        
        if (len(self.columnGroups) > 0):
            if (not self.showRowHeader):
                return initHeight + self.colGroupHeight + 10
            else:
                return initHeight + self.colGroupHeight + 5
        else:
            return initHeight + self.headerHeight
    
    
    def setHeader(self, iCol, sLabel, iFont=3):
        self.header[iCol] = sLabel
        self.headerFont[iCol] = iFont
        
        
    def setTextColWidth(self, iCol, iWidth):
        self.textColWidth[iCol] = iWidth

    def setStackedBarColWidth(self, iCol, iWidth):
        self.StackedBarColWidth[iCol] = iWidth
        
    def createColumnGroup(self, sLabel, iLength):
        self.columnGroups.append(ColumnGroup(sLabel, iLength))

    
    def createGrid(self):
        self.calculateLayout()
        self.addControls()

    def hideGrid(self):
        self.widgetCount = 0
        self.hideControls()


    def appendRow(self, sRowHeader, sMessage, iFont=3):
        self.data.append(RowData(sRowHeader, sMessage, iFont, len(self.columns)))

    def addIcon(self, iRowIndex, iColumnIndex, sImage, iSize, widgetType, iData1, iData2=-1, bEnabled=True):
        self.data[iRowIndex].addIcon(iColumnIndex, sImage, iSize, widgetType, iData1, iData2, bEnabled)

    def setText(self, iRowIndex, iColumnIndex, sText, iFont=3):
        self.data[iRowIndex].setText(iColumnIndex, sText, iFont)

    def addStackedBar(self, iRowIndex, iColumnIndex, fValue, sColor, sText, iFont=3):
#       BugUtil.debug("addStackedbar %i %i %s %s %i" % (iColumnIndex, fValue, sColor, sText, iFont))
        self.data[iRowIndex].addStackedBar(iColumnIndex, fValue, sColor, sText, iFont)

    def clearData(self):
        self.scrollPosition = 0
        self.data = []
    
    
    def scrollUp(self):
        self.scrollPosition = self.scrollPosition - 1
        self.refresh()
    
    def scrollDown(self):
        self.scrollPosition = self.scrollPosition + 1
        self.refresh()
    
    def scrollPageUp(self):
        self.scrollPosition = self.scrollPosition - (self.numRows - 1)
        self.refresh()
    
    def scrollPageDown(self):
        self.scrollPosition = self.scrollPosition + (self.numRows - 1)
        self.refresh()
    
    def scrollTop(self):
        self.scrollPosition = 0
        self.refresh()
    
    def scrollBottom(self):
        self.scrollPosition = len(self.data) - self.numRows
        self.refresh()
    
    def handleInput(self, inputClass):
        if (inputClass.getNotifyCode() == NotifyCode.NOTIFY_CLICKED):
            if (inputClass.getButtonType() == WidgetTypes.WIDGET_GENERAL):
                func = self.inputFunctionMap.get(inputClass.getData1(), None)
                if func is not None:
                    BugUtil.debug("calling %r", func)
                    func()
                    return 1
        
        elif (inputClass.getNotifyCode() == NotifyCode.NOTIFY_CHARACTER):
            func = self.keyFunctionMap.get(inputClass.getData(), None)
            if func:
                if inputClass.getID():
                    BugUtil.debug("calling %r", func)
                    func()
                return 1
        
        return 0
    
    
    def refresh(self):
        # check if scrollPosistion is valid and show/hide scroll buttons
        if (self.scrollPosition <= 0):
            self.screen.hide(self.scrollUpArrow)
            self.screen.hide(self.pageUpArrow)
            self.screen.hide(self.scrollTopArrow)
            self.scrollPosition = 0
        else:
            self.screen.show(self.scrollUpArrow)
            self.screen.show(self.pageUpArrow)
            self.screen.show(self.scrollTopArrow)
        
        if (self.scrollPosition >= len(self.data) - self.numRows):
            self.screen.hide(self.scrollDownArrow)
            self.screen.hide(self.pageDownArrow)
            self.screen.hide(self.scrollBottomArrow)
            self.scrollPosition = max(0, len(self.data) - self.numRows)
        else:
            self.screen.show(self.scrollDownArrow)
            self.screen.show(self.pageDownArrow)
            self.screen.show(self.scrollBottomArrow)

        maxIndex = min(self.numRows, len(self.data))
        for rowIndex in range(maxIndex):
            rowData = self.data[self.scrollPosition + rowIndex]

            currentX = self.xStart
            currentY = self.firstRowY + (self.totalRowHeight + self.rowSpace) * rowIndex + 2
            if (self.showRowBorder):
                currentX += self.rowBorderWidth
                currentY += self.rowBorderWidth + 1
            if (self.showRowHeader):
                currentY += self.rowHeaderHeight
                text = "<font=%i>%s</font>" % (rowData.font, rowData.rowHeader)
                self.screen.setLabel(self.rowName + str(rowIndex) + "name", "",
                                     text, CvUtil.FONT_LEFT_JUSTIFY,
                                     self.xStart + 5, self.firstRowY + (self.totalRowHeight + self.rowSpace) * rowIndex - 3,
                                     0, FontTypes.GAME_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1 )
            
            startIndex = 0
            for groupIndex in range(len(self.columnGroups)):
                colGroup = self.columnGroups[groupIndex]
                if (colGroup.label != ""):
                    currentX += self.groupBorder

                # put info in grouped columns
                for offset in range(colGroup.length):
#                   BugUtil.debug("Grouped Column %i %i" % (startIndex + offset, self.columns[startIndex + offset]))
                    if (self.columns[startIndex + offset] == GRID_ICON_COLUMN):
                        bDataFound = True
                        try:
                            iconData = rowData.cells[startIndex + offset].icons[0]
                        except:
                            bDataFound = False

                        szIcon_ID = self.rowName + str(rowIndex) + "_" + str(startIndex + offset)
                        if bDataFound:
                            self.screen.setImageButton(szIcon_ID,
                                                       iconData.image, currentX - (iconData.size - 64) / 2, currentY - (iconData.size - 64) / 2, iconData.size, iconData.size, 
                                                       iconData.widgetType, iconData.data1, iconData.data2)
                        else:
                            self.screen.deleteWidget(szIcon_ID)
                        currentX += self.iconColWidth + self.colSpace

                    elif (self.columns[startIndex + offset] == GRID_MULTI_LIST_COLUMN):
                        listName = self.rowName + str(rowIndex) + "_" + str(startIndex + offset)
                        self.screen.clearMultiList(listName)
                        iCount = 0
                        for icon in rowData.cells[startIndex + offset].icons:
                            self.screen.appendMultiListButton(listName, icon.image, 0, icon.widgetType, icon.data1, icon.data2, False)
                            if not icon.enabled:
                                self.screen.disableMultiListButton( listName, 0, iCount, icon.image)
                            iCount += 1
                        currentX += self.multiListColWidth + self.colSpace

                    elif (self.columns[startIndex + offset] == GRID_TEXT_COLUMN):
                        textY = self.firstRowY + (self.totalRowHeight + self.rowSpace) * rowIndex + 28
                        if (self.showRowHeader):
                            textY += self.rowHeaderHeight
                        text = "<font=%i>%s</font>" % (rowData.cells[startIndex + offset].font, rowData.cells[startIndex + offset].text)
                        self.screen.setLabel( self.rowName + str(rowIndex) + "_" + str(startIndex + offset), ""
                                            , text, CvUtil.FONT_LEFT_JUSTIFY
                                            , currentX + 6, textY, 0, FontTypes.GAME_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1 )
                        currentX += self.textColWidth[startIndex + offset] + self.colSpace

                    elif (self.columns[startIndex + offset] == GRID_STACKEDBAR_COLUMN):
#                       BugUtil.debug("Stacked Bar Start A")

                        bDataFound = True
                        try:
#                           BugUtil.debug("Stacked Bar try")
                            stackedbarData = rowData.cells[startIndex + offset].stackedbar[0]
                        except:
                            bDataFound = False

#                       BugUtil.debug("Stacked Bar data found? %s" % (bDataFound))
                        if bDataFound:      
                            textY = self.firstRowY + (self.totalRowHeight + self.rowSpace) * rowIndex + 20
                            if (self.showRowHeader):
                                textY += self.rowHeaderHeight

                            width = self.StackedBarColWidth[startIndex + offset] - 15

                            if stackedbarData.text != "" and stackedbarData.value > 0:
                                iSBarOffset_Y = 10
                            else:
                                iSBarOffset_Y = 0

#                           BugUtil.debug("Stacked Bar value %i" % (stackedbarData.value))
                            szBar_ID = self.rowName + str(rowIndex) + "_" + str(startIndex + offset) + "SB"
                            if stackedbarData.value > 0:
                                self.screen.addStackedBarGFC(szBar_ID, 
                                                             currentX + 6, textY + iSBarOffset_Y, width, 25,
                                                             InfoBarTypes.NUM_INFOBAR_TYPES, WidgetTypes.WIDGET_GENERAL, -1, -1 )

                                self.screen.setBarPercentage(szBar_ID, InfoBarTypes.INFOBAR_STORED, float(stackedbarData.value) / float(100))
                                self.screen.setStackedBarColors(szBar_ID, InfoBarTypes.INFOBAR_STORED, gc.getInfoTypeForString(stackedbarData.color))
                            else:
                                self.screen.deleteWidget(szBar_ID)

                            szTxt_ID = self.rowName + str(rowIndex) + "_" + str(startIndex + offset) + "T"
                            if stackedbarData.text != "":
                                text = "<font=%i>%s</font>" % (stackedbarData.font, stackedbarData.text)
                                self.screen.setLabel (szTxt_ID, "",
                                                      text, CvUtil.FONT_CENTER_JUSTIFY,
                                                      currentX + 6 + width / 2, textY - iSBarOffset_Y,
                                                      -0.1, FontTypes.GAME_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1)
                            else:
                                self.screen.deleteWidget(szTxt_ID)

                        currentX += self.StackedBarColWidth[startIndex + offset] + self.colSpace
#                       BugUtil.debug("Stacked Bar done")

                startIndex += colGroup.length
                if (colGroup.label != ""):
                    currentX += self.groupBorder        
            
            # put info in non grouped columns
            for offset in range(len(self.columns) - startIndex):
#               BugUtil.debug("Single Column %i %i" % (startIndex + offset, self.columns[startIndex + offset]))
                if (self.columns[startIndex + offset] == GRID_ICON_COLUMN):
                    bDataFound = True
                    try:
                        iconData = rowData.cells[startIndex + offset].icons[0]
                    except:
                        bDataFound = False

                    if bDataFound:      
                        self.screen.setImageButton(self.rowName + str(rowIndex) + "_" + str(startIndex + offset), 
                                                   iconData.image, currentX - (iconData.size - 64) / 2, currentY - (iconData.size - 64) / 2, iconData.size, iconData.size, 
                                                   iconData.widgetType, iconData.data1, iconData.data2 )
                    currentX += self.iconColWidth + self.colSpace

                elif (self.columns[startIndex + offset] == GRID_MULTI_LIST_COLUMN):
                    self.screen.clearMultiList(self.rowName + str(rowIndex) + "_" + str(startIndex + offset))
                    for icon in rowData.cells[startIndex + offset].icons:
                        self.screen.appendMultiListButton( self.rowName + str(rowIndex) + "_" + str(startIndex + offset)
                                                         , icon.image, 0, icon.widgetType, icon.data1, icon.data2, False )
                    currentX += self.multiListColWidth + self.colSpace

                elif (self.columns[startIndex + offset] == GRID_TEXT_COLUMN):
                    text = "<font=%i>%s</font>" % (rowData.cells[startIndex + offset].font, rowData.cells[startIndex + offset].text)
                    self.screen.setLabel(self.rowName + str(rowIndex) + "_" + str(startIndex + offset), "", 
                                         text, CvUtil.FONT_LEFT_JUSTIFY, 
                                         currentX + 6, self.firstRowY + (self.totalRowHeight + self.rowSpace) * rowIndex + 28, 
                                         0, FontTypes.GAME_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1 )
                    currentX += self.textColWidth[startIndex + offset] + self.colSpace

                elif (self.columns[startIndex + offset] == GRID_STACKEDBAR_COLUMN):
#                   BugUtil.debug("Stacked Bar Start B")
                    bDataFound = True
                    try:
                        stackedbarData = rowData.cells[startIndex + offset].stackedbar[0]
                    except:
                        bDataFound = False

                    if bDataFound:      
                        textY = self.firstRowY + (self.totalRowHeight + self.rowSpace) * rowIndex + 20

                        width = self.StackedBarColWidth[startIndex + offset] - 15

                        if stackedbarData.text != "" and stackedbarData.value > 0:
                            iSBarOffset_Y = 10
                        else:
                            iSBarOffset_Y = 0

#                       BugUtil.debug("Stacked Bar value %i" % (stackedbarData.value))
                        szBar_ID = self.rowName + str(rowIndex) + "_" + str(startIndex + offset) + "SB"
                        if stackedbarData.value > 0:
                            szBar_ID = self.rowName + str(rowIndex) + "_" + str(startIndex + offset) + "SB"
                            self.screen.addStackedBarGFC(szBar_ID, 
                                                         currentX + 6, textY + iSBarOffset_Y, width, 25,
                                                         InfoBarTypes.NUM_INFOBAR_TYPES, WidgetTypes.WIDGET_GENERAL, -1, -1 )
                            self.screen.setBarPercentage(szBar_ID, InfoBarTypes.INFOBAR_STORED, float(stackedbarData.value) / float(100))
                            self.screen.setStackedBarColors(szBar_ID, InfoBarTypes.INFOBAR_STORED, gc.getInfoTypeForString(stackedbarData.color))
                        else:
                            self.screen.deleteWidget(szBar_ID)

                        szTxt_ID = self.rowName + str(rowIndex) + "_" + str(startIndex + offset) + "T"
                        if stackedbarData.text != "":
                            text = "<font=%i>%s</font>" % (stackedbarData.font, stackedbarData.text)
                            self.screen.setLabel (szTxt_ID, "",
                                                  text, CvUtil.FONT_CENTER_JUSTIFY,
                                                  currentX + 6 + width / 2, textY - iSBarOffset_Y,
                                                  -0.1, FontTypes.GAME_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1)
                        else:
                            self.screen.deleteWidget(szTxt_ID)

                    currentX += self.StackedBarColWidth[startIndex + offset] + self.colSpace
#                   BugUtil.debug("Stacked Bar done")
            
            if ( rowData.message == "" ):
                self.screen.attachLabel(self.rowName + str(rowIndex), self.rowName + str(rowIndex) + "NotConnected", "")
            else:
                text = "<font=%i>                              %s</font>" % (rowData.font, rowData.message)
                self.screen.attachLabel(self.rowName + str(rowIndex),
                                        self.rowName + str(rowIndex) + "NotConnected",
                                        text)

    def calculateLayout(self):
        if (self.useSmallIcons):
            self.iconSize = 32
        else:
            self.iconSize = 64
        # width
        availableWidth = self.width - self.scrollArrowSize - self.scrollSpace - self.minColSpace * (len(self.columns) - 1)
        useColGroups = False
        for colGroup in self.columnGroups:
            if (colGroup.label != ""):
                availableWidth -= self.groupBorder * 2
                useColGroups = True
        
        numMultiListCols = 0
        for colIndex in range(len(self.columns)):
            col = self.columns[colIndex]
            if (col == GRID_ICON_COLUMN):
                availableWidth -= self.iconColWidth
            if (col == GRID_MULTI_LIST_COLUMN):
                numMultiListCols += 1
            if (col == GRID_TEXT_COLUMN):
                availableWidth -= self.textColWidth[colIndex]
            if (col == GRID_STACKEDBAR_COLUMN):
                availableWidth -= self.StackedBarColWidth[colIndex]
        
        if (self.showRowBorder):
            availableWidth -= self.rowBorderWidth * 2
        
        initMultiListColWidth = availableWidth / numMultiListCols
        numIcons = (initMultiListColWidth - 16) / (self.iconSize + 2)
        self.multiListColWidth = numIcons * (self.iconSize + 2) + 16
        self.colSpace = (availableWidth - self.multiListColWidth * numMultiListCols) / (len(self.columns) - 1) + self.minColSpace
        
        # height
        if (useColGroups):
            self.colGroupHeight = self.groupTitleHeight + self.headerHeight + 8
            self.headerY = self.yStart + self.groupTitleHeight + 3
            self.firstRowY = self.headerY + self.headerHeight + 7
            availableHeight = self.height - self.colGroupHeight - 5
            if (not self.showRowHeader):
                self.firstRowY += 5
                availableHeight -= 5
        else:
            self.colCroupHeight = 0
            self.headerY = self.yStart
            self.firstRowY = self.headerY + self.headerHeight
            availableHeight = self.height - self.headerHeight
        
        if (self.showRowHeader):
            self.totalRowHeight = self.rowHeight + self.rowHeaderHeight
            self.multiListStartY = self.firstRowY + self.rowHeaderHeight
        else:
            self.totalRowHeight = self.rowHeight
            self.multiListStartY = self.firstRowY
        
        if (self.showRowBorder):
            self.totalRowHeight += self.rowBorderWidth * 2
        
        self.numRows = (availableHeight + self.minRowSpace) / (self.totalRowHeight + self.minRowSpace)
        self.rowSpace = (availableHeight - self.numRows * self.totalRowHeight) / (self.numRows - 1)
        
    def addControls(self):
        self.addGroups()
        self.addHeader()
        
        # add the rows
        self.leaderHeadName = self.getNextWidgetName()
        self.multiListName = self.getNextWidgetName()
        self.rowName = self.getNextWidgetName()
        
        for rowIndex in range(self.numRows):
            self.addRow(rowIndex)
        
        self.scrollUpArrow = self.getNextWidgetName()
        self.scrollDownArrow = self.getNextWidgetName()
        self.pageUpArrow = self.getNextWidgetName()
        self.pageDownArrow = self.getNextWidgetName()
        self.scrollTopArrow = self.getNextWidgetName()
        self.scrollBottomArrow = self.getNextWidgetName()
        x = self.xStart + self.width - self.scrollArrowSize
        y = self.firstRowY
        self.screen.setImageButton( self.scrollTopArrow
                                  , ArtFileMgr.getInterfaceArtInfo("SCROLL_TOP_ARROW").getPath()
                                  , x, y
                                  , self.scrollArrowSize, self.scrollArrowSize
                                  , WidgetTypes.WIDGET_GENERAL, self.SCROLL_TOP, -1 )
        self.screen.setImageButton( self.pageUpArrow
                                  , ArtFileMgr.getInterfaceArtInfo("SCROLL_PAGE_UP_ARROW").getPath()
                                  , x, y + self.scrollArrowSize + 4
                                  , self.scrollArrowSize, self.scrollArrowSize
                                  , WidgetTypes.WIDGET_GENERAL, self.SCROLL_PAGE_UP, -1 )
        self.screen.setImageButton( self.scrollUpArrow
                                  , ArtFileMgr.getInterfaceArtInfo("SCROLL_UP_ARROW").getPath()
                                  , x, y + 2 * (self.scrollArrowSize + 4)
                                  , self.scrollArrowSize, self.scrollArrowSize
                                  , WidgetTypes.WIDGET_GENERAL, self.SCROLL_UP, -1 )
        
        y = self.yStart + self.height - self.scrollArrowSize
        self.screen.setImageButton( self.scrollDownArrow
                                  , ArtFileMgr.getInterfaceArtInfo("SCROLL_DOWN_ARROW").getPath()
                                  , x, y - 2 * (self.scrollArrowSize + 4)
                                  , self.scrollArrowSize, self.scrollArrowSize
                                  , WidgetTypes.WIDGET_GENERAL, self.SCROLL_DOWN, -1 )
        self.screen.setImageButton( self.pageDownArrow
                                  , ArtFileMgr.getInterfaceArtInfo("SCROLL_PAGE_DOWN_ARROW").getPath()
                                  , x, y - (self.scrollArrowSize + 4)
                                  , self.scrollArrowSize, self.scrollArrowSize
                                  , WidgetTypes.WIDGET_GENERAL, self.SCROLL_PAGE_DOWN, -1 )
        self.screen.setImageButton( self.scrollBottomArrow
                                  , ArtFileMgr.getInterfaceArtInfo("SCROLL_BOTTOM_ARROW").getPath()
                                  , x, y
                                  , self.scrollArrowSize, self.scrollArrowSize
                                  , WidgetTypes.WIDGET_GENERAL, self.SCROLL_BOTTOM, -1 )

    def addGroups(self):
        self.groupPanelName = self.getNextWidgetName()
        
        startIndex = 0
        lastColGroupIndex = 0
        colGroupX = self.xStart
        
        for index in range(len(self.columnGroups)):
            colGroup = self.columnGroups[index]
            if (colGroup.label != ""):
                colGroupWidth = self.groupBorder * 2
                for offset in range(colGroup.length):
                    if (self.columns[startIndex + offset] == GRID_ICON_COLUMN):
                        colGroupWidth += self.iconColWidth + self.colSpace
                    elif (self.columns[startIndex + offset] == GRID_MULTI_LIST_COLUMN):
                        colGroupWidth += self.multiListColWidth + self.colSpace
                    elif (self.columns[startIndex + offset] == GRID_TEXT_COLUMN):
                        colGroupWidth += self.textColWidth[startIndex + offset] + self.colSpace
                    elif (self.columns[startIndex + offset] == GRID_STACKEDBAR_COLUMN):
                        colGroupWidth += self.StackedBarColWidth[startIndex + offset] + self.colSpace

                colGroupWidth -= self.colSpace
                if (colGroup.length == 1):
                    self.groupLabelOffset = "  "
                    self.screen.addPanel( self.groupPanelName + str(index), self.groupLabelOffset + colGroup.label, "", False, False
                                        , colGroupX, self.yStart, colGroupWidth + 7, self.colGroupHeight
                                        , PanelStyles.PANEL_STYLE_EMPTY )
                else:
                    self.groupLabelOffset = "  "
                    self.screen.addPanel( self.groupPanelName + str(index), self.groupLabelOffset + colGroup.label, "", False, False
                                        , colGroupX, self.yStart, colGroupWidth + 7, self.colGroupHeight
                                        , PanelStyles.PANEL_STYLE_MAIN_TAN )
                colGroupX += colGroupWidth + self.colSpace
            else:
                for offset in range(colGroup.length):
                    if (self.columns[startIndex + offset] == GRID_ICON_COLUMN):
                        colGroupX += self.iconColWidth + self.colSpace
                    elif (self.columns[startIndex + offset] == GRID_MULTI_LIST_COLUMN):
                        colGroupX += self.multiListColWidth + self.colSpace
                    elif (self.columns[startIndex + offset] == GRID_TEXT_COLUMN):
                        colGroupX += self.textColWidth[startIndex + offset] + self.colSpace
                    elif (self.columns[startIndex + offset] == GRID_STACKEDBAR_COLUMN):
                        colGroupX += self.StackedBarColWidth[startIndex + offset] + self.colSpace

            startIndex += colGroup.length
            
    def addHeader(self):
        self.headerName = self.getNextWidgetName()
        headerX = self.xStart
        if (len(self.columnGroups) > 0 and self.columnGroups[0].label != ""):
            headerX += self.groupBorder
        self.screen.addTableControlGFC( self.headerName, len(self.columns)
                                      , headerX, self.headerY, self.width - self.scrollArrowSize, self.headerHeight
                                      , False, False, 16, 16, TableStyles.TABLE_STYLE_EMPTY )
        startIndex = 0
        for groupIndex in range(len(self.columnGroups)):
            colGroup = self.columnGroups[groupIndex]
            headerWidth = 0
            
            for offset in range(colGroup.length):
                if (self.columns[startIndex + offset] == GRID_ICON_COLUMN):
                    headerWidth = self.iconColWidth + self.colSpace
                elif (self.columns[startIndex + offset] == GRID_MULTI_LIST_COLUMN):
                    headerWidth = self.multiListColWidth + self.colSpace
                elif (self.columns[startIndex + offset] == GRID_TEXT_COLUMN):
                    headerWidth = self.textColWidth[startIndex + offset] + self.colSpace
                elif (self.columns[startIndex + offset] == GRID_STACKEDBAR_COLUMN):
                    headerWidth = self.StackedBarColWidth[startIndex + offset] + self.colSpace
                
                if (offset == colGroup.length - 1): # last column of this group
                    if (colGroup.label != ""):
                        headerWidth += self.groupBorder
                    if (groupIndex < len(self.columnGroups) - 1 and self.columnGroups[groupIndex + 1].label != ""):
                        headerWidth += self.groupBorder

                self.screen.setTableColumnHeader( self.headerName, startIndex + offset, "", headerWidth )
                text = "<font=%i>%s</font>" % (self.headerFont[startIndex + offset], self.header[startIndex + offset])
                self.screen.setTableText(self.headerName, startIndex + offset, 0,
                                         text, "", WidgetTypes.WIDGET_GENERAL, -1, -1, 0 )
            startIndex += colGroup.length
        
        for offset in range(len(self.columns) - startIndex):
            if (self.columns[startIndex + offset] == GRID_ICON_COLUMN):
                headerWidth = self.iconColWidth + self.colSpace
            elif (self.columns[startIndex + offset] == GRID_MULTI_LIST_COLUMN):
                headerWidth = self.multiListColWidth + self.colSpace
            elif (self.columns[startIndex + offset] == GRID_TEXT_COLUMN):
                headerWidth = self.textColWidth[startIndex + offset] + self.colSpace
            elif (self.columns[startIndex + offset] == GRID_STACKEDBAR_COLUMN):
                headerWidth = self.StackedBarColWidth[startIndex + offset] + self.colSpace

            self.screen.setTableColumnHeader( self.headerName, startIndex + offset, "", headerWidth )
            text = "<font=%i>%s</font>" % (self.headerFont[startIndex + offset], self.header[startIndex + offset])
            self.screen.setTableText(self.headerName, startIndex + offset, 0,
                                     text, "", WidgetTypes.WIDGET_GENERAL, -1, -1, 0 )

    def addRow(self, rowIndex):
        if (self.showRowBorder):
            panelY = self.firstRowY + (self.totalRowHeight + self.rowSpace) * rowIndex
            panelHeight = self.totalRowHeight
            if (self.showRowHeader):
                panelY += self.rowHeaderHeight
                panelHeight -= self.rowHeaderHeight
            
            self.screen.addPanel( self.rowName + str(rowIndex), "", "", False, True, self.xStart, panelY
                                , self.width - self.scrollArrowSize - self.scrollSpace, panelHeight
                                , PanelStyles.PANEL_STYLE_OUT )
        
        startIndex = 0
        currentX = self.xStart
        listY = self.multiListStartY + (self.totalRowHeight + self.rowSpace) * rowIndex
        if (self.showRowBorder):
            currentX += self.rowBorderWidth
            listY += self.rowBorderWidth + 1
        
        for groupIndex in range(len(self.columnGroups)):
            colGroup = self.columnGroups[groupIndex]
            if (colGroup.label != ""):
                currentX += self.groupBorder
            
            for offset in range(colGroup.length):
                if (self.columns[startIndex + offset] == GRID_ICON_COLUMN):
                    currentX += self.iconColWidth + self.colSpace
                elif (self.columns[startIndex + offset] == GRID_MULTI_LIST_COLUMN):
                    self.screen.addMultiListControlGFC( self.rowName + str(rowIndex) + "_" + str(startIndex + offset), ""
                                                      , currentX, listY, self.multiListColWidth, self.rowHeight
                                                      , 1, self.iconSize, self.iconSize, TableStyles.TABLE_STYLE_EMPTY )
                    currentX += self.multiListColWidth + self.colSpace
                elif (self.columns[startIndex + offset] == GRID_TEXT_COLUMN):
                    currentX += self.textColWidth[startIndex + offset] + self.colSpace
                elif (self.columns[startIndex + offset] == GRID_STACKEDBAR_COLUMN):
                    currentX += self.StackedBarColWidth[startIndex + offset] + self.colSpace
            
            startIndex += colGroup.length
            if (colGroup.label != ""):
                currentX += self.groupBorder        
        
        for offset in range(len(self.columns) - startIndex):
            if (self.columns[startIndex + offset] == GRID_ICON_COLUMN):
                currentX += self.iconColWidth + self.colSpace
            elif (self.columns[startIndex + offset] == GRID_MULTI_LIST_COLUMN):
                self.screen.addMultiListControlGFC( self.rowName + str(rowIndex) + "_" + str(startIndex + offset), ""
                                                  , currentX, listY, self.multiListColWidth, self.rowHeight
                                                  , 1, self.iconSize, self.iconSize, TableStyles.TABLE_STYLE_EMPTY )
                currentX += self.multiListColWidth + self.colSpace
            elif (self.columns[startIndex + offset] == GRID_TEXT_COLUMN):
                currentX += self.textColWidth[startIndex + offset] + self.colSpace
            elif (self.columns[startIndex + offset] == GRID_STACKEDBAR_COLUMN):
                currentX += self.StackedBarColWidth[startIndex + offset] + self.colSpace

    def hideControls(self):
        self.hideGroups()
        self.hideHeader()
        
        # add the rows
        self.leaderHeadName = self.getNextWidgetName()
        self.multiListName = self.getNextWidgetName()
        self.rowName = self.getNextWidgetName()
        
        for rowIndex in range(self.numRows):
            self.hideRow(rowIndex)
        
        self.scrollUpArrow = self.getNextWidgetName()
        self.scrollDownArrow = self.getNextWidgetName()
        self.pageUpArrow = self.getNextWidgetName()
        self.pageDownArrow = self.getNextWidgetName()
        self.scrollTopArrow = self.getNextWidgetName()
        self.scrollBottomArrow = self.getNextWidgetName()
        self.screen.deleteWidget(self.scrollUpArrow)
        self.screen.deleteWidget(self.scrollDownArrow)
        self.screen.deleteWidget(self.pageUpArrow)
        self.screen.deleteWidget(self.pageDownArrow)
        self.screen.deleteWidget(self.scrollTopArrow)
        self.screen.deleteWidget(self.scrollBottomArrow)

    def hideGroups(self):
        self.groupPanelName = self.getNextWidgetName()
        
        for index in range(len(self.columnGroups)):
            if (self.columnGroups[index].label != ""):
                self.screen.deleteWidget(self.groupPanelName + str(index))

    def hideHeader(self):
        self.headerName = self.getNextWidgetName()
        self.screen.deleteWidget(self.headerName)

    def hideRow(self, rowIndex):
        if (self.showRowBorder):
            self.screen.deleteWidget(self.rowName + str(rowIndex))

        if (self.showRowHeader):
            self.screen.deleteWidget(self.rowName + str(rowIndex) + "name")
        
        startIndex = 0
        for groupIndex in range(len(self.columnGroups)):
            colGroup = self.columnGroups[groupIndex]

            for offset in range(colGroup.length):
                if (self.columns[startIndex + offset] == GRID_ICON_COLUMN):
                    self.screen.hide( self.rowName + str(rowIndex) + "_" + str(startIndex + offset))
                elif (self.columns[startIndex + offset] == GRID_MULTI_LIST_COLUMN):
                    self.screen.deleteWidget(self.rowName + str(rowIndex) + "_" + str(startIndex + offset))
                elif (self.columns[startIndex + offset] == GRID_TEXT_COLUMN):
                    self.screen.hide( self.rowName + str(rowIndex) + "_" + str(startIndex + offset))
                elif (self.columns[startIndex + offset] == GRID_STACKEDBAR_COLUMN):
                    self.screen.hide( self.rowName + str(rowIndex) + "_" + str(startIndex + offset))
                    self.screen.hide( self.rowName + str(rowIndex) + "_" + str(startIndex + offset) + "SB")
                    self.screen.hide( self.rowName + str(rowIndex) + "_" + str(startIndex + offset) + "T")

            startIndex += colGroup.length
        
        for offset in range(len(self.columns) - startIndex):
            if (self.columns[startIndex + offset] == GRID_ICON_COLUMN):
                self.screen.hide( self.rowName + str(rowIndex) + "_" + str(startIndex + offset))
            elif (self.columns[startIndex + offset] == GRID_MULTI_LIST_COLUMN):
                self.screen.deleteWidget(self.rowName + str(rowIndex) + "_" + str(startIndex + offset))
            elif (self.columns[startIndex + offset] == GRID_TEXT_COLUMN):
                self.screen.hide( self.rowName + str(rowIndex) + "_" + str(startIndex + offset))
            elif (self.columns[startIndex + offset] == GRID_STACKEDBAR_COLUMN):
                self.screen.hide( self.rowName + str(rowIndex) + "_" + str(startIndex + offset))
                self.screen.hide( self.rowName + str(rowIndex) + "_" + str(startIndex + offset) + "SB")
                self.screen.hide( self.rowName + str(rowIndex) + "_" + str(startIndex + offset) + "T")

    def getNextWidgetName(self):
        szName = self.NEXT_WIDGET_ID + str(self.widgetCount)
        self.widgetCount += 1
        return szName
        
    def deleteAllWidgets(self):
        i = self.widgetCount - 1
        while (i >= 0):
            self.widgetCount = i
            self.screen.deleteWidget(self.getNextWidgetName())
            i -= 1

        self.widgetCount = 0

        self.screen.hide(self.scrollDownArrow)
        self.screen.hide(self.scrollDownArrow)

        maxIndex = min(self.numRows, len(self.data))
        for rowIndex in range(maxIndex):
            self.screen.hide(self.rowName + str(rowIndex) + "name")

            self.screen.deleteWidget(self.rowName + str(rowIndex))
            startIndex = 0
            for groupIndex in range(len(self.columnGroups)):
                colGroup = self.columnGroups[groupIndex]
                if (colGroup.label != ""):
                    currentX += self.groupBorder
                
                for offset in range(colGroup.length):
                    if (self.columns[startIndex + offset] == GRID_ICON_COLUMN):
                        self.screen.hide(self.rowName + str(rowIndex) + "_" + str(startIndex + offset))
