class ToonStatueSelectionGUI(DirectFrame):
    notify = DirectNotifyGlobal.directNotify.newCategory('ToonStatueSelectionGUI')

    def __init__(self, doneEvent, specialBoxActive = False):
        base.tssGUI = self
        instructions = TTLocalizer.GardeningChooseToonStatue
        instructionsPos = (0, 0.4)
        DirectFrame.__init__(self, relief=None, state='normal', geom=DGG.getDefaultDialogGeom(), geom_color=ToontownGlobals.GlobalDialogColor, geom_scale=(1.5, 1.0, 1.0), frameSize=(-1, 1, -1, 1), pos=(0, 0, 0), text=instructions, text_wordwrap=18, text_scale=0.08, text_pos=instructionsPos)
        self.initialiseoptions(ToonStatueSelectionGUI)
        self.doneEvent = doneEvent
        buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui')
        okImageList = (buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr'))
        cancelImageList = (buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr'))
        self.cancelButton = DirectButton(parent=self, relief=None, image=cancelImageList, pos=(-0.3, 0, -0.35), text=TTLocalizer.PlantingGuiCancel, text_scale=0.06, text_pos=(0, -0.1), command=self.__cancel)
        self.okButton = DirectButton(parent=self, relief=None, image=okImageList, pos=(0.3, 0, -0.35), text=TTLocalizer.PlantingGuiOk, text_scale=0.06, text_pos=(0, -0.1), command=self.__accept)
        buttons.removeNode()
        self.ffList = []
        self.friends = {}
        self.doId2Dna = {}
        self.textRolloverColor = Vec4(1, 1, 0, 1)
        self.textDownColor = Vec4(0.5, 0.9, 1, 1)
        self.textDisabledColor = Vec4(0.4, 0.8, 0.4, 1)
        self.createFriendsList()
        return

    def destroy(self):
        self.doneEvent = None
        self.previewToon.delete()
        self.previewToon = None
        for ff in self.ffList:
            self.friends[ff].destroy()

        self.ffList = []
        self.friends = {}
        self.doId2Dna = {}
        self.scrollList.destroy()
        DirectFrame.destroy(self)
        return

    def __cancel(self):
        messenger.send(self.doneEvent, [0, '', -1])
        messenger.send('wakeup')

    def __accept(self):
        messenger.send(self.doneEvent, [1, '', DistributedToonStatuary.dnaCodeFromToonDNA(self.dnaSelected)])
        messenger.send('wakeup')

    def createFriendsList(self):
        self.__makeFFlist()
        if len(self.ffList) > 0:
            gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui')
            self.scrollList = DirectScrolledList(parent=self, relief=None, incButton_image=(gui.find('**/FndsLst_ScrollUp'),
             gui.find('**/FndsLst_ScrollDN'),
             gui.find('**/FndsLst_ScrollUp_Rllvr'),
             gui.find('**/FndsLst_ScrollUp')), incButton_relief=None, incButton_pos=(0.0, 0.0, -0.316), incButton_image1_color=Vec4(1.0, 0.9, 0.4, 1.0), incButton_image3_color=Vec4(1.0, 1.0, 0.6, 0.5), incButton_scale=(1.0, 1.0, -1.0), decButton_image=(gui.find('**/FndsLst_ScrollUp'),
             gui.find('**/FndsLst_ScrollDN'),
             gui.find('**/FndsLst_ScrollUp_Rllvr'),
             gui.find('**/FndsLst_ScrollUp')), decButton_relief=None, decButton_pos=(0.0, 0.0, 0.117), decButton_image1_color=Vec4(1.0, 1.0, 0.6, 1.0), decButton_image3_color=Vec4(1.0, 1.0, 0.6, 0.6), itemFrame_pos=(-0.17, 0.0, 0.06), itemFrame_relief=DGG.SUNKEN, itemFrame_frameSize=(-0.01,
             0.35,
             -0.35,
             0.04), itemFrame_frameColor=(0.85, 0.95, 1, 1), itemFrame_borderWidth=(0.01, 0.01), numItemsVisible=8, itemFrame_scale=1.0, items=[])
            gui.removeNode()
            self.scrollList.setPos(0.35, 0, 0.125)
            self.scrollList.setScale(1.25)
            clipper = PlaneNode('clipper')
            clipper.setPlane(Plane(Vec3(-1, 0, 0), Point3(0.17, 0, 0)))
            clipNP = self.scrollList.attachNewNode(clipper)
            self.scrollList.setClipPlane(clipNP)
            self.__makeScrollList()
        return

    def checkFamily(self, doId):
        test = 0
        for familyMember in base.cr.avList:
            if familyMember.id == doId:
                test = 1

        return test

    def __makeFFlist(self):
        playerAvatar = (base.localAvatar.doId, base.localAvatar.name, NametagGroup.CCNonPlayer)
        self.ffList.append(playerAvatar)
        self.dnaSelected = base.localAvatar.style
        self.createPreviewToon(self.dnaSelected)
        for familyMember in base.cr.avList:
            if familyMember.id != base.localAvatar.doId:
                newFF = (familyMember.id, familyMember.name, NametagGroup.CCNonPlayer)
                self.ffList.append(newFF)

        for friendPair in base.localAvatar.friendsList:
            friendId, flags = friendPair
            handle = base.cr.identifyFriend(friendId)
            if handle and not self.checkFamily(friendId):
                if hasattr(handle, 'getName'):
                    colorCode = NametagGroup.CCSpeedChat
                    if flags & ToontownGlobals.FriendChat:
                        colorCode = NametagGroup.CCFreeChat
                    newFF = (friendPair[0], handle.getName(), colorCode)
                    self.ffList.append(newFF)
                else:
                    self.notify.warning('Bad Handle for getName in makeFFlist')

    def __makeScrollList(self):
        for ff in self.ffList:
            ffbutton = self.makeFamilyButton(ff[0], ff[1], ff[2])
            if ffbutton:
                self.scrollList.addItem(ffbutton, refresh=0)
                self.friends[ff] = ffbutton

        self.scrollList.refresh()

    def makeFamilyButton(self, familyId, familyName, colorCode):
        fg = NametagGlobals.getNameFg(colorCode, PGButton.SInactive)
        return DirectButton(relief=None, text=familyName, text_scale=0.04, text_align=TextNode.ALeft, text_fg=fg, text1_bg=self.textDownColor, text2_bg=self.textRolloverColor, text3_fg=self.textDisabledColor, textMayChange=0, command=self.__chooseFriend, extraArgs=[familyId, familyName])

    def __chooseFriend(self, friendId, friendName):
        messenger.send('wakeup')
        if self.checkFamily(friendId):
            if friendId == base.localAvatar.doId:
                self.createPreviewToon(base.localAvatar.style)
            elif self.doId2Dna.has_key(friendId):
                self.createPreviewToon(self.doId2Dna[friendId])
            else:
                familyAvatar = DistributedToon.DistributedToon(base.cr)
                familyAvatar.doId = friendId
                familyAvatar.forceAllowDelayDelete()
                base.cr.getAvatarDetails(familyAvatar, self.__handleFamilyAvatar, 'DistributedToon')
        else:
            friend = base.cr.identifyFriend(friendId)
            if friend:
                self.createPreviewToon(friend.style)

    def __handleFamilyAvatar(self, gotData, avatar, dclass):
        self.doId2Dna[avatar.doId] = avatar.style
        self.createPreviewToon(avatar.style)
        avatar.delete()

    def createPreviewToon(self, dna):
        if hasattr(self, 'previewToon'):
            self.previewToon.delete()
        self.dnaSelected = dna
        self.previewToon = Toon.Toon()
        self.previewToon.setDNA(dna)
        self.previewToon.loop('neutral')
        self.previewToon.setH(180)
        self.previewToon.setPos(-0.3, 0, -0.3)
        self.previewToon.setScale(0.13)
        self.previewToon.reparentTo(self)
        self.previewToon.startBlink()
        self.previewToon.startLookAround()
        self.previewToon.getGeomNode().setDepthWrite(1)
        self.previewToon.getGeomNode().setDepthTest(1)
class ToonStatueSelectionGUI(DirectFrame):
    notify = DirectNotifyGlobal.directNotify.newCategory(
        'ToonStatueSelectionGUI')

    def __init__(self, doneEvent, specialBoxActive=False):
        base.tssGUI = self
        instructions = TTLocalizer.GardeningChooseToonStatue
        instructionsPos = (0, 0.4)
        DirectFrame.__init__(self,
                             relief=None,
                             state='normal',
                             geom=DGG.getDefaultDialogGeom(),
                             geom_color=ToontownGlobals.GlobalDialogColor,
                             geom_scale=(1.5, 1.0, 1.0),
                             frameSize=(-1, 1, -1, 1),
                             pos=(0, 0, 0),
                             text=instructions,
                             text_wordwrap=18,
                             text_scale=0.08,
                             text_pos=instructionsPos)
        self.initialiseoptions(ToonStatueSelectionGUI)
        self.doneEvent = doneEvent
        buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui')
        okImageList = (buttons.find('**/ChtBx_OKBtn_UP'),
                       buttons.find('**/ChtBx_OKBtn_DN'),
                       buttons.find('**/ChtBx_OKBtn_Rllvr'))
        cancelImageList = (buttons.find('**/CloseBtn_UP'),
                           buttons.find('**/CloseBtn_DN'),
                           buttons.find('**/CloseBtn_Rllvr'))
        self.cancelButton = DirectButton(parent=self,
                                         relief=None,
                                         image=cancelImageList,
                                         pos=(-0.3, 0, -0.35),
                                         text=TTLocalizer.PlantingGuiCancel,
                                         text_scale=0.06,
                                         text_pos=(0, -0.1),
                                         command=self.__cancel)
        self.okButton = DirectButton(parent=self,
                                     relief=None,
                                     image=okImageList,
                                     pos=(0.3, 0, -0.35),
                                     text=TTLocalizer.PlantingGuiOk,
                                     text_scale=0.06,
                                     text_pos=(0, -0.1),
                                     command=self.__accept)
        buttons.removeNode()
        self.ffList = []
        self.friends = {}
        self.doId2Dna = {}
        self.textRolloverColor = Vec4(1, 1, 0, 1)
        self.textDownColor = Vec4(0.5, 0.9, 1, 1)
        self.textDisabledColor = Vec4(0.4, 0.8, 0.4, 1)
        self.createFriendsList()
        return

    def destroy(self):
        self.doneEvent = None
        self.previewToon.delete()
        self.previewToon = None
        for ff in self.ffList:
            self.friends[ff].destroy()

        self.ffList = []
        self.friends = {}
        self.doId2Dna = {}
        self.scrollList.destroy()
        DirectFrame.destroy(self)
        return

    def __cancel(self):
        messenger.send(self.doneEvent, [0, '', -1])
        messenger.send('wakeup')

    def __accept(self):
        messenger.send(self.doneEvent, [
            1, '',
            DistributedToonStatuary.dnaCodeFromToonDNA(self.dnaSelected)
        ])
        messenger.send('wakeup')

    def createFriendsList(self):
        self.__makeFFlist()
        if len(self.ffList) > 0:
            gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui')
            self.scrollList = DirectScrolledList(
                parent=self,
                relief=None,
                incButton_image=(gui.find('**/FndsLst_ScrollUp'),
                                 gui.find('**/FndsLst_ScrollDN'),
                                 gui.find('**/FndsLst_ScrollUp_Rllvr'),
                                 gui.find('**/FndsLst_ScrollUp')),
                incButton_relief=None,
                incButton_pos=(0.0, 0.0, -0.316),
                incButton_image1_color=Vec4(1.0, 0.9, 0.4, 1.0),
                incButton_image3_color=Vec4(1.0, 1.0, 0.6, 0.5),
                incButton_scale=(1.0, 1.0, -1.0),
                decButton_image=(gui.find('**/FndsLst_ScrollUp'),
                                 gui.find('**/FndsLst_ScrollDN'),
                                 gui.find('**/FndsLst_ScrollUp_Rllvr'),
                                 gui.find('**/FndsLst_ScrollUp')),
                decButton_relief=None,
                decButton_pos=(0.0, 0.0, 0.117),
                decButton_image1_color=Vec4(1.0, 1.0, 0.6, 1.0),
                decButton_image3_color=Vec4(1.0, 1.0, 0.6, 0.6),
                itemFrame_pos=(-0.17, 0.0, 0.06),
                itemFrame_relief=DGG.SUNKEN,
                itemFrame_frameSize=(-0.01, 0.35, -0.35, 0.04),
                itemFrame_frameColor=(0.85, 0.95, 1, 1),
                itemFrame_borderWidth=(0.01, 0.01),
                numItemsVisible=8,
                itemFrame_scale=1.0,
                items=[])
            gui.removeNode()
            self.scrollList.setPos(0.35, 0, 0.125)
            self.scrollList.setScale(1.25)
            clipper = PlaneNode('clipper')
            clipper.setPlane(Plane(Vec3(-1, 0, 0), Point3(0.17, 0, 0)))
            clipNP = self.scrollList.attachNewNode(clipper)
            self.scrollList.setClipPlane(clipNP)
            self.__makeScrollList()
        return

    def checkFamily(self, doId):
        test = 0
        for familyMember in base.cr.avList:
            if familyMember.id == doId:
                test = 1

        return test

    def __makeFFlist(self):
        playerAvatar = (base.localAvatar.doId, base.localAvatar.name,
                        NametagGlobals.CCNonPlayer)
        self.ffList.append(playerAvatar)
        self.dnaSelected = base.localAvatar.style
        self.createPreviewToon(self.dnaSelected)
        for familyMember in base.cr.avList:
            if familyMember.id != base.localAvatar.doId:
                newFF = (familyMember.id, familyMember.name,
                         NametagGlobals.CCNonPlayer)
                self.ffList.append(newFF)

        for friendPair in base.localAvatar.friendsList:
            friendId, flags = friendPair
            handle = base.cr.identifyFriend(friendId)
            if handle and not self.checkFamily(friendId):
                if hasattr(handle, 'getName'):
                    colorCode = NametagGlobals.CCSpeedChat
                    if flags & ToontownGlobals.FriendChat:
                        colorCode = NametagGlobals.CCFreeChat
                    newFF = (friendPair[0], handle.getName(), colorCode)
                    self.ffList.append(newFF)
                else:
                    self.notify.warning('Bad Handle for getName in makeFFlist')

    def __makeScrollList(self):
        for ff in self.ffList:
            ffbutton = self.makeFamilyButton(ff[0], ff[1], ff[2])
            if ffbutton:
                self.scrollList.addItem(ffbutton, refresh=0)
                self.friends[ff] = ffbutton

        self.scrollList.refresh()

    def makeFamilyButton(self, familyId, familyName, colorCode):
        fg = NametagGlobals.NametagColors[colorCode][3][0]
        return DirectButton(relief=None,
                            text=familyName,
                            text_scale=0.04,
                            text_align=TextNode.ALeft,
                            text_fg=fg,
                            text1_bg=self.textDownColor,
                            text2_bg=self.textRolloverColor,
                            text3_fg=self.textDisabledColor,
                            textMayChange=0,
                            command=self.__chooseFriend,
                            extraArgs=[familyId, familyName])

    def __chooseFriend(self, friendId, friendName):
        messenger.send('wakeup')
        if self.checkFamily(friendId):
            if friendId == base.localAvatar.doId:
                self.createPreviewToon(base.localAvatar.style)
            elif friendId in self.doId2Dna:
                self.createPreviewToon(self.doId2Dna[friendId])
            else:
                familyAvatar = DistributedToon.DistributedToon(base.cr)
                familyAvatar.doId = friendId
                familyAvatar.forceAllowDelayDelete()
                base.cr.getAvatarDetails(familyAvatar,
                                         self.__handleFamilyAvatar,
                                         'DistributedToon')
        else:
            friend = base.cr.identifyFriend(friendId)
            if friend:
                self.createPreviewToon(friend.style)

    def __handleFamilyAvatar(self, gotData, avatar, dclass):
        self.doId2Dna[avatar.doId] = avatar.style
        self.createPreviewToon(avatar.style)
        avatar.delete()

    def createPreviewToon(self, dna):
        if hasattr(self, 'previewToon'):
            self.previewToon.delete()
        self.dnaSelected = dna
        self.previewToon = Toon.Toon()
        self.previewToon.setDNA(dna)
        self.previewToon.loop('neutral')
        self.previewToon.setH(180)
        self.previewToon.setPos(-0.3, 0, -0.3)
        self.previewToon.setScale(0.13)
        self.previewToon.reparentTo(self)
        self.previewToon.startBlink()
        self.previewToon.startLookAround()
        self.previewToon.getGeomNode().setDepthWrite(1)
        self.previewToon.getGeomNode().setDepthTest(1)
class CatalogScreen(DirectFrame):
    notify = DirectNotifyGlobal.directNotify.newCategory('CatalogScreen')

    def __init__(self, parent = aspect2d, **kw):
        self.gifting = -1
        guiItems = loader.loadModel('phase_5.5/models/gui/catalog_gui')
        background = guiItems.find('**/catalog_background')
        background.setBin("background", 10)
        guiButton = loader.loadModel('phase_3/models/gui/quit_button')
        guiBack = loader.loadModel('phase_5.5/models/gui/package_delivery_panel')
        optiondefs = (('scale', 0.667, None),
         ('pos', (0, 1, 0.025), None),
         ('phone', None, None),
         ('doneEvent', None, None),
         ('image', background, None),
         ('relief', None, None))
        self.defineoptions(kw, optiondefs)
        DirectFrame.__init__(self, parent)
        self.friend = None
        self.friendAvId = None
        self.friendName = None
        self.friendList = []
        self.friends = []
        self.load(guiItems, guiButton, guiBack)
        self.initialiseoptions(CatalogScreen)
        self.enableBackorderCatalogButton()
        self.setMaxPageIndex(self.numNewPages)
        self.setPageIndex(-1)
        self.showPageItems()
        self.hide()
        self.clarabelleChatNP = None
        self.clarabelleChatBalloon = None
        self.createdGiftGui = None
        self.viewing = None

    def show(self):
        self.accept('CatalogItemPurchaseRequest', self.__handlePurchaseRequest)
        self.accept('CatalogItemGiftPurchaseRequest', self.__handleGiftPurchaseRequest)
        self.accept(localAvatar.uniqueName('moneyChange'), self.__moneyChange)
        self.accept(localAvatar.uniqueName('bankMoneyChange'), self.__bankMoneyChange)
        self.accept(localAvatar.uniqueName('emblemsChange'), self.__emblemChange)
        deliveryText = 'setDeliverySchedule-%s' % base.localAvatar.doId
        self.accept(deliveryText, self.remoteUpdate)
        base.setBackgroundColor(Vec4(0.529, 0.290, 0.286, 1))
        render.hide()
        DirectFrame.show(self)

        def clarabelleGreeting(task):
            self.setClarabelleChat(TTLocalizer.CatalogGreeting, type='greeting')

        def clarabelleHelpText1(task):
            self.setClarabelleChat(TTLocalizer.CatalogHelpText1)

        taskMgr.doMethodLater(1.0, clarabelleGreeting, 'clarabelleGreeting')
        taskMgr.doMethodLater(12.0, clarabelleHelpText1, 'clarabelleHelpText1')

    def hide(self):
        self.ignore('CatalogItemPurchaseRequest')
        self.ignore('CatalogItemGiftPurchaseRequest')
        self.ignore(localAvatar.uniqueName('moneyChange'))
        self.ignore(localAvatar.uniqueName('bankMoneyChange'))
        self.ignore(localAvatar.uniqueName('emblemsChange'))
        deliveryText = 'setDeliverySchedule-%s' % base.localAvatar.doId
        self.ignore(deliveryText)
        base.setBackgroundColor(ToontownGlobals.DefaultBackgroundColor)
        render.show()
        DirectFrame.hide(self)

    def setNumNewPages(self, numNewPages):
        self.numNewPages = numNewPages

    def setNumBackPages(self, numBackPages):
        self.numBackPages = numBackPages

    def setNumSpecialPages(self, numSpecialPages):
        self.numSpecialPages = numSpecialPages

    def setNumEmblemPages(self, numEmblemPages):
        self.numEmblemPages = numEmblemPages

    def setPageIndex(self, index):
        self.pageIndex = index

    def setMaxPageIndex(self, numPages):
        self.maxPageIndex = max(numPages - 1, -1)

    def enableBackorderCatalogButton(self):
        self.backCatalogButton['state'] = DGG.NORMAL
        self.newCatalogButton['state'] = DGG.DISABLED
        self.specialCatalogButton['state'] = DGG.DISABLED
        self.emblemCatalogButton['state'] = DGG.DISABLED

    def enableNewCatalogButton(self):
        self.backCatalogButton['state'] = DGG.DISABLED
        self.newCatalogButton['state'] = DGG.NORMAL
        self.specialCatalogButton['state'] = DGG.DISABLED
        self.emblemCatalogButton['state'] = DGG.DISABLED

    def enableSpecialCatalogButton(self):
        self.backCatalogButton['state'] = DGG.DISABLED
        self.newCatalogButton['state'] = DGG.DISABLED
        self.specialCatalogButton['state'] = DGG.NORMAL
        self.emblemCatalogButton['state'] = DGG.DISABLED

    def enableEmblemCatalogButton(self):
        self.backCatalogButton['state'] = DGG.DISABLED
        self.newCatalogButton['state'] = DGG.DISABLED
        self.specialCatalogButton['state'] = DGG.DISABLED
        self.emblemCatalogButton['state'] = DGG.NORMAL

    def modeBackorderCatalog(self):
        self.backCatalogButton['state'] = DGG.DISABLED
        self.newCatalogButton['state'] = DGG.NORMAL
        self.specialCatalogButton['state'] = DGG.NORMAL
        self.emblemCatalogButton['state'] = DGG.NORMAL

    def modeNewCatalog(self):
        self.backCatalogButton['state'] = DGG.NORMAL
        self.newCatalogButton['state'] = DGG.DISABLED
        self.specialCatalogButton['state'] = DGG.NORMAL
        self.emblemCatalogButton['state'] = DGG.NORMAL

    def modeSpecialCatalog(self):
        self.backCatalogButton['state'] = DGG.NORMAL
        self.newCatalogButton['state'] = DGG.NORMAL
        self.specialCatalogButton['state'] = DGG.DISABLED
        self.emblemCatalogButton['state'] = DGG.NORMAL

    def modeEmblemCatalog(self):
        self.backCatalogButton['state'] = DGG.NORMAL
        self.newCatalogButton['state'] = DGG.NORMAL
        self.specialCatalogButton['state'] = DGG.NORMAL
        self.emblemCatalogButton['state'] = DGG.DISABLED

    def showNewItems(self, index = None):
        if config.GetBool('want-qa-regression', 0):
            self.notify.info('QA-REGRESSION: CATALOG: New item')
        taskMgr.remove('clarabelleHelpText1')
        messenger.send('wakeup')
        self.viewing = 'New'
        self.modeNewCatalog()
        self.setMaxPageIndex(self.numNewPages)
        if self.numNewPages == 0:
            self.setPageIndex(-1)
        elif index is not None:
            self.setPageIndex(index)
        else:
            self.setPageIndex(0)
        self.showPageItems()
        return

    def showBackorderItems(self, index = None):
        if config.GetBool('want-qa-regression', 0):
            self.notify.info('QA-REGRESSION: CATALOG: Backorder item')
        taskMgr.remove('clarabelleHelpText1')
        messenger.send('wakeup')
        self.viewing = 'Backorder'
        self.modeBackorderCatalog()
        self.setMaxPageIndex(self.numBackPages)
        if self.numBackPages == 0:
            self.setPageIndex(-1)
        elif index is not None:
            self.setPageIndex(index)
        else:
            self.setPageIndex(0)
        self.showPageItems()
        return

    def showSpecialItems(self, index = None):
        if config.GetBool('want-qa-regression', 0):
            self.notify.info('QA-REGRESSION: CATALOG: Special item')
        taskMgr.remove('clarabelleHelpText1')
        messenger.send('wakeup')
        self.viewing = 'Special'
        self.modeSpecialCatalog()
        self.setMaxPageIndex(self.numSpecialPages)
        if self.numSpecialPages == 0:
            self.setPageIndex(-1)
        elif index is not None:
            self.setPageIndex(index)
        else:
            self.setPageIndex(0)
        self.showPageItems()
        return

    def showEmblemItems(self, index = None):
        if config.GetBool('want-qa-regression', 0):
            self.notify.info('QA-REGRESSION: CATALOG: Emblem item')
        taskMgr.remove('clarabelleHelpText1')
        messenger.send('wakeup')
        self.viewing = 'Emblem'
        self.modeEmblemCatalog()
        self.setMaxPageIndex(self.numEmblemPages)
        if self.numEmblemPages == 0:
            self.setPageIndex(-1)
        elif index is not None:
            self.setPageIndex(index)
        else:
            self.setPageIndex(0)
        self.showPageItems()
        return

    def showNextPage(self):
        taskMgr.remove('clarabelleHelpText1')
        messenger.send('wakeup')
        self.pageIndex = self.pageIndex + 1
        if self.viewing == None:
            self.modeNewCatalog()
            self.viewing == 'New'
        if self.viewing == 'New' and self.pageIndex > self.maxPageIndex and self.numBackPages > 0:
            self.showBackorderItems()
        if self.viewing == 'New' and self.pageIndex > self.maxPageIndex and self.numSpecialPages > 0:
            self.showSpecialItems()
        elif self.viewing == 'Backorder' and self.pageIndex > self.maxPageIndex and self.numSpecialPages > 0:
            self.showSpecialItems()
        elif self.viewing == 'Special' and self.pageIndex > self.maxPageIndex and self.numEmblemPages > 0:
            self.showEmblemItems()
        else:
            self.pageIndex = min(self.pageIndex, self.maxPageIndex)
            self.showPageItems()
        return

    def showBackPage(self):
        taskMgr.remove('clarabelleHelpText1')
        messenger.send('wakeup')
        self.pageIndex = self.pageIndex - 1
        if self.viewing == 'Backorder' and self.pageIndex < 0 and self.numNewPages > 0:
            self.showNewItems(self.numNewPages - 1)
        elif self.viewing == 'Special' and self.pageIndex < 0 and self.numBackPages > 0:
            self.showBackorderItems(self.numBackPages - 1)
        elif self.viewing == 'Emblem' and self.pageIndex < 0 and self.numSpecialPages > 0:
            self.showSpecialItems(self.numSpecialPages - 1)
        else:
            self.pageIndex = max(self.pageIndex, -1)
            self.showPageItems()

    def showPageItems(self):
        self.hidePages()
        if self.viewing == None:
            self.viewing = 'New'
        if self.pageIndex < 0:
            self.closeCover()
        else:
            if self.pageIndex == 0:
                self.openCover()
            if self.viewing == 'New':
                page = self.pageList[self.pageIndex]
                newOrBackOrSpecial = 0
            elif self.viewing == 'Backorder':
                page = self.backPageList[self.pageIndex]
                newOrBackOrSpecial = 1
            elif self.viewing == 'Special':
                page = self.specialPageList[self.pageIndex]
                newOrBackOrSpecial = 2
            elif self.viewing == 'Emblem':
                page = self.emblemPageList[self.pageIndex]
                newOrBackOrSpecial = 3
            page.show()
            for panel in self.panelDict[page.get_key()]:
                panel.load()
                if panel.ival:
                    panel.ival.loop()
                self.visiblePanels.append(panel)

            pIndex = 0
            randGen = random.Random()
            randGen.seed(base.localAvatar.catalogScheduleCurrentWeek + (self.pageIndex << 8) + (newOrBackOrSpecial << 16))
            for i in xrange(NUM_CATALOG_ROWS):
                for j in xrange(NUM_CATALOG_COLS):
                    if pIndex < len(self.visiblePanels):
                        type = self.visiblePanels[pIndex]['item'].getTypeCode()
                        self.squares[i][j].setColor(CatalogPanelColors.values()[randGen.randint(0, len(CatalogPanelColors) - 1)])
                        cs = 0.7 + 0.3 * randGen.random()
                        self.squares[i][j].setColorScale(0.7 + 0.3 * randGen.random(), 0.7 + 0.3 * randGen.random(), 0.7 + 0.3 * randGen.random(), 1)
                    else:
                        self.squares[i][j].setColor(CatalogPanelColors[CatalogItemTypes.CHAT_ITEM])
                        self.squares[i][j].clearColorScale()
                    pIndex += 1

            if self.viewing == 'New':
                text = TTLocalizer.CatalogNew
            elif self.viewing == 'Special':
                text = TTLocalizer.CatalogSpecial
            elif self.viewing == 'Backorder':
                text = TTLocalizer.CatalogBackorder
            elif self.viewing == 'Emblem':
                text = TTLocalizer.CatalogEmblem
            self.pageLabel['text'] = text + ' - %d' % (self.pageIndex + 1)
            if self.pageIndex < self.maxPageIndex:
                self.nextPageButton.show()
            elif self.viewing == 'New' and self.numBackPages == 0 and self.numSpecialPages == 0:
                self.nextPageButton.hide()
            elif self.viewing == 'Backorder' and self.numSpecialPages == 0:
                self.nextPageButton.hide()
            elif self.viewing == 'Special' and self.numEmblemPages == 0:
                self.nextPageButton.hide()
            elif self.viewing == 'Special' and self.numEmblemPages > 0:
                self.nextPageButton.show()
            elif self.viewing == 'Emblem':
                self.nextPageButton.hide()
            self.adjustForSound()
            self.update()
        return

    def adjustForSound(self):
        numEmoteItems = 0
        emotePanels = []
        for visIndex in xrange(len(self.visiblePanels)):
            panel = self.visiblePanels[visIndex]
            item = panel['item']
            catalogType = item.getTypeCode()
            if catalogType == CatalogItemTypes.EMOTE_ITEM:
                numEmoteItems += 1
                emotePanels.append(panel)
            else:
                panel.soundOnButton.hide()
                panel.soundOffButton.hide()

        if numEmoteItems == 1:
            emotePanels[0].handleSoundOnButton()
        elif numEmoteItems > 1:
            for panel in emotePanels:
                panel.handleSoundOffButton()

    def hidePages(self):
        for page in self.pageList:
            page.hide()

        for page in self.backPageList:
            page.hide()

        for page in self.specialPageList:
            page.hide()

        for page in self.emblemPageList:
            page.hide()

        for panel in self.visiblePanels:
            if panel.ival:
                panel.ival.finish()

        self.visiblePanels = []

    def openCover(self):
        self.cover.hide()
        self.hideDummyTabs()
        self.backPageButton.show()
        self.pageLabel.show()

    def closeCover(self):
        self.cover.show()
        self.showDummyTabs()
        self.nextPageButton.show()
        self.backPageButton.hide()
        self.pageLabel.hide()
        self.hidePages()

    def showDummyTabs(self):
        if self.numNewPages > 0:
            self.newCatalogButton2.show()
        if self.numBackPages > 0:
            self.backCatalogButton2.show()
        if self.numSpecialPages > 0:
            self.specialCatalogButton2.show()
        if self.numEmblemPages > 0:
            self.emblemCatalogButton2.show()
        self.newCatalogButton.hide()
        self.backCatalogButton.hide()
        self.specialCatalogButton.hide()
        self.emblemCatalogButton.hide()

    def hideDummyTabs(self):
        self.newCatalogButton2.hide()
        self.backCatalogButton2.hide()
        self.specialCatalogButton2.hide()
        self.emblemCatalogButton2.hide()
        if self.numNewPages > 0:
            self.newCatalogButton.show()
        if self.numBackPages > 0:
            self.backCatalogButton.show()
        if self.numSpecialPages > 0:
            self.specialCatalogButton.show()
        if self.numEmblemPages > 0:
            self.emblemCatalogButton.show()

    def packPages(self, panelList, pageList, prefix):
        i = 0
        j = 0
        numPages = 0
        pageName = prefix + '_page%d' % numPages
        for item in panelList:
            if i == 0 and j == 0:
                numPages += 1
                pageName = prefix + '_page%d' % numPages
                page = self.base.attachNewNode(pageName)
                pageList.append(page)
            item.reparentTo(page)
            item.setPos(CatalogPanelCenters[i][j])
            itemList = self.panelDict.get(page.get_key(), [])
            itemList.append(item)
            self.panelDict[page.get_key()] = itemList
            j += 1
            if j == NUM_CATALOG_COLS:
                j = 0
                i += 1
            if i == NUM_CATALOG_ROWS:
                i = 0

        return numPages

    def load(self, guiItems, guiButton, guiBack):
        self.pageIndex = -1
        self.maxPageIndex = 0
        self.numNewPages = 0
        self.numBackPages = 5
        self.numSpecialPages = 0
        self.viewing = 'New'
        self.panelList = []
        self.backPanelList = []
        self.pageList = []
        self.backPageList = []
        self.specialPanelList = []
        self.specialPageList = []
        self.emblemPanelList = []
        self.emblemPageList = []
        self.panelDict = {}
        self.visiblePanels = []
        self.responseDialog = None
        catalogBase = guiItems.find('**/catalog_base')
        self.base = DirectLabel(self, relief=None, image=catalogBase)
        newDown = guiItems.find('**/new1')
        newUp = guiItems.find('**/new2')
        backDown = guiItems.find('**/previous2')
        backUp = guiItems.find('**/previous1')
        giftToggleUp = guiItems.find('**/giftButtonUp')
        giftToggleDown = guiItems.find('**/giftButtonDown')
        giftFriends = guiItems.find('**/gift_names')
        oldLift = 0.4
        lift = 0.4
        liftDiff = lift - oldLift
        lift2 = 0.05
        smash = 0.75
        priceScale = 0.15
        emblemIcon = loader.loadModel('phase_3.5/models/gui/tt_m_gui_gen_emblemIcons')
        silverModel = emblemIcon.find('**/tt_t_gui_gen_emblemSilver')
        goldModel = emblemIcon.find('**/tt_t_gui_gen_emblemGold')
        self.silverLabel = DirectLabel(parent=self, relief=None, pos=(1.05, 0, -0.6), scale=priceScale, image=silverModel, image_pos=(-0.4, 0, 0.4), text=str(localAvatar.emblems[ToontownGlobals.EmblemTypes.Silver]), text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ALeft)
        base.silverLabel = self.silverLabel
        self.goldLabel = DirectLabel(parent=self, relief=None, pos=(1.05, 0, -0.8), scale=priceScale, image=goldModel, image_pos=(-0.4, 0, 0.4), text=str(localAvatar.emblems[ToontownGlobals.EmblemTypes.Gold]), text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ALeft)
        base.goldLabel = self.goldLabel
        if not base.cr.wantEmblems:
            self.hideEmblems()
        self.newCatalogButton = DirectButton(self.base, relief=None, pos=(0, 0, 0.17), frameSize=(-0.2,
         0.25,
         0.45,
         1.2), image=[newDown,
         newDown,
         newDown,
         newUp], image_scale=(1.0, 1.0, smash), image_pos=(0.0, 0.0, lift), pressEffect=0, command=self.showNewItems, text=TTLocalizer.CatalogNew, text_font=ToontownGlobals.getSignFont(), text_pos=(-0.4 - lift, 0.13), text3_pos=(-0.4 - lift, 0.1), text_scale=0.08, text_fg=(0.353, 0.627, 0.627, 1.0), text2_fg=(0.353, 0.427, 0.427, 1.0))
        self.newCatalogButton.hide()
        self.newCatalogButton2 = DirectButton(self.base, relief=None, pos=(0, 0, 0.17), frameSize=(-0.2,
         0.25,
         0.45,
         1.2), image=newDown, image_scale=(1.0, 1.0, smash), image_pos=(0.0, 0.0, lift), pressEffect=0, command=self.showNewItems, text=TTLocalizer.CatalogNew, text_font=ToontownGlobals.getSignFont(), text_pos=(-0.4 - lift, 0.13), text_scale=0.08, text_fg=(0.353, 0.627, 0.627, 1.0), text2_fg=(0.353, 0.427, 0.427, 1.0))
        self.newCatalogButton2.hide()
        self.backCatalogButton = DirectButton(self.base, relief=None, pos=(0, 0, 0.269), frameSize=(-0.2,
         0.25,
         -0.2,
         0.4), image=[backDown,
         backDown,
         backDown,
         backUp], image_scale=(1.0, 1.0, smash), image_pos=(0.0, 0.0, lift), pressEffect=0, command=self.showBackorderItems, text=TTLocalizer.CatalogBackorder, text_font=ToontownGlobals.getSignFont(), text_pos=(0.25 - lift, 0.132), text3_pos=(0.25 - lift, 0.112), text_scale=TTLocalizer.CSbackCatalogButton, text_fg=(0.392, 0.549, 0.627, 1.0), text2_fg=(0.392, 0.349, 0.427, 1.0))
        self.backCatalogButton.hide()
        self.backCatalogButton2 = DirectButton(self.base, relief=None, pos=(0, 0, 0.269), frameSize=(-0.2,
         0.25,
         -0.2,
         0.4), image_scale=(1.0, 1.0, smash), image_pos=(0.0, 0.0, lift), image=backDown, pressEffect=0, command=self.showBackorderItems, text=TTLocalizer.CatalogBackorder, text_font=ToontownGlobals.getSignFont(), text_pos=(0.25 - lift, 0.132), text_scale=TTLocalizer.CSbackCatalogButton, text_fg=(0.392, 0.549, 0.627, 1.0), text2_fg=(0.392, 0.349, 0.427, 1.0))
        self.backCatalogButton2.hide()
        self.specialCatalogButton = DirectButton(self.base, relief=None, pos=(0, 0, 0.469), frameSize=(-0.2,
         0.25,
         -0.85,
         -0.3), image=[newDown,
         newDown,
         newDown,
         newUp], image_scale=(1.0, 1.0, smash), image_pos=(0.0, 0.0, -1.4 + lift), pressEffect=0, command=self.showSpecialItems, text=TTLocalizer.CatalogSpecial, text_font=ToontownGlobals.getSignFont(), text_pos=(1.0 - lift, 0.132), text3_pos=(1.0 - lift, 0.112), text_scale=0.065, text_fg=(0.353, 0.627, 0.627, 1.0), text2_fg=(0.353, 0.427, 0.427, 1.0))
        self.specialCatalogButton.hide()
        self.specialCatalogButton2 = DirectButton(self.base, relief=None, pos=(0, 0, 0.469), frameSize=(-0.2,
         0.25,
         -0.85,
         -0.3), image_scale=(1.0, 1.0, smash), image_pos=(0.0, 0.0, -1.4 + lift), image=newDown, pressEffect=0, command=self.showSpecialItems, text=TTLocalizer.CatalogSpecial, text_font=ToontownGlobals.getSignFont(), text_pos=(1.0 - lift, 0.132), text_scale=0.065, text_fg=(0.353, 0.627, 0.627, 1.0), text2_fg=(0.353, 0.427, 0.427, 1.0))
        self.specialCatalogButton2.hide()
        self.emblemCatalogButton = DirectButton(self.base, relief=None, pos=(0, 0, 1.05), frameSize=(-0.2,
         0.25,
         -2.0,
         -1.45), image=[backDown,
         backDown,
         backDown,
         backUp], image_scale=(1.0, 1.0, smash), image_pos=(0.0, 0.0, -1.9 + lift), pressEffect=0, command=self.showEmblemItems, text=TTLocalizer.CatalogEmblem, text_font=ToontownGlobals.getSignFont(), text_pos=(1.75, 0.132), text3_pos=(1.75, 0.112), text_scale=0.065, text_fg=(0.353, 0.627, 0.627, 1.0), text2_fg=(0.353, 0.427, 0.427, 1.0))
        self.emblemCatalogButton.hide()
        self.emblemCatalogButton2 = DirectButton(self.base, relief=None, pos=(0, 0, 1.05), frameSize=(-0.2,
         0.25,
         -2.0,
         -1.45), image_scale=(1.0, 1.0, smash), image_pos=(0.0, 0.0, -1.9 + lift), image=backDown, pressEffect=0, command=self.showEmblemItems, text=TTLocalizer.CatalogEmblem, text_font=ToontownGlobals.getSignFont(), text_pos=(1.75, 0.132), text_scale=0.065, text_fg=(0.353, 0.627, 0.627, 1.0), text2_fg=(0.353, 0.427, 0.427, 1.0))
        self.emblemCatalogButton2.hide()
        self.__makeFriendList()
        if len(self.friendList) > 0:
            if config.GetBool('want-gifting', True):
                self.giftToggle = DirectButton(self.base, relief=None, pressEffect=0, image=(giftToggleUp, giftToggleDown, giftToggleUp), image_scale=(1.0, 1, 0.7), command=self.__giftToggle, text=TTLocalizer.CatalogGiftToggleOff, text_font=ToontownGlobals.getSignFont(), text_pos=TTLocalizer.CSgiftTogglePos, text_scale=TTLocalizer.CSgiftToggle, text_fg=(0.353, 0.627, 0.627, 1.0), text3_fg=(0.15, 0.3, 0.3, 1.0), text2_fg=(0.353, 0.427, 0.427, 1.0), image_color=Vec4(1.0, 1.0, 0.2, 1.0), image1_color=Vec4(0.9, 0.85, 0.2, 1.0), image2_color=Vec4(0.9, 0.85, 0.2, 1.0), image3_color=Vec4(0.5, 0.45, 0.2, 1.0))
                self.giftToggle.setPos(0.0, 0, -0.035)
            self.giftLabel = DirectLabel(self.base, relief=None, image=giftFriends, image_scale=(1.15, 1, 1.14), text=' ', text_font=ToontownGlobals.getSignFont(), text_pos=(1.2, -0.97), text_scale=0.07, text_fg=(0.392, 0.549, 0.627, 1.0), sortOrder=100, textMayChange=1)
            self.giftLabel.setPos(-0.15, 0, 0.08)
            self.giftLabel.hide()
            self.friendLabel = DirectLabel(self.base, relief=None, text=TTLocalizer.CatalogGiftChoose, text_font=ToontownGlobals.getSignFont(), text_pos=(-0.25, 0.132), text_scale=0.068, text_align=TextNode.ALeft, text_fg=(0.992, 0.949, 0.327, 1.0), sortOrder=100, textMayChange=1)
            self.friendLabel.setPos(0.5, 0, -0.42)
            self.friendLabel.hide()
            gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui')
            self.scrollList = DirectScrolledList(parent=self, relief=None, incButton_image=(gui.find('**/FndsLst_ScrollUp'),
             gui.find('**/FndsLst_ScrollDN'),
             gui.find('**/FndsLst_ScrollUp_Rllvr'),
             gui.find('**/FndsLst_ScrollUp')), incButton_relief=None, incButton_pos=(0.0, 0.0, -0.316), incButton_image1_color=Vec4(1.0, 0.9, 0.4, 1.0), incButton_image3_color=Vec4(1.0, 1.0, 0.6, 0.5), incButton_scale=(1.0, 1.0, -1.0), decButton_image=(gui.find('**/FndsLst_ScrollUp'),
             gui.find('**/FndsLst_ScrollDN'),
             gui.find('**/FndsLst_ScrollUp_Rllvr'),
             gui.find('**/FndsLst_ScrollUp')), decButton_relief=None, decButton_pos=(0.0, 0.0, 0.117), decButton_image1_color=Vec4(1.0, 1.0, 0.6, 1.0), decButton_image3_color=Vec4(1.0, 1.0, 0.6, 0.6), itemFrame_pos=(-0.17, 0.0, 0.06), itemFrame_relief=None, numItemsVisible=8, items=[])
            self.scrollList.setPos(1.2, 0, -0.58)
            self.scrollList.setScale(1.5)
            self.scrollList.hide()
            clipper = PlaneNode('clipper')
            clipper.setPlane(Plane(Vec3(-1, 0, 0), Point3(0.17, 0, 0)))
            clipNP = self.scrollList.attachNewNode(clipper)
            self.scrollList.setClipPlane(clipNP)
            self.__makeScrollList()
            self.createdGiftGui = 1
        for i in xrange(4):
            self.newCatalogButton.component('text%d' % i).setR(90)
            self.newCatalogButton2.component('text%d' % i).setR(90)
            self.backCatalogButton.component('text%d' % i).setR(90)
            self.backCatalogButton2.component('text%d' % i).setR(90)
            self.specialCatalogButton.component('text%d' % i).setR(90)
            self.specialCatalogButton2.component('text%d' % i).setR(90)
            self.emblemCatalogButton.component('text%d' % i).setR(90)
            self.emblemCatalogButton2.component('text%d' % i).setR(90)

        self.squares = [[],
         [],
         [],
         []]
        for i in xrange(NUM_CATALOG_ROWS):
            for j in xrange(NUM_CATALOG_COLS):
                square = guiItems.find('**/square%d%db' % (i + 1, j + 1))
                label = DirectLabel(self.base, image=square, relief=None, state='normal')
                self.squares[i].append(label)

        def priceSort(a, b, type):
            priceA = a.getPrice(type)
            priceB = b.getPrice(type)
            return priceB - priceA

        itemList = base.localAvatar.monthlyCatalog + base.localAvatar.weeklyCatalog
        itemList.sort(lambda a, b: priceSort(a, b, CatalogItem.CatalogTypeWeekly))
        itemList.reverse()
        allClosetItems = CatalogFurnitureItem.getAllClosets()
        allBankItems = CatalogFurnitureItem.getAllBanks()
        isMaxClosetOfferred = False
        isMaxBankOffered = False
        for item in itemList:
            if item in allClosetItems and item.furnitureType in CatalogFurnitureItem.MaxClosetIds:
                isMaxClosetOfferred = True
                break

        for item in itemList:
            if item in allBankItems and item.furnitureType == CatalogFurnitureItem.MaxBankId:
                isMaxBankOffered = True
                break

        for item in itemList:
            if isinstance(item, CatalogInvalidItem.CatalogInvalidItem):
                self.notify.warning('skipping catalog invalid item %s' % item)
                continue
            if isMaxClosetOfferred and item in allClosetItems and item.furnitureType not in CatalogFurnitureItem.MaxClosetIds:
                continue
            if isMaxBankOffered and item in allBankItems and item.furnitureType != CatalogFurnitureItem.MaxBankId:
                continue
            if item.getIsSpecial():
                self.specialPanelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeSpecial, parentCatalogScreen=self))
            elif item.getEmblemPrices():
                self.emblemPanelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeWeekly, parentCatalogScreen=self))
            else:
                self.panelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeWeekly, parentCatalogScreen=self))

        itemList = base.localAvatar.backCatalog
        itemList.sort(lambda a, b: priceSort(a, b, CatalogItem.CatalogTypeBackorder))
        itemList.reverse()
        for item in itemList:
            if isinstance(item, CatalogInvalidItem.CatalogInvalidItem):
                self.notify.warning('skipping catalog invalid item %s' % item)
                continue
            if isMaxClosetOfferred and item in allClosetItems and item.furnitureType not in CatalogFurnitureItem.MaxClosetIds:
                continue
            if isMaxBankOffered and item in allBankItems and item.furnitureType != CatalogFurnitureItem.MaxBankId:
                continue
            if item.getIsSpecial():
                self.specialPanelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeSpecial, parentCatalogScreen=self))
            elif item.getEmblemPrices():
                self.emblemPanelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeBackorder, parentCatalogScreen=self))
            else:
                self.backPanelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeBackorder, parentCatalogScreen=self))

        numPages = self.packPages(self.panelList, self.pageList, 'new')
        self.setNumNewPages(numPages)
        numPages = self.packPages(self.backPanelList, self.backPageList, 'back')
        self.setNumBackPages(numPages)
        numPages = self.packPages(self.specialPanelList, self.specialPageList, 'special')
        self.setNumSpecialPages(numPages)
        numPages = self.packPages(self.emblemPanelList, self.emblemPageList, 'emblem')
        self.setNumEmblemPages(numPages)
        currentWeek = base.localAvatar.catalogScheduleCurrentWeek - 1
        if currentWeek < 57:
            seriesNumber = currentWeek / ToontownGlobals.CatalogNumWeeksPerSeries + 1
            weekNumber = currentWeek % ToontownGlobals.CatalogNumWeeksPerSeries + 1
        elif currentWeek < 65:
            seriesNumber = 6
            weekNumber = currentWeek - 56
        else:
            seriesNumber = currentWeek / ToontownGlobals.CatalogNumWeeksPerSeries + 2
            weekNumber = currentWeek % ToontownGlobals.CatalogNumWeeksPerSeries + 1
        geom = NodePath('cover')
        cover = guiItems.find('**/cover')
        maxSeries = ToontownGlobals.CatalogNumWeeks / ToontownGlobals.CatalogNumWeeksPerSeries + 1
        coverSeries = (seriesNumber - 1) % maxSeries + 1
        coverPicture = cover.find('**/cover_picture%s' % coverSeries)
        if not coverPicture.isEmpty():
            coverPicture.reparentTo(geom)
        bottomSquare = cover.find('**/cover_bottom')
        topSquare = guiItems.find('**/square12b2')
        if seriesNumber == 1:
            topSquare.setColor(0.651, 0.404, 0.322, 1.0)
            bottomSquare.setColor(0.655, 0.522, 0.263, 1.0)
        else:
            topSquare.setColor(0.651, 0.404, 0.322, 1.0)
            bottomSquare.setColor(0.655, 0.522, 0.263, 1.0)
        bottomSquare.reparentTo(geom)
        topSquare.reparentTo(geom)
        cover.find('**/clarabelle_text').reparentTo(geom)
        cover.find('**/blue_circle').reparentTo(geom)
        cover.find('**/clarabelle').reparentTo(geom)
        cover.find('**/circle_green').reparentTo(geom)
        self.cover = DirectLabel(self.base, relief=None, geom=geom)
        self.catalogNumber = DirectLabel(self.cover, relief=None, scale=0.2, pos=(-0.22, 0, -0.33), text='#%d' % weekNumber, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getInterfaceFont())
        self.catalogSeries = DirectLabel(self.cover, relief=None, scale=(0.22, 1, 0.18), pos=(-0.76, 0, -0.9), text=TTLocalizer.CatalogSeriesLabel % seriesNumber, text_fg=(0.9, 0.9, 0.4, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getInterfaceFont())
        self.catalogSeries.setShxz(0.4)
        self.rings = DirectLabel(self.base, relief=None, geom=guiItems.find('**/rings'))
        self.clarabelleFrame = DirectLabel(self, relief=None, image=guiItems.find('**/clarabelle_frame'))
        hangupGui = guiItems.find('**/hangup')
        hangupRolloverGui = guiItems.find('**/hangup_rollover')
        self.hangup = DirectButton(self, relief=None, pos=(1.78, 0, -1.3), image=[hangupGui,
         hangupRolloverGui,
         hangupGui], text=['', TTLocalizer.CatalogHangUp, TTLocalizer.CatalogHangUp], text_fg=Vec4(1), text_scale=0.07, text_pos=(0.0, 0.14), command=self.hangUp)
        self.beanBank = DirectLabel(self, relief=None, image=guiItems.find('**/bean_bank'), text=str(base.localAvatar.getMoney() + base.localAvatar.getBankMoney()), text_align=TextNode.ARight, text_scale=0.11, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_pos=(0.75, -0.81), text_font=ToontownGlobals.getSignFont())
        nextUp = guiItems.find('**/arrow_up')
        nextRollover = guiItems.find('**/arrow_Rollover')
        nextDown = guiItems.find('**/arrow_Down')
        prevUp = guiItems.find('**/arrowUp')
        prevDown = guiItems.find('**/arrowDown1')
        prevRollover = guiItems.find('**/arrowRollover')
        self.nextPageButton = DirectButton(self, relief=None, pos=(-0.1, 0, -0.9), image=[nextUp,
         nextDown,
         nextRollover,
         nextUp], image_color=(0.9, 0.9, 0.9, 1), image2_color=(1, 1, 1, 1), command=self.showNextPage)
        self.backPageButton = DirectButton(self, relief=None, pos=(-0.1, 0, -0.9), image=[prevUp,
         prevDown,
         prevRollover,
         prevUp], image_color=(0.9, 0.9, 0.9, 1), image2_color=(1, 1, 1, 1), command=self.showBackPage)
        self.backPageButton.hide()
        self.pageLabel = DirectLabel(self.base, relief=None, pos=(-1.33, 0, -0.9), scale=0.06, text=TTLocalizer.CatalogPagePrefix, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ALeft)
        self.loadClarabelle()
        return

    def loadClarabelle(self):
        self.cRender = NodePath('cRender')
        self.cCamera = self.cRender.attachNewNode('cCamera')
        self.cCamNode = Camera('cCam')
        self.cLens = PerspectiveLens()
        self.cLens.setFov(40, 40)
        self.cLens.setNear(0.1)
        self.cLens.setFar(100.0)
        self.cCamNode.setLens(self.cLens)
        self.cCamNode.setScene(self.cRender)
        self.cCam = self.cCamera.attachNewNode(self.cCamNode)
        self.cDr = base.win.makeDisplayRegion(0.56, 0.81, 0.52, 0.85)
        self.cDr.setSort(1)
        self.cDr.setClearDepthActive(1)
        self.cDr.setClearColorActive(1)
        self.cDr.setClearColor(Vec4(0.3, 0.3, 0.3, 1))
        self.cDr.setCamera(self.cCam)
        self.clarabelle = Actor.Actor('phase_5.5/models/char/Clarabelle-zero', {'listen': 'phase_5.5/models/char/Clarabelle-listens'})
        self.clarabelle.loop('listen')
        self.clarabelle.find('**/eyes').setBin('fixed', 0)
        self.clarabelle.find('**/pupilL').setBin('fixed', 1)
        self.clarabelle.find('**/pupilR').setBin('fixed', 1)
        self.clarabelle.find('**/glassL').setBin('fixed', 2)
        self.clarabelle.find('**/glassR').setBin('fixed', 2)
        switchboard = loader.loadModel('phase_5.5/models/estate/switchboard')
        switchboard.reparentTo(self.clarabelle)
        switchboard.setPos(1, -1.6, 0)
        switchboard.setH(30)
        room = loader.loadModel('phase_3/models/makeatoon/tt_m_ara_mat_room.bam')
        room.reparentTo(self.clarabelle)
        room.find('**/genderProps').removeNode()
        room.find('**/bodyWalls').removeNode()
        room.find('**/bodyProps').removeNode()
        room.find('**/colorWalls').removeNode()
        room.find('**/colorProps').removeNode()
        room.find('**/clothWalls').removeNode()
        room.find('**/nameWalls').removeNode()
        room.find('**/nameProps').removeNode()
        room.find('**/spotlight').removeNode()
        room.setPos(5.5, 1.25, 0)
        room.setH(330)
        self.clarabelle.reparentTo(self.cRender)
        self.clarabelle.setPosHprScale(-0.52, 6.13, -3.81, 85, 0.0, 0.0, 1.0, 1.0, 1.0)
        self.clarabelleFrame.setPosHprScale(-0.01, 0.0, -0.01, 0.0, 0.0, 0.0, 1.02, 1.0, 1.02)

    def reload(self):
        for panel in self.panelList + self.backPanelList + self.specialPanelList + self.emblemPanelList:
            panel.destroy()

        def priceSort(a, b, type):
            priceA = a.getPrice(type)
            priceB = b.getPrice(type)
            return priceB - priceA

        self.pageIndex = -1
        self.maxPageIndex = 0
        self.numNewPages = 0
        self.numBackPages = 5
        self.numSpecialPages = 0
        self.viewing = 'New'
        self.panelList = []
        self.backPanelList = []
        self.specialList = []
        self.pageList = []
        self.backPageList = []
        self.specialPanelList = []
        self.specialPageList = []
        self.panelDict = {}
        self.visiblePanels = []
        itemList = base.localAvatar.monthlyCatalog + base.localAvatar.weeklyCatalog
        itemList.sort(lambda a, b: priceSort(a, b, CatalogItem.CatalogTypeWeekly))
        itemList.reverse()
        for item in itemList:
            if item.getIsSpecial():
                self.specialPanelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeSpecial, parentCatalogScreen=self))
            else:
                self.panelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeWeekly))

        itemList = base.localAvatar.backCatalog
        itemList.sort(lambda a, b: priceSort(a, b, CatalogItem.CatalogTypeBackorder))
        itemList.reverse()
        for item in itemList:
            if item.getIsSpecial():
                self.specialPanelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeSpecial, parentCatalogScreen=self))
            else:
                self.backPanelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeBackorder))

        numPages = self.packPages(self.panelList, self.pageList, 'new')
        self.setNumNewPages(numPages)
        numPages = self.packPages(self.backPanelList, self.backPageList, 'back')
        self.setNumBackPages(numPages)
        numPages = self.packPages(self.specialPanelList, self.specialPageList, 'special')
        self.setNumSpecialPages(numPages)
        seriesNumber = (base.localAvatar.catalogScheduleCurrentWeek - 1) / ToontownGlobals.CatalogNumWeeksPerSeries + 1
        self.catalogSeries['text'] = Localizer.CatalogSeriesLabel % seriesNumber
        weekNumber = (base.localAvatar.catalogScheduleCurrentWeek - 1) % ToontownGlobals.CatalogNumWeeksPerSeries + 1
        self.catalogNumber['text'] = '#%d' % weekNumber
        self.enableBackorderCatalogButton()
        self.setMaxPageIndex(self.numNewPages)
        self.setPageIndex(-1)
        self.showPageItems()

    def unload(self):
        taskMgr.remove('clearClarabelleChat')
        taskMgr.remove('postGoodbyeHangUp')
        taskMgr.remove('clarabelleGreeting')
        taskMgr.remove('clarabelleHelpText1')
        taskMgr.remove('clarabelleAskAnythingElse')
        taskMgr.remove('friendButtonsReady')
        self.hide()
        self.hangup.hide()
        self.destroy()
        del self.base
        del self.squares
        for panel in self.panelList + self.backPanelList + self.specialPanelList + self.emblemPanelList:
            panel.destroy()

        del self.panelList
        del self.backPanelList
        del self.cover
        del self.rings
        del self.clarabelleFrame
        del self.hangup
        del self.beanBank
        del self.silverLabel
        del self.goldLabel
        del self.nextPageButton
        del self.backPageButton
        del self.newCatalogButton
        del self.newCatalogButton2
        del self.backCatalogButton
        del self.backCatalogButton2
        del self.specialCatalogButton
        del self.specialCatalogButton2
        del self.pageLabel
        if self.createdGiftGui:
            del self.giftToggle
            del self.giftLabel
            del self.friendLabel
            del self.scrollList
            del self.friend
            del self.friends
        self.unloadClarabelle()
        if self.responseDialog:
            self.responseDialog.cleanup()
            self.responseDialog = None

    def unloadClarabelle(self):
        base.win.removeDisplayRegion(self.cDr)
        del self.cRender
        del self.cCamera
        del self.cCamNode
        del self.cLens
        del self.cCam
        del self.cDr
        self.clarabelle.cleanup()
        del self.clarabelle

        if self.clarabelleChatBalloon:
            self.clarabelleChatBalloon.removeNode()
            del self.clarabelleChatBalloon

    def hangUp(self):
        self.setClarabelleChat(random.choice(TTLocalizer.CatalogGoodbyeList), type='goodbye')
        self.setPageIndex(-1)
        self.showPageItems()
        self.nextPageButton.hide()
        self.backPageButton.hide()
        self.newCatalogButton.hide()
        self.newCatalogButton2.hide()
        self.backCatalogButton.hide()
        self.backCatalogButton2.hide()
        self.specialCatalogButton.hide()
        self.specialCatalogButton2.hide()
        self.emblemCatalogButton.hide()
        self.emblemCatalogButton2.hide()
        self.hangup.hide()
        taskMgr.remove('clarabelleGreeting')
        taskMgr.remove('clarabelleHelpText1')
        taskMgr.remove('clarabelleAskAnythingElse')

        def postGoodbyeHangUp(task):
            messenger.send(self['doneEvent'])
            self.unload()

        taskMgr.doMethodLater(1.5, postGoodbyeHangUp, 'postGoodbyeHangUp')

    def remoteUpdate(self):
        self.update()

    def update(self, task = None):
        if (not self.friend) and self.gifting == 1:
            self.__giftToggle()
        if hasattr(self, 'beanBank'):
            self.beanBank['text'] = str(base.localAvatar.getTotalMoney())
            for item in self.panelList + self.backPanelList + self.specialPanelList + self.emblemPanelList:
                if type(item) != type(''):
                    item.updateButtons(self.gifting)

    def __handlePurchaseRequest(self, item):
        item.requestPurchase(self['phone'], self.__handlePurchaseResponse)
        taskMgr.remove('clarabelleAskAnythingElse')

    def __handleGiftPurchaseRequest(self, item):
        item.requestGiftPurchase(self['phone'], self.friendAvId, self.__handleGiftPurchaseResponse)
        taskMgr.remove('clarabelleAskAnythingElse')

    def __handlePurchaseResponse(self, retCode, item):
        if retCode == ToontownGlobals.P_UserCancelled:
            self.update()
            return

        if hasattr(item, 'houseId') and retCode == ToontownGlobals.P_ItemAvailable:
            localAvatar.houseType = item.houseId

        taskMgr.doMethodLater(0.5, self.update, 'purchaseUpdate')
        self.setClarabelleChat(item.getRequestPurchaseErrorText(retCode), item.getRequestPurchaseErrorTextTimeout())

    def __handleGiftPurchaseResponse(self, retCode, item):
        if retCode == ToontownGlobals.P_UserCancelled:
            return
        if self.isEmpty() or self.isHidden():
            return
        self.setClarabelleChat(item.getRequestGiftPurchaseErrorText(retCode) % self.friendName)
        self.__loadFriend()

        def askAnythingElse(task):
            self.setClarabelleChat(TTLocalizer.CatalogAnythingElse)

        if retCode >= 0:
            taskMgr.doMethodLater(8, askAnythingElse, 'clarabelleAskAnythingElse')

    def __clearDialog(self, event):
        self.responseDialog.cleanup()
        self.responseDialog = None
        return

    def setClarabelleChat(self, str, timeout = 6, type = None):
        self.clearClarabelleChat()

        if not self.clarabelleChatBalloon:
            self.clarabelleChatBalloon = loader.loadModel('phase_3/models/props/chatbox')

        self.clarabelleChat = ChatBalloon(self.clarabelleChatBalloon)
        chatNode = self.clarabelleChat.generate(str, ToontownGlobals.getInterfaceFont())[0]
        self.clarabelleChatNP = self.attachNewNode(chatNode.node(), 1000)
        self.clarabelleChatNP.setScale(0.08)
        self.clarabelleChatNP.setPos(0.7, 0, 0.6)

        if timeout:
            taskMgr.doMethodLater(timeout, self.clearClarabelleChat, 'clearClarabelleChat')

    def clearClarabelleChat(self, task = None):
        taskMgr.remove('clearClarabelleChat')
        if self.clarabelleChatNP:
            self.clarabelleChatNP.removeNode()
            self.clarabelleChatNP = None
            del self.clarabelleChat
        return

    def __moneyChange(self, money):
        self.update()

    def __bankMoneyChange(self, bankMoney):
        self.update()

    def __emblemChange(self, newEmblems):
        self.silverLabel['text'] = str(newEmblems[0])
        self.goldLabel['text'] = str(newEmblems[1])

    def showEmblems(self):
        if base.cr.wantEmblems:
            self.silverLabel.show()
            self.goldLabel.show()

    def hideEmblems(self):
        self.silverLabel.hide()
        self.goldLabel.hide()

    def __makeFriendList(self):
        for av in base.cr.avList:
            if av.id != base.localAvatar.doId:
                self.friendList.append((av.id, av.name, NametagGroup.CCNonPlayer))
                
        for id, handle in base.cr.friendsMap.items():
            if isinstance(handle, FriendHandle.FriendHandle):
                self.friendList.append((id, handle.getName(), NametagConstants.getFriendColor(handle)))

    def __makeScrollList(self):
        for friend in self.friendList:
            button = self.makeFriendButton(*friend)
            self.scrollList.addItem(button, refresh=0)
            self.friends.append(button)

        self.scrollList.refresh()

    def makeFriendButton(self, avId, name, colorCode):
        color = NametagConstants.NAMETAG_COLORS[colorCode]

        return DirectButton(relief=None, text=name, text_scale=0.04, text_align=TextNode.ALeft, text_fg=color[0][0], text1_bg=(1, 1, 0, 1),
                            text2_bg=(0.5, 0.9, 1, 1), text3_fg=(0.4, 0.8, 0.4, 1), command=self.__chooseFriend, extraArgs=[avId, name])

    def __chooseFriend(self, avId, name):
        messenger.send('wakeup')
        
        if self.friendAvId == avId:
            return

        self.friendAvId = avId
        self.friendName = name
        self.__loadFriend()

    def __loadFriend(self):
        if not self.friendAvId:
            return

        for friendButton in self.friends:
            friendButton['state'] = DGG.DISABLED

        self.friend = None
        self.friendLabel['text'] = TTLocalizer.CatalogGiftUpdating
        taskMgr.remove('friendButtonsReady')
        self['phone'].requestGiftAvatar(self.friendAvId)
    
    def setFriendReady(self, friend):
        self.friend = friend
        self.friendLabel['text'] = TTLocalizer.CatalogGiftTo % self.friendName
        taskMgr.doMethodLater(1.5, self.setFriendButtonsReady, 'friendButtonsReady')
        self.update()
    
    def setFriendButtonsReady(self, task=None):
        for friendButton in self.friends:
            friendButton['state'] = DGG.NORMAL

    def __giftToggle(self):
        messenger.send('wakeup')
        if self.gifting == -1:
            self.gifting = 1
            self.giftLabel.show()
            self.friendLabel.show()
            self.scrollList.show()
            self.hideEmblems()
            self.giftToggle['text'] = TTLocalizer.CatalogGiftToggleOn
            self.friendLabel['text'] = TTLocalizer.CatalogGiftChoose
            self.__loadFriend()
        else:
            self.friend = None
            self.friendAvId = 0
            self.friendName = None
            self.gifting = -1
            self.giftLabel.hide()
            self.friendLabel.hide()
            self.scrollList.hide()
            self.showEmblems()
            self.giftToggle['text'] = TTLocalizer.CatalogGiftToggleOff
            self.update()
示例#4
0
class CatalogScreen(DirectFrame):
    notify = DirectNotifyGlobal.directNotify.newCategory('CatalogScreen')

    def __init__(self, parent = aspect2d, **kw):
        guiItems = loader.loadModel('phase_5.5/models/gui/catalog_gui')
        background = guiItems.find('**/catalog_background')
        background.setBin("background", 10)
        guiButton = loader.loadModel('phase_3/models/gui/quit_button')
        guiBack = loader.loadModel('phase_5.5/models/gui/package_delivery_panel')
        optiondefs = (('scale', 0.667, None),
         ('pos', (0, 1, 0.025), None),
         ('phone', None, None),
         ('doneEvent', None, None),
         ('image', background, None),
         ('relief', None, None))
        self.defineoptions(kw, optiondefs)
        DirectFrame.__init__(self, parent)
        self.friendGiftIndex = 0
        self.friendGiftHandle = None
        self.frienddoId = None
        self.receiverName = 'Error Nameless Toon'
        self.friends = {}
        self.family = {}
        self.ffList = []
        self.textRolloverColor = Vec4(1, 1, 0, 1)
        self.textDownColor = Vec4(0.5, 0.9, 1, 1)
        self.textDisabledColor = Vec4(0.4, 0.8, 0.4, 1)
        self.giftAvatar = None
        self.gotAvatar = 0
        self.allowGetDetails = 1
        self.load(guiItems, guiButton, guiBack)
        self.initialiseoptions(CatalogScreen)
        self.enableBackorderCatalogButton()
        self.setMaxPageIndex(self.numNewPages)
        self.setPageIndex(-1)
        self.showPageItems()
        self.hide()
        self.clarabelleChatNP = None
        self.clarabelleChatBalloon = None
        self.clarabelleGreetingSfx = None
        self.clarabelleGoodbyeSfx = None
        self.clarabelleErrorSfx = None
        self.clarabelleChatterSfx = None
        self.gifting = -1
        self.createdGiftGui = None
        self.viewing = None
        return

    def show(self):
        self.accept('CatalogItemPurchaseRequest', self.__handlePurchaseRequest)
        self.accept('CatalogItemGiftPurchaseRequest', self.__handleGiftPurchaseRequest)
        self.accept(localAvatar.uniqueName('moneyChange'), self.__moneyChange)
        self.accept(localAvatar.uniqueName('bankMoneyChange'), self.__bankMoneyChange)

        deliveryText = 'setDeliverySchedule-%s' % base.localAvatar.doId
        self.accept(deliveryText, self.remoteUpdate)
        base.setBackgroundColor(Vec4(0.529, 0.290, 0.286, 1))
        render.hide()
        DirectFrame.show(self)

        def clarabelleGreeting(task):
            self.setClarabelleChat(TTLocalizer.CatalogGreeting, type='greeting')

        def clarabelleHelpText1(task):
            self.setClarabelleChat(TTLocalizer.CatalogHelpText1)

        taskMgr.doMethodLater(1.0, clarabelleGreeting, 'clarabelleGreeting')
        taskMgr.doMethodLater(12.0, clarabelleHelpText1, 'clarabelleHelpText1')
        if hasattr(self, 'giftToggle'):
            self.giftToggle['text'] = TTLocalizer.CatalogGiftToggleOff

    def hide(self):
        self.ignore('CatalogItemPurchaseRequest')
        self.ignore('CatalogItemGiftPurchaseRequest')
        self.ignore('DeliveryManagerAck')
        taskMgr.remove('ackTimeOut')
        self.ignore(localAvatar.uniqueName('moneyChange'))
        self.ignore(localAvatar.uniqueName('bankMoneyChange'))

        deliveryText = 'setDeliverySchedule-%s' % base.localAvatar.doId
        self.ignore(deliveryText)
        base.setBackgroundColor(ToontownGlobals.DefaultBackgroundColor)
        render.show()
        DirectFrame.hide(self)

    def setNumNewPages(self, numNewPages):
        self.numNewPages = numNewPages

    def setNumBackPages(self, numBackPages):
        self.numBackPages = numBackPages

    def setNumLoyaltyPages(self, numLoyaltyPages):
        self.numLoyaltyPages = numLoyaltyPages


    def setPageIndex(self, index):
        self.pageIndex = index

    def setMaxPageIndex(self, numPages):
        self.maxPageIndex = max(numPages - 1, -1)

    def enableBackorderCatalogButton(self):
        self.backCatalogButton['state'] = DGG.NORMAL
        self.newCatalogButton['state'] = DGG.DISABLED
        self.loyaltyCatalogButton['state'] = DGG.DISABLED

    def enableNewCatalogButton(self):
        self.backCatalogButton['state'] = DGG.DISABLED
        self.newCatalogButton['state'] = DGG.NORMAL
        self.loyaltyCatalogButton['state'] = DGG.DISABLED

    def enableLoyaltyCatalogButton(self):
        self.backCatalogButton['state'] = DGG.DISABLED
        self.newCatalogButton['state'] = DGG.DISABLED
        self.loyaltyCatalogButton['state'] = DGG.NORMAL

    def modeBackorderCatalog(self):
        self.backCatalogButton['state'] = DGG.DISABLED
        self.newCatalogButton['state'] = DGG.NORMAL
        self.loyaltyCatalogButton['state'] = DGG.NORMAL

    def modeNewCatalog(self):
        self.backCatalogButton['state'] = DGG.NORMAL
        self.newCatalogButton['state'] = DGG.DISABLED
        self.loyaltyCatalogButton['state'] = DGG.NORMAL

    def modeLoyaltyCatalog(self):
        self.backCatalogButton['state'] = DGG.NORMAL
        self.newCatalogButton['state'] = DGG.NORMAL
        self.loyaltyCatalogButton['state'] = DGG.DISABLED

    def showNewItems(self, index = None):
        if config.GetBool('want-qa-regression', 0):
            self.notify.info('QA-REGRESSION: CATALOG: New item')
        taskMgr.remove('clarabelleHelpText1')
        messenger.send('wakeup')
        self.viewing = 'New'
        self.modeNewCatalog()
        self.setMaxPageIndex(self.numNewPages)
        if self.numNewPages == 0:
            self.setPageIndex(-1)
        elif index is not None:
            self.setPageIndex(index)
        else:
            self.setPageIndex(0)
        self.showPageItems()
        return

    def showBackorderItems(self, index = None):
        if config.GetBool('want-qa-regression', 0):
            self.notify.info('QA-REGRESSION: CATALOG: Backorder item')
        taskMgr.remove('clarabelleHelpText1')
        messenger.send('wakeup')
        self.viewing = 'Backorder'
        self.modeBackorderCatalog()
        self.setMaxPageIndex(self.numBackPages)
        if self.numBackPages == 0:
            self.setPageIndex(-1)
        elif index is not None:
            self.setPageIndex(index)
        else:
            self.setPageIndex(0)
        self.showPageItems()
        return

    def showLoyaltyItems(self, index = None):
        if config.GetBool('want-qa-regression', 0):
            self.notify.info('QA-REGRESSION: CATALOG: Special item')
        taskMgr.remove('clarabelleHelpText1')
        messenger.send('wakeup')
        self.viewing = 'Loyalty'
        self.modeLoyaltyCatalog()
        self.setMaxPageIndex(self.numLoyaltyPages)
        if self.numLoyaltyPages == 0:
            self.setPageIndex(-1)
        elif index is not None:
            self.setPageIndex(index)
        else:
            self.setPageIndex(0)
        self.showPageItems()
        return


    def showNextPage(self):
        taskMgr.remove('clarabelleHelpText1')
        messenger.send('wakeup')
        self.pageIndex = self.pageIndex + 1
        if self.viewing == None:
            self.modeNewCatalog()
            self.viewing == 'New'
        if self.viewing == 'New' and self.pageIndex > self.maxPageIndex and self.numBackPages > 0:
            self.showBackorderItems()
        if self.viewing == 'New' and self.pageIndex > self.maxPageIndex and self.numLoyaltyPages > 0:
            self.showLoyaltyItems()
        elif self.viewing == 'Backorder' and self.pageIndex > self.maxPageIndex and self.numLoyaltyPages > 0:
            self.showLoyaltyItems()

        else:
            self.pageIndex = min(self.pageIndex, self.maxPageIndex)
            self.showPageItems()
        return

    def showBackPage(self):
        taskMgr.remove('clarabelleHelpText1')
        messenger.send('wakeup')
        self.pageIndex = self.pageIndex - 1
        if self.viewing == 'Backorder' and self.pageIndex < 0 and self.numNewPages > 0:
            self.showNewItems(self.numNewPages - 1)
        elif self.viewing == 'Loyalty' and self.pageIndex < 0 and self.numBackPages > 0:
            self.showBackorderItems(self.numBackPages - 1)

        else:
            self.pageIndex = max(self.pageIndex, -1)
            self.showPageItems()

    def showPageItems(self):
        self.hidePages()
        if self.viewing == None:
            self.viewing = 'New'
        if self.pageIndex < 0:
            self.closeCover()
        else:
            if self.pageIndex == 0:
                self.openCover()
            if self.viewing == 'New':
                page = self.pageList[self.pageIndex]
                newOrBackOrLoyalty = 0
            elif self.viewing == 'Backorder':
                page = self.backPageList[self.pageIndex]
                newOrBackOrLoyalty = 1
            elif self.viewing == 'Loyalty':
                page = self.loyaltyPageList[self.pageIndex]
                newOrBackOrLoyalty = 2
            page.show()
            for panel in self.panelDict[page.get_key()]:
                panel.load()
                if panel.ival:
                    panel.ival.loop()
                self.visiblePanels.append(panel)

            pIndex = 0
            randGen = random.Random()
            randGen.seed(base.localAvatar.catalogScheduleCurrentWeek + (self.pageIndex << 8) + (newOrBackOrLoyalty << 16))
            for i in xrange(NUM_CATALOG_ROWS):
                for j in xrange(NUM_CATALOG_COLS):
                    if pIndex < len(self.visiblePanels):
                        type = self.visiblePanels[pIndex]['item'].getTypeCode()
                        self.squares[i][j].setColor(CatalogPanelColors.values()[randGen.randint(0, len(CatalogPanelColors) - 1)])
                        cs = 0.7 + 0.3 * randGen.random()
                        self.squares[i][j].setColorScale(0.7 + 0.3 * randGen.random(), 0.7 + 0.3 * randGen.random(), 0.7 + 0.3 * randGen.random(), 1)
                    else:
                        self.squares[i][j].setColor(CatalogPanelColors[CatalogItemTypes.CHAT_ITEM])
                        self.squares[i][j].clearColorScale()
                    pIndex += 1

            if self.viewing == 'New':
                text = TTLocalizer.CatalogNew
            elif self.viewing == 'Loyalty':
                text = TTLocalizer.CatalogLoyalty
            elif self.viewing == 'Backorder':
                text = TTLocalizer.CatalogBackorder

            self.pageLabel['text'] = text + ' - %d' % (self.pageIndex + 1)
            if self.pageIndex < self.maxPageIndex:
                self.nextPageButton.show()
            elif self.viewing == 'New' and self.numBackPages == 0 and self.numLoyaltyPages == 0:
                self.nextPageButton.hide()
            elif self.viewing == 'Backorder' and self.numLoyaltyPages == 0:
                self.nextPageButton.hide()
            elif self.viewing == 'Loyalty':
                self.nextPageButton.hide()


            self.adjustForSound()
            self.update()
        return

    def adjustForSound(self):
        numEmoteItems = 0
        emotePanels = []
        for visIndex in xrange(len(self.visiblePanels)):
            panel = self.visiblePanels[visIndex]
            item = panel['item']
            catalogType = item.getTypeCode()
            if catalogType == CatalogItemTypes.EMOTE_ITEM:
                numEmoteItems += 1
                emotePanels.append(panel)
            else:
                panel.soundOnButton.hide()
                panel.soundOffButton.hide()

        if numEmoteItems == 1:
            emotePanels[0].handleSoundOnButton()
        elif numEmoteItems > 1:
            for panel in emotePanels:
                panel.handleSoundOffButton()

    def hidePages(self):
        for page in self.pageList:
            page.hide()

        for page in self.backPageList:
            page.hide()

        for page in self.loyaltyPageList:
            page.hide()


        for panel in self.visiblePanels:
            if panel.ival:
                panel.ival.finish()

        self.visiblePanels = []

    def openCover(self):
        self.cover.hide()
        self.hideDummyTabs()
        self.backPageButton.show()
        self.pageLabel.show()

    def closeCover(self):
        self.cover.show()
        self.showDummyTabs()
        self.nextPageButton.show()
        self.backPageButton.hide()
        self.pageLabel.hide()
        self.hidePages()

    def showDummyTabs(self):
        if self.numNewPages > 0:
            self.newCatalogButton2.show()
        if self.numBackPages > 0:
            self.backCatalogButton2.show()
        if self.numLoyaltyPages > 0:
            self.loyaltyCatalogButton2.show()

        self.newCatalogButton.hide()
        self.backCatalogButton.hide()
        self.loyaltyCatalogButton.hide()


    def hideDummyTabs(self):
        self.newCatalogButton2.hide()
        self.backCatalogButton2.hide()
        self.loyaltyCatalogButton2.hide()

        if self.numNewPages > 0:
            self.newCatalogButton.show()
        if self.numBackPages > 0:
            self.backCatalogButton.show()
        if self.numLoyaltyPages > 0:
            self.loyaltyCatalogButton.show()


    def packPages(self, panelList, pageList, prefix):
        i = 0
        j = 0
        numPages = 0
        pageName = prefix + '_page%d' % numPages
        for item in panelList:
            if i == 0 and j == 0:
                numPages += 1
                pageName = prefix + '_page%d' % numPages
                page = self.base.attachNewNode(pageName)
                pageList.append(page)
            item.reparentTo(page)
            item.setPos(CatalogPanelCenters[i][j])
            itemList = self.panelDict.get(page.get_key(), [])
            itemList.append(item)
            self.panelDict[page.get_key()] = itemList
            j += 1
            if j == NUM_CATALOG_COLS:
                j = 0
                i += 1
            if i == NUM_CATALOG_ROWS:
                i = 0

        return numPages

    def load(self, guiItems, guiButton, guiBack):
        self.pageIndex = -1
        self.maxPageIndex = 0
        self.numNewPages = 0
        self.numBackPages = 5
        self.numLoyaltyPages = 0
        self.viewing = 'New'
        self.panelList = []
        self.backPanelList = []
        self.pageList = []
        self.backPageList = []
        self.loyaltyPanelList = []
        self.loyaltyPageList = []

        self.panelDict = {}
        self.visiblePanels = []
        self.responseDialog = None
        catalogBase = guiItems.find('**/catalog_base')
        self.base = DirectLabel(self, relief=None, image=catalogBase)
        newDown = guiItems.find('**/new1')
        newUp = guiItems.find('**/new2')
        backDown = guiItems.find('**/previous2')
        backUp = guiItems.find('**/previous1')
        giftToggleUp = guiItems.find('**/giftButtonUp')
        giftToggleDown = guiItems.find('**/giftButtonDown')
        giftFriends = guiItems.find('**/gift_names')
        oldLift = 0.4
        lift = 0.4
        liftDiff = lift - oldLift
        lift2 = 0.05
        smash = 0.75
        priceScale = 0.15

        self.newCatalogButton = DirectButton(self.base, relief=None, pos=(0, 0, 0.17), frameSize=(-0.2,
         0.25,
         0.45,
         1.2), image=[newDown,
         newDown,
         newDown,
         newUp], image_scale=(1.0, 1.0, smash), image_pos=(0.0, 0.0, lift), pressEffect=0, command=self.showNewItems, text=TTLocalizer.CatalogNew, text_font=ToontownGlobals.getSignFont(), text_pos=(-0.4 - lift, 0.13), text3_pos=(-0.4 - lift, 0.1), text_scale=0.08, text_fg=(0.353, 0.627, 0.627, 1.0), text2_fg=(0.353, 0.427, 0.427, 1.0))
        self.newCatalogButton.hide()
        self.newCatalogButton2 = DirectButton(self.base, relief=None, pos=(0, 0, 0.17), frameSize=(-0.2,
         0.25,
         0.45,
         1.2), image=newDown, image_scale=(1.0, 1.0, smash), image_pos=(0.0, 0.0, lift), pressEffect=0, command=self.showNewItems, text=TTLocalizer.CatalogNew, text_font=ToontownGlobals.getSignFont(), text_pos=(-0.4 - lift, 0.13), text_scale=0.08, text_fg=(0.353, 0.627, 0.627, 1.0), text2_fg=(0.353, 0.427, 0.427, 1.0))
        self.newCatalogButton2.hide()
        self.backCatalogButton = DirectButton(self.base, relief=None, pos=(0, 0, 0.269), frameSize=(-0.2,
         0.25,
         -0.2,
         0.4), image=[backDown,
         backDown,
         backDown,
         backUp], image_scale=(1.0, 1.0, smash), image_pos=(0.0, 0.0, lift), pressEffect=0, command=self.showBackorderItems, text=TTLocalizer.CatalogBackorder, text_font=ToontownGlobals.getSignFont(), text_pos=(0.25 - lift, 0.132), text3_pos=(0.25 - lift, 0.112), text_scale=TTLocalizer.CSbackCatalogButton, text_fg=(0.392, 0.549, 0.627, 1.0), text2_fg=(0.392, 0.349, 0.427, 1.0))
        self.backCatalogButton.hide()
        self.backCatalogButton2 = DirectButton(self.base, relief=None, pos=(0, 0, 0.269), frameSize=(-0.2,
         0.25,
         -0.2,
         0.4), image_scale=(1.0, 1.0, smash), image_pos=(0.0, 0.0, lift), image=backDown, pressEffect=0, command=self.showBackorderItems, text=TTLocalizer.CatalogBackorder, text_font=ToontownGlobals.getSignFont(), text_pos=(0.25 - lift, 0.132), text_scale=TTLocalizer.CSbackCatalogButton, text_fg=(0.392, 0.549, 0.627, 1.0), text2_fg=(0.392, 0.349, 0.427, 1.0))
        self.backCatalogButton2.hide()
        self.loyaltyCatalogButton = DirectButton(self.base, relief=None, pos=(0, 0, 0.469), frameSize=(-0.2,
         0.25,
         -0.85,
         -0.3), image=[newDown,
         newDown,
         newDown,
         newUp], image_scale=(1.0, 1.0, smash), image_pos=(0.0, 0.0, -1.4 + lift), pressEffect=0, command=self.showLoyaltyItems, text=TTLocalizer.CatalogLoyalty, text_font=ToontownGlobals.getSignFont(), text_pos=(1.0 - lift, 0.132), text3_pos=(1.0 - lift, 0.112), text_scale=0.065, text_fg=(0.353, 0.627, 0.627, 1.0), text2_fg=(0.353, 0.427, 0.427, 1.0))
        self.loyaltyCatalogButton.hide()
        self.loyaltyCatalogButton2 = DirectButton(self.base, relief=None, pos=(0, 0, 0.469), frameSize=(-0.2,
         0.25,
         -0.85,
         -0.3), image_scale=(1.0, 1.0, smash), image_pos=(0.0, 0.0, -1.4 + lift), image=newDown, pressEffect=0, command=self.showLoyaltyItems, text=TTLocalizer.CatalogLoyalty, text_font=ToontownGlobals.getSignFont(), text_pos=(1.0 - lift, 0.132), text_scale=0.065, text_fg=(0.353, 0.627, 0.627, 1.0), text2_fg=(0.353, 0.427, 0.427, 1.0))
        self.loyaltyCatalogButton2.hide()
        self.__makeFFlist()
        if len(self.ffList) > 0:
            if config.GetBool('want-gifting', True):
                self.giftToggle = DirectButton(self.base, relief=None, pressEffect=0, image=(giftToggleUp, giftToggleDown, giftToggleUp), image_scale=(1.0, 1, 0.7), command=self.__giftToggle, text=TTLocalizer.CatalogGiftToggleOff, text_font=ToontownGlobals.getSignFont(), text_pos=TTLocalizer.CSgiftTogglePos, text_scale=TTLocalizer.CSgiftToggle, text_fg=(0.353, 0.627, 0.627, 1.0), text3_fg=(0.15, 0.3, 0.3, 1.0), text2_fg=(0.353, 0.427, 0.427, 1.0), image_color=Vec4(1.0, 1.0, 0.2, 1.0), image1_color=Vec4(0.9, 0.85, 0.2, 1.0), image2_color=Vec4(0.9, 0.85, 0.2, 1.0), image3_color=Vec4(0.5, 0.45, 0.2, 1.0))
                self.giftToggle.setPos(0.0, 0, -0.035)
            self.giftLabel = DirectLabel(self.base, relief=None, image=giftFriends, image_scale=(1.15, 1, 1.14), text=' ', text_font=ToontownGlobals.getSignFont(), text_pos=(1.2, -0.97), text_scale=0.07, text_fg=(0.392, 0.549, 0.627, 1.0), sortOrder=100, textMayChange=1)
            self.giftLabel.setPos(-0.15, 0, 0.08)
            self.giftLabel.hide()
            self.friendLabel = DirectLabel(self.base, relief=None, text='Friend Name', text_font=ToontownGlobals.getSignFont(), text_pos=(-0.25, 0.132), text_scale=0.068, text_align=TextNode.ALeft, text_fg=(0.992, 0.949, 0.327, 1.0), sortOrder=100, textMayChange=1)
            self.friendLabel.setPos(0.5, 0, -0.42)
            self.friendLabel.hide()
            gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui')
            self.scrollList = DirectScrolledList(parent=self, relief=None, incButton_image=(gui.find('**/FndsLst_ScrollUp'),
             gui.find('**/FndsLst_ScrollDN'),
             gui.find('**/FndsLst_ScrollUp_Rllvr'),
             gui.find('**/FndsLst_ScrollUp')), incButton_relief=None, incButton_pos=(0.0, 0.0, -0.316), incButton_image1_color=Vec4(1.0, 0.9, 0.4, 1.0), incButton_image3_color=Vec4(1.0, 1.0, 0.6, 0.5), incButton_scale=(1.0, 1.0, -1.0), decButton_image=(gui.find('**/FndsLst_ScrollUp'),
             gui.find('**/FndsLst_ScrollDN'),
             gui.find('**/FndsLst_ScrollUp_Rllvr'),
             gui.find('**/FndsLst_ScrollUp')), decButton_relief=None, decButton_pos=(0.0, 0.0, 0.117), decButton_image1_color=Vec4(1.0, 1.0, 0.6, 1.0), decButton_image3_color=Vec4(1.0, 1.0, 0.6, 0.6), itemFrame_pos=(-0.17, 0.0, 0.06), itemFrame_relief=None, numItemsVisible=8, items=[])
            self.scrollList.setPos(1.2, 0, -0.58)
            self.scrollList.setScale(1.5)
            self.scrollList.hide()
            clipper = PlaneNode('clipper')
            clipper.setPlane(Plane(Vec3(-1, 0, 0), Point3(0.17, 0, 0)))
            clipNP = self.scrollList.attachNewNode(clipper)
            self.scrollList.setClipPlane(clipNP)
            self.__makeScrollList()
            friendId = self.ffList[0]
            self.__chooseFriend(self.ffList[0][0], self.ffList[0][1])
            self.update()
            self.createdGiftGui = 1
        for i in xrange(4):
            self.newCatalogButton.component('text%d' % i).setR(90)
            self.newCatalogButton2.component('text%d' % i).setR(90)
            self.backCatalogButton.component('text%d' % i).setR(90)
            self.backCatalogButton2.component('text%d' % i).setR(90)
            self.loyaltyCatalogButton.component('text%d' % i).setR(90)
            self.loyaltyCatalogButton2.component('text%d' % i).setR(90)


        self.squares = [[],
         [],
         [],
         []]
        for i in xrange(NUM_CATALOG_ROWS):
            for j in xrange(NUM_CATALOG_COLS):
                square = guiItems.find('**/square%d%db' % (i + 1, j + 1))
                label = DirectLabel(self.base, image=square, relief=None, state='normal')
                self.squares[i].append(label)

        def priceSort(a, b, type):
            priceA = a.getPrice(type)
            priceB = b.getPrice(type)
            return priceB - priceA

        itemList = base.localAvatar.monthlyCatalog + base.localAvatar.weeklyCatalog
        itemList.sort(lambda a, b: priceSort(a, b, CatalogItem.CatalogTypeWeekly))
        itemList.reverse()
        allClosetItems = CatalogFurnitureItem.getAllClosets()
        allBankItems = CatalogFurnitureItem.getAllBanks()
        isMaxClosetOfferred = False
        isMaxBankOffered = False
        for item in itemList:
            if item in allClosetItems and item.furnitureType in CatalogFurnitureItem.MaxClosetIds:
                isMaxClosetOfferred = True
                break

        for item in itemList:
            if item in allBankItems and item.furnitureType == CatalogFurnitureItem.MaxBankId:
                isMaxBankOffered = true
                break
                
        for item in itemList:
            if isinstance(item, CatalogInvalidItem.CatalogInvalidItem):
                self.notify.warning('skipping catalog invalid item %s' % item)
                continue
            if isMaxClosetOfferred and item in allClosetItems and item.furnitureType not in CatalogFurnitureItem.MaxClosetIds:
                continue
            if isMaxBankOffered and item in allBankItems and item.furnitureType != CatalogFurnitureItem.MaxBankId:
                continue
            if item.loyaltyRequirement() != 0:
                self.loyaltyPanelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeLoyalty, parentCatalogScreen=self))
            else:
                self.panelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeWeekly, parentCatalogScreen=self))

        itemList = base.localAvatar.backCatalog
        itemList.sort(lambda a, b: priceSort(a, b, CatalogItem.CatalogTypeBackorder))
        itemList.reverse()
        for item in itemList:
            if isinstance(item, CatalogInvalidItem.CatalogInvalidItem):
                self.notify.warning('skipping catalog invalid item %s' % item)
                continue
            if isMaxClosetOfferred and item in allClosetItems and item.furnitureType not in CatalogFurnitureItem.MaxClosetIds:
                continue
            if isMaxBankOffered and item in allBankItems and item.furnitureType != CatalogFurnitureItem.MaxBankId:
                continue
            if item.loyaltyRequirement() != 0:
                self.loyaltyPanelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeLoyalty, parentCatalogScreen=self))
            else:
                self.backPanelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeBackorder, parentCatalogScreen=self))

        numPages = self.packPages(self.panelList, self.pageList, 'new')
        self.setNumNewPages(numPages)
        numPages = self.packPages(self.backPanelList, self.backPageList, 'back')
        self.setNumBackPages(numPages)
        numPages = self.packPages(self.loyaltyPanelList, self.loyaltyPageList, 'loyalty')
        self.setNumLoyaltyPages(numPages)

        currentWeek = base.localAvatar.catalogScheduleCurrentWeek - 1
        if currentWeek < 57:
            seriesNumber = currentWeek / ToontownGlobals.CatalogNumWeeksPerSeries + 1
            weekNumber = currentWeek % ToontownGlobals.CatalogNumWeeksPerSeries + 1
        elif currentWeek < 65:
            seriesNumber = 6
            weekNumber = currentWeek - 56
        else:
            seriesNumber = currentWeek / ToontownGlobals.CatalogNumWeeksPerSeries + 2
            weekNumber = currentWeek % ToontownGlobals.CatalogNumWeeksPerSeries + 1
        geom = NodePath('cover')
        cover = guiItems.find('**/cover')
        maxSeries = ToontownGlobals.CatalogNumWeeks / ToontownGlobals.CatalogNumWeeksPerSeries + 1
        coverSeries = (seriesNumber - 1) % maxSeries + 1
        coverPicture = cover.find('**/cover_picture%s' % coverSeries)
        if not coverPicture.isEmpty():
            coverPicture.reparentTo(geom)
        bottomSquare = cover.find('**/cover_bottom')
        topSquare = guiItems.find('**/square12b2')
        if seriesNumber == 1:
            topSquare.setColor(0.651, 0.404, 0.322, 1.0)
            bottomSquare.setColor(0.651, 0.404, 0.322, 1.0)
        else:
            topSquare.setColor(0.651, 0.404, 0.322, 1.0)
            bottomSquare.setColor(0.651, 0.404, 0.322, 1.0)
        bottomSquare.reparentTo(geom)
        topSquare.reparentTo(geom)
        cover.find('**/clarabelle_text').reparentTo(geom)
        cover.find('**/blue_circle').reparentTo(geom)
        cover.find('**/clarabelle').reparentTo(geom)
        cover.find('**/circle_green').reparentTo(geom)
        self.cover = DirectLabel(self.base, relief=None, geom=geom)
        self.catalogNumber = DirectLabel(self.cover, relief=None, scale=0.2, pos=(-0.22, 0, -0.33), text='#%d' % weekNumber, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getInterfaceFont())
        self.catalogSeries = DirectLabel(self.cover, relief=None, scale=(0.22, 1, 0.18), pos=(-0.76, 0, -0.9), text=TTLocalizer.CatalogSeriesLabel % seriesNumber, text_fg=(0.9, 0.9, 0.4, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getInterfaceFont())
        self.catalogSeries.setShxz(0.4)
        self.rings = DirectLabel(self.base, relief=None, geom=guiItems.find('**/rings'))
        self.clarabelleFrame = DirectLabel(self, relief=None, image=guiItems.find('**/clarabelle_frame'))
        hangupGui = guiItems.find('**/hangup')
        hangupRolloverGui = guiItems.find('**/hangup_rollover')
        self.hangup = DirectButton(base.a2dBottomRight, relief=None, pos=(-0.158, 0, 0.14), scale=(0.7, 0.7, 0.7), image=[hangupGui,
         hangupRolloverGui,
         hangupRolloverGui,
         hangupGui], text=['', TTLocalizer.CatalogHangUp, TTLocalizer.CatalogHangUp], text_fg=Vec4(1), text_scale=0.07, text_pos=(0.0, 0.14), command=self.hangUp)
        self.beanBank = DirectLabel(self, relief=None, image=guiItems.find('**/bean_bank'), text=str(base.localAvatar.getMoney() + base.localAvatar.getBankMoney()), text_align=TextNode.ARight, text_scale=0.11, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_pos=(0.75, -0.81), text_font=ToontownGlobals.getSignFont())
        nextUp = guiItems.find('**/arrow_up')
        nextRollover = guiItems.find('**/arrow_Rollover')
        nextDown = guiItems.find('**/arrow_Down')
        prevUp = guiItems.find('**/arrowUp')
        prevDown = guiItems.find('**/arrowDown1')
        prevRollover = guiItems.find('**/arrowRollover')
        self.nextPageButton = DirectButton(self, relief=None, pos=(-0.1, 0, -0.9), image=[nextUp,
         nextDown,
         nextRollover,
         nextUp], image_color=(0.9, 0.9, 0.9, 1), image2_color=(1, 1, 1, 1), command=self.showNextPage)
        self.backPageButton = DirectButton(self, relief=None, pos=(-0.1, 0, -0.9), image=[prevUp,
         prevDown,
         prevRollover,
         prevUp], image_color=(0.9, 0.9, 0.9, 1), image2_color=(1, 1, 1, 1), command=self.showBackPage)
        self.backPageButton.hide()
        self.pageLabel = DirectLabel(self.base, relief=None, pos=(-1.33, 0, -0.9), scale=0.06, text=TTLocalizer.CatalogPagePrefix, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ALeft)
        self.loadClarabelle()
        return

    def loadClarabelle(self):
        self.cRender = NodePath('cRender')
        self.cCamera = self.cRender.attachNewNode('cCamera')
        self.cCamNode = Camera('cCam')
        self.cLens = PerspectiveLens()
        self.cLens.setFov(40, 40)
        self.cLens.setNear(0.1)
        self.cLens.setFar(100.0)
        self.cCamNode.setLens(self.cLens)
        self.cCamNode.setScene(self.cRender)
        self.cCam = self.cCamera.attachNewNode(self.cCamNode)
        self.cDr = base.win.makeDisplayRegion(0.56, 0.81, 0.52, 0.85)
        self.cDr.setSort(1)
        self.cDr.setClearDepthActive(1)
        self.cDr.setClearColorActive(1)
        self.cDr.setClearColor(Vec4(0.3, 0.3, 0.3, 1))
        self.cDr.setCamera(self.cCam)
        self.clarabelle = Actor.Actor('phase_5.5/models/char/Clarabelle-zero', {'listen': 'phase_5.5/models/char/Clarabelle-listens'})
        self.clarabelle.loop('listen')
        self.clarabelle.find('**/eyes').setBin('fixed', 0)
        self.clarabelle.find('**/pupilL').setBin('fixed', 1)
        self.clarabelle.find('**/pupilR').setBin('fixed', 1)
        self.clarabelle.find('**/glassL').setBin('fixed', 2)
        self.clarabelle.find('**/glassR').setBin('fixed', 2)
        switchboard = loader.loadModel('phase_5.5/models/estate/switchboard')
        switchboard.reparentTo(self.clarabelle)
        switchboard.setPos(1, -1.6, 0)
        switchboard.setH(30)
        room = loader.loadModel('phase_3/models/makeatoon/tt_m_ara_mat_room.bam')
        room.reparentTo(self.clarabelle)
        room.find('**/genderProps').removeNode()
        room.find('**/bodyWalls').removeNode()
        room.find('**/bodyProps').removeNode()
        room.find('**/colorWalls').removeNode()
        room.find('**/colorProps').removeNode()
        room.find('**/clothWalls').removeNode()
        room.find('**/nameWalls').removeNode()
        room.find('**/nameProps').removeNode()
        room.find('**/spotlight').removeNode()
        room.setPos(5.5, 1.25, 0)
        room.setH(330)
        self.clarabelle.reparentTo(self.cRender)
        self.clarabelle.setPosHprScale(-0.52, 6.13, -3.81, 85, 0.0, 0.0, 1.0, 1.0, 1.0)
        self.clarabelleFrame.setPosHprScale(-0.01, 0.0, -0.01, 0.0, 0.0, 0.0, 1.02, 1.0, 1.02)

    def reload(self):
        for panel in self.panelList + self.backPanelList + self.loyaltyPanelList:
            panel.destroy()

        def priceSort(a, b, type):
            priceA = a.getPrice(type)
            priceB = b.getPrice(type)
            return priceB - priceA

        self.pageIndex = -1
        self.maxPageIndex = 0
        self.numNewPages = 0
        self.numBackPages = 5
        self.numLoyaltyPages = 0
        self.viewing = 'New'
        self.panelList = []
        self.backPanelList = []
        self.loyaltyList = []
        self.pageList = []
        self.backPageList = []
        self.loyaltyPanelList = []
        self.loyaltyPageList = []
        self.panelDict = {}
        self.visiblePanels = []
        itemList = base.localAvatar.monthlyCatalog + base.localAvatar.weeklyCatalog
        itemList.sort(lambda a, b: priceSort(a, b, CatalogItem.CatalogTypeWeekly))
        itemList.reverse()
        for item in itemList:
            if item.loyaltyRequirement() != 0:
                self.loyaltyPanelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeLoyalty, parentCatalogScreen=self))
            else:
                self.panelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeWeekly))

        itemList = base.localAvatar.backCatalog
        itemList.sort(lambda a, b: priceSort(a, b, CatalogItem.CatalogTypeBackorder))
        itemList.reverse()
        for item in itemList:
            if item.loyaltyRequirement() != 0:
                self.loyaltyPanelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeLoyalty, parentCatalogScreen=self))
            else:
                self.backPanelList.append(CatalogItemPanel.CatalogItemPanel(parent=hidden, item=item, type=CatalogItem.CatalogTypeBackorder))

        numPages = self.packPages(self.panelList, self.pageList, 'new')
        self.setNumNewPages(numPages)
        numPages = self.packPages(self.backPanelList, self.backPageList, 'back')
        self.setNumBackPages(numPages)
        numPages = self.packPages(self.loyaltyPanelList, self.loyaltyPageList, 'loyalty')
        self.setNumLoyaltyPages(numPages)
        seriesNumber = (base.localAvatar.catalogScheduleCurrentWeek - 1) / ToontownGlobals.CatalogNumWeeksPerSeries + 1
        self.catalogSeries['text'] = Localizer.CatalogSeriesLabel % seriesNumber
        weekNumber = (base.localAvatar.catalogScheduleCurrentWeek - 1) % ToontownGlobals.CatalogNumWeeksPerSeries + 1
        self.catalogNumber['text'] = '#%d' % weekNumber
        self.enableBackorderCatalogButton()
        self.setMaxPageIndex(self.numNewPages)
        self.setPageIndex(-1)
        self.showPageItems()

    def unload(self):
        taskMgr.remove('clearClarabelleChat')
        taskMgr.remove('postGoodbyeHangUp')
        taskMgr.remove('clarabelleGreeting')
        taskMgr.remove('clarabelleHelpText1')
        taskMgr.remove('clarabelleAskAnythingElse')
        if self.giftAvatar:
            base.cr.cancelAvatarDetailsRequest(self.giftAvatar)
        self.hide()
        self.hangup.hide()
        self.destroy()
        del self.base
        del self.squares
        for panel in self.panelList + self.backPanelList + self.loyaltyPanelList:
            panel.destroy()

        del self.panelList
        del self.backPanelList
        del self.cover
        del self.rings
        del self.clarabelleFrame
        del self.hangup
        del self.beanBank
        del self.nextPageButton
        del self.backPageButton
        del self.newCatalogButton
        del self.newCatalogButton2
        del self.backCatalogButton
        del self.backCatalogButton2
        del self.loyaltyCatalogButton
        del self.loyaltyCatalogButton2
        del self.pageLabel
        if self.createdGiftGui:
            del self.giftToggle
            del self.giftLabel
            del self.friendLabel
            del self.scrollList
        self.unloadClarabelle()
        if self.responseDialog:
            self.responseDialog.cleanup()
            self.responseDialog = None
        if self.giftAvatar:
            if hasattr(self.giftAvatar, 'doId'):
                self.giftAvatar.delete()
            else:
                self.giftAvatar = None
        return

    def unloadClarabelle(self):
        base.win.removeDisplayRegion(self.cDr)
        del self.cRender
        del self.cCamera
        del self.cCamNode
        del self.cLens
        del self.cCam
        del self.cDr
        self.clarabelle.cleanup()
        del self.clarabelle
        if self.clarabelleGreetingSfx:
            for sound in self.clarabelleGreetingSfx:
                del sound
            del self.clarabelleGreetingSfx
        if self.clarabelleGoodbyeSfx:
            for sound in self.clarabelleGoodbyeSfx:
                del sound
            del self.clarabelleGoodbyeSfx
        if self.clarabelleErrorSfx:
            for sound in self.clarabelleGoodbyeSfx:
                del sound
            del self.clarabelleGoodbyeSfx
        if self.clarabelleChatterSfx:
            for sound in self.clarabelleChatterSfx:
                del sound
            del self.clarabelleChatterSfx
        if self.clarabelleChatBalloon:
            self.clarabelleChatBalloon.removeNode()
            del self.clarabelleChatBalloon

    def hangUp(self):
        if hasattr(self, 'giftAvatar') and self.giftAvatar:
            self.giftAvatar.disable()
        self.setClarabelleChat(random.choice(TTLocalizer.CatalogGoodbyeList), type='goodbye')
        self.setPageIndex(-1)
        self.showPageItems()
        self.nextPageButton.hide()
        self.backPageButton.hide()
        self.newCatalogButton.hide()
        self.newCatalogButton2.hide()
        self.backCatalogButton.hide()
        self.backCatalogButton2.hide()
        self.loyaltyCatalogButton.hide()
        self.loyaltyCatalogButton2.hide()

        self.hangup.hide()
        taskMgr.remove('clarabelleGreeting')
        taskMgr.remove('clarabelleHelpText1')
        taskMgr.remove('clarabelleAskAnythingElse')

        def postGoodbyeHangUp(task):
            messenger.send(self['doneEvent'])
            self.unload()

        taskMgr.doMethodLater(1.5, postGoodbyeHangUp, 'postGoodbyeHangUp')

    def remoteUpdate(self):
        self.update()

    def update(self, lock = 0):
        if not hasattr(self.giftAvatar, 'doId'):
            if self.gifting == 1:
                self.__giftToggle()
        if hasattr(self, 'beanBank'):
            self.beanBank['text'] = str(base.localAvatar.getTotalMoney())
            if lock == 0:
                for item in self.panelList + self.backPanelList + self.loyaltyPanelList:
                    if type(item) != type(''):
                        item.updateButtons(self.gifting)

    def __handlePurchaseRequest(self, item):
        item.requestPurchase(self['phone'], self.__handlePurchaseResponse)
        taskMgr.remove('clarabelleAskAnythingElse')

    def __handleGiftPurchaseRequest(self, item):
        item.requestGiftPurchase(self['phone'], self.frienddoId, self.__handleGiftPurchaseResponse)
        taskMgr.remove('clarabelleAskAnythingElse')

    def __handlePurchaseResponse(self, retCode, item):
        if retCode == ToontownGlobals.P_UserCancelled:
            self.update()
            return
        self.setClarabelleChat(item.getRequestPurchaseErrorText(retCode), item.getRequestPurchaseErrorTextTimeout())

    def __handleGiftPurchaseResponse(self, retCode, item):
        if retCode == ToontownGlobals.P_UserCancelled:
            return
        if self.isEmpty() or self.isHidden():
            return
        self.setClarabelleChat(item.getRequestGiftPurchaseErrorText(retCode) % self.receiverName)
        self.__loadFriend()

        def askAnythingElse(task):
            self.setClarabelleChat(TTLocalizer.CatalogAnythingElse)

        if retCode >= 0:
            taskMgr.doMethodLater(8, askAnythingElse, 'clarabelleAskAnythingElse')

    def __clearDialog(self, event):
        self.responseDialog.cleanup()
        self.responseDialog = None
        return

    def setClarabelleChat(self, str, timeout = 6, type = None):
        self.clearClarabelleChat()
        if type == 'greeting':
            if not self.clarabelleGreetingSfx:
                clarabelleGreeting1 = base.loadSfx('phase_5.5/audio/dial/clarabelle_ah_1.ogg')
                clarabelleGreeting2 = base.loadSfx('phase_5.5/audio/dial/clarabelle_ah_2.ogg')
                self.clarabelleGreetingSfx = [clarabelleGreeting1, clarabelleGreeting2]
            base.playSfx(random.choice(self.clarabelleGreetingSfx))
        elif type == 'goodbye':
            if not self.clarabelleGoodbyeSfx:
                clarabelleGoodbye1 = base.loadSfx('phase_5.5/audio/dial/clarabelle_wa_1.ogg')
                clarabelleGoodbye2 = base.loadSfx('phase_5.5/audio/dial/clarabelle_wa_2.ogg')
                clarabelleGoodbye3 = base.loadSfx('phase_5.5/audio/dial/clarabelle_wa_3.ogg')
                clarabelleGoodbye4 = base.loadSfx('phase_5.5/audio/dial/clarabelle_wa_4.ogg')
                self.clarabelleGoodbyeSfx = [clarabelleGoodbye1, clarabelleGoodbye2, clarabelleGoodbye3, clarabelleGoodbye4]
            base.playSfx(random.choice(self.clarabelleGoodbyeSfx))
        elif type == 'error':
            if not self.clarabelleErrorSfx:
                clarabelleError1 = base.loadSfx('phase_5.5/audio/dial/clarabelle_ah_2.ogg')
                self.clarabelleChatterSfx = [clarabelleError1]
            base.playSfx(random.choice(self.clarabelleErrorSfx))
        else:
            if not self.clarabelleChatterSfx:
                clarabelleChatter1 = base.loadSfx('phase_5.5/audio/dial/clarabelle_ah_1.ogg')
                clarabelleChatter2 = base.loadSfx('phase_5.5/audio/dial/clarabelle_ah_2.ogg')
                clarabelleChatter3 = base.loadSfx('phase_5.5/audio/dial/clarabelle_gen_2.ogg')
                self.clarabelleChatterSfx = [clarabelleChatter1, clarabelleChatter2, clarabelleChatter3]
            base.playSfx(random.choice(self.clarabelleChatterSfx))
        if not self.clarabelleChatBalloon:
            self.clarabelleChatBalloon = loader.loadModel('phase_3/models/props/chatbox')
        
        self.clarabelleChat = CatalogChatBalloon.CatalogChatBalloon(self.clarabelleChatBalloon)
        chatNode = self.clarabelleChat.generate(str, ToontownGlobals.getInterfaceFont())[0]
        self.clarabelleChatNP = self.attachNewNode(chatNode.node(), 1000)
        self.clarabelleChatNP.setScale(0.08)
        self.clarabelleChatNP.setPos(0.7, 0, 0.6)
        
        if timeout:
            taskMgr.doMethodLater(timeout, self.clearClarabelleChat, 'clearClarabelleChat')

    def clearClarabelleChat(self, task = None):
        taskMgr.remove('clearClarabelleChat')
        if self.clarabelleChatNP:
            self.clarabelleChatNP.removeNode()
            self.clarabelleChatNP = None
            del self.clarabelleChat
        return

    def __moneyChange(self, money):
        if self.gifting > 0:
            self.update(1)
        else:
            self.update(0)

    def __bankMoneyChange(self, bankMoney):
        if self.gifting > 0:
            self.update(1)
        else:
            self.update(0)


    def checkFamily(self, doId):
        test = 0
        for familyMember in base.cr.avList:
            if familyMember.id == doId:
                test = 1

        return test

    def __makeFFlist(self):
        for familyMember in base.cr.avList:
            if familyMember.id != base.localAvatar.doId:
                newFF = (familyMember.id, familyMember.name, NametagGlobals.CCNonPlayer)
                self.ffList.append(newFF)

        for friendPair in base.localAvatar.friendsList:
            friendId, flags = friendPair
            handle = base.cr.identifyFriend(friendId)
            if handle and not self.checkFamily(friendId):
                if hasattr(handle, 'getName'):
                    colorCode = NametagGlobals.CCSpeedChat
                    if flags & ToontownGlobals.FriendChat:
                        colorCode = NametagGlobals.CCFreeChat
                    newFF = (friendPair[0], handle.getName(), colorCode)
                    self.ffList.append(newFF)
                else:
                    self.notify.warning('Bad Handle for getName in makeFFlist')

        hasManager = hasattr(base.cr, 'playerFriendsManager')
        if hasManager:
            for avatarId in base.cr.playerFriendsManager.getAllOnlinePlayerAvatars():
                handle = base.cr.playerFriendsManager.getAvHandleFromId(avatarId)
                playerId = base.cr.playerFriendsManager.findPlayerIdFromAvId(avatarId)
                playerInfo = base.cr.playerFriendsManager.getFriendInfo(playerId)
                freeChat = playerInfo.understandableYesNo
                if handle and not self.checkFamily(avatarId):
                    if hasattr(handle, 'getName'):
                        colorCode = NametagGlobals.CCSpeedChat
                        if freeChat:
                            colorCode = NametagGlobals.CCFreeChat
                        newFF = (avatarId, handle.getName(), colorCode)
                        self.ffList.append(newFF)
                    else:
                        self.notify.warning('Bad Handle for getName in makeFFlist')

    def __makeScrollList(self):
        for ff in self.ffList:
            ffbutton = self.makeFamilyButton(ff[0], ff[1], ff[2])
            if ffbutton:
                self.scrollList.addItem(ffbutton, refresh=0)
                self.friends[ff] = ffbutton

        self.scrollList.refresh()

    def makeFamilyButton(self, familyId, familyName, colorCode):
        # fg = NametagGlobals.getNameFg(colorCode, PGButton.SInactive)
        return DirectButton(
            relief=None,
            text=familyName,
            text_scale=0.04,
            text_align=TextNode.ALeft,
            # text_fg=fg,
            text1_bg=self.textDownColor,
            text2_bg=self.textRolloverColor,
            text3_fg=self.textDisabledColor,
            textMayChange=0,
            command=self.__chooseFriend,
            extraArgs=[familyId, familyName]
            )

    def __chooseFriend(self, friendId, friendName):
        messenger.send('wakeup')
        self.frienddoId = friendId
        self.receiverName = friendName
        self.friendLabel['text'] = TTLocalizer.CatalogGiftTo % self.receiverName
        self.__loadFriend()

    def __loadFriend(self):
        if self.allowGetDetails == 0:
            CatalogScreen.notify.warning('smashing requests')
        if self.frienddoId and self.allowGetDetails:
            if self.giftAvatar:
                if hasattr(self.giftAvatar, 'doId'):
                    self.giftAvatar.disable()
                    self.giftAvatar.delete()
                self.giftAvatar = None
            self.giftAvatar = DistributedToon.DistributedToon(base.cr)
            self.giftAvatar.doId = self.frienddoId
            self.giftAvatar.forceAllowDelayDelete()
            self.giftAvatar.generate()
            base.cr.getAvatarDetails(self.giftAvatar, self.__handleAvatarDetails, 'DistributedToon')
            self.gotAvatar = 0
            self.allowGetDetails = 0
            self.scrollList['state'] = DGG.DISABLED
        return

    def __handleAvatarDetails(self, gotData, avatar, dclass):
        if self.giftAvatar.doId != avatar.doId or gotData == 0:
            CatalogScreen.notify.error('Get Gift Avatar Failed')
            self.gotAvatar = 0
            return
        else:
            self.gotAvatar = 1
            self.giftAvatar = avatar
            self.scrollList['state'] = DGG.NORMAL
        self.allowGetDetails = 1
        self.update()

    def __giftToggle(self):
        messenger.send('wakeup')
        FeatureComingSoonDialog.FeatureComingSoonDialog("Woah! That feature will is \n\1textShadow\1coming soon\2! Sorry about that!")
        '''
        if self.gifting == -1:
            self.gifting = 1
            self.giftLabel.show()
            self.friendLabel.show()
            self.scrollList.show()

            self.giftToggle['text'] = TTLocalizer.CatalogGiftToggleOn
            self.__loadFriend()
        else:
            self.gifting = -1
            self.giftLabel.hide()
            self.friendLabel.hide()
            self.scrollList.hide()

            self.giftToggle['text'] = TTLocalizer.CatalogGiftToggleOff
            self.update()
        '''
    def __handleUDack(self, caller = None):
        taskMgr.remove('ackTimeOut')
        if hasattr(self, 'giftToggle') and self.giftToggle:
            self.giftToggle['state'] = DGG.NORMAL
            self.giftToggle['text'] = TTLocalizer.CatalogGiftToggleOff

    def __handleNoAck(self, caller = None):
        if hasattr(self, 'giftToggle') and self.giftToggle:
            self.giftToggle['text'] = TTLocalizer.CatalogGiftToggleNoAck