text: from direct.gui.DirectGui import *
  from pandac.PandaModules import *
  from toontown.toonbase.ToontownGlobals import *
  from toontown.toonbase.ToonBaseGlobal import *
  from pandac.PandaModules import *
  from direct.interval.IntervalGlobal import *
  from direct.distributed.ClockDelta import *
  from toontown.toonbase import ToontownGlobals
  from direct.showbase import DirectObject
  from toontown.toon import ToonDNA
  from direct.fsm import ClassicFSM, State, StateData
  from . import ClosetGUI
  from direct.task.Task import Task
  from . import ClosetGlobals
  from . import DistributedFurnitureItem
  from toontown.toonbase import TTLocalizer
  
  class DistributedCloset(DistributedFurnitureItem.DistributedFurnitureItem):
      notify = directNotify.newCategory('DistributedCloset')
  
      def __init__(self, cr):
          DistributedFurnitureItem.DistributedFurnitureItem.__init__(self, cr)
          self.notify.debug('__init__')
          self.lastAvId = 0
          self.hasLocalAvatar = 0
          self.lastTime = 0
          self.av = None
          self.closetGUI = None
          self.closetModel = None
          self.closetSphere = None
          self.closetSphereNode = None
          self.closetSphereNodePath = None
          self.topList = []
          self.botList = []
          self.oldTopList = []
          self.oldBotList = []
          self.oldStyle = None
          self.button = None
          self.topTrashButton = None
          self.bottomTrashButton = None
          self.isLocalToon = None
          self.popupInfo = None
          self.isOwner = 0
          self.ownerId = 0
          self.customerId = 0
          self.purchaseDoneEvent = ''
          self.swapEvent = ''
          self.locked = 0
          self.gender = None
          self.topDeleted = 0
          self.bottomDeleted = 0
          self.closetTrack = None
          self.avMoveTrack = None
          self.scale = 1.0
          self.fsm = ClassicFSM.ClassicFSM('Closet', [State.State('off', self.enterOff, self.exitOff, ['ready', 'open', 'closed']),
           State.State('ready', self.enterReady, self.exitReady, ['open', 'closed']),
           State.State('closed', self.enterClosed, self.exitClosed, ['open', 'off']),
           State.State('open', self.enterOpen, self.exitOpen, ['closed', 'off'])], 'off', 'off')
          self.fsm.enterInitialState()
          return
  
      def generate(self):
          DistributedFurnitureItem.DistributedFurnitureItem.generate(self)
  
      def announceGenerate(self):
          self.notify.debug('announceGenerate')
          DistributedFurnitureItem.DistributedFurnitureItem.announceGenerate(self)
          self.load()
          self.setupCollisionSphere()
          self.fsm.request('ready')
  
      def load(self):
          self.setTwoSided(1)
          lNode = self.find('**/door_rotate_L')
          lDoor = self.find('**/closetdoor_L')
          if lNode.isEmpty() or lDoor.isEmpty():
              self.leftDoor = None
          else:
              lDoor.wrtReparentTo(lNode)
              self.leftDoor = lNode
          rNode = self.find('**/door_rotate_R')
          rDoor = self.find('**/closetdoor_R')
          if rNode.isEmpty() or rDoor.isEmpty():
              self.rightDoor = None
          else:
              rDoor.wrtReparentTo(rNode)
              self.rightDoor = rNode
          if not lNode.isEmpty():
              self.scale = lNode.getScale()[0]
          return
  
      def setupCollisionSphere(self):
          if self.ownerId:
              self.closetSphereEvent = self.uniqueName('closetSphere')
              self.closetSphereEnterEvent = 'enter' + self.closetSphereEvent
              self.closetSphere = CollisionSphere(0, 0, 0, self.scale * 2.125)
              self.closetSphere.setTangible(0)
              self.closetSphereNode = CollisionNode(self.closetSphereEvent)
              self.closetSphereNode.setIntoCollideMask(WallBitmask)
              self.closetSphereNode.addSolid(self.closetSphere)
              self.closetSphereNodePath = self.attachNewNode(self.closetSphereNode)
  
      def disable(self):
          self.notify.debug('disable')
          self.ignore(self.closetSphereEnterEvent)
          self.ignoreAll()
          taskMgr.remove(self.uniqueName('popupChangeClothesGUI'))
          taskMgr.remove(self.uniqueName('lerpCamera'))
          taskMgr.remove(self.uniqueName('lerpToon'))
          if self.closetTrack:
              self.closetTrack.finish()
              self.closetTrack = None
          if self.closetGUI:
              self.closetGUI.resetClothes(self.oldStyle)
              self.resetCloset()
          if self.hasLocalAvatar:
              self.freeAvatar()
          self.ignoreAll()
          DistributedFurnitureItem.DistributedFurnitureItem.disable(self)
          return
  
      def delete(self):
          self.notify.debug('delete')
          DistributedFurnitureItem.DistributedFurnitureItem.delete(self)
          if self.popupInfo:
              self.popupInfo.destroy()
              self.popupInfo = None
          if self.av:
              del self.av
          del self.gender
          del self.closetSphere
          del self.closetSphereNode
          del self.closetSphereNodePath
          del self.closetGUI
          del self.fsm
          return
  
      def enterOff(self):
          pass
  
      def exitOff(self):
          pass
  
      def enterReady(self):
          if self.ownerId:
              self.accept(self.closetSphereEnterEvent, self.handleEnterSphere)
  
      def exitReady(self):
          pass
  
      def enterOpen(self):
          if self.ownerId:
              self.ignore(self.closetSphereEnterEvent)
              self._openDoors()
              if self.customerId == base.localAvatar.doId:
                  camera.wrtReparentTo(self)
                  camera.posQuatInterval(1, (-7.58, -6.02, 6.9), (286.3, 336.8, 0), other=self, blendType='easeOut').start()
                  camera.setPosHpr(self, -7.58, -6.02, 6.9, 286.3, 336.8, 0)
              if self.av:
                  if self.avMoveTrack:
                      self.avMoveTrack.finish()
                  self.av.stopSmooth()
                  self.avMoveTrack = Sequence(Parallel(Func(self.av.play, 'walk'), LerpPosHprInterval(nodePath=self.av, other=self, duration=1.0, pos=Vec3(1.67, -3.29, 0.025), hpr=Vec3(112, 0, 0), blendType='easeOut')), Func(self.av.loop, 'neutral'), Func(self.av.startSmooth))
                  self.avMoveTrack.start()
  
      def exitOpen(self):
          if self.ownerId:
              self._closeDoors()
  
      def enterClosed(self):
          if self.ownerId:
              self.accept(self.closetSphereEnterEvent, self.handleEnterSphere)
  
      def exitClosed(self):
          pass
  
      def handleEnterSphere(self, collEntry):
          if self.smoothStarted:
              return
          if base.localAvatar.doId == self.lastAvId and globalClock.getFrameTime() <= self.lastTime + 0.5:
              self.notify.info('Ignoring duplicate entry for avatar.')
              return
          if self.hasLocalAvatar:
              self.freeAvatar()
          self.notify.debug('Entering Closet Sphere....%s' % self.closetSphereEnterEvent)
          if self.cr.playGame.getPlace() == None:
              self.notify.info('Not opening closet before place is defined.')
              return
          self.ignore(self.closetSphereEnterEvent)
          if not self.locked:
              self.cr.playGame.getPlace().fsm.request('closet')
              self.accept('closetAsleep', self._handleCancel)
              self.sendUpdate('enterAvatar', [])
              self.hasLocalAvatar = 1
          return
  
      def setState(self, mode, avId, ownerId, gender, topList, botList):
          self.notify.debug('setState, mode=%s, avId=%s, ownerId=%d' % (mode, avId, ownerId))
          self.isOwner = avId == ownerId
          self.ownerGender = gender
          if mode == ClosetGlobals.CLOSED:
              self.fsm.request('closed')
              return
          elif mode == ClosetGlobals.OPEN:
              self.customerId = avId
              self.av = self.cr.doId2do.get(self.customerId, None)
              if self.av:
                  if base.localAvatar.getDoId() == self.customerId:
                      self.gender = self.av.style.gender
                      self.topList = topList
                      self.botList = botList
                      self.oldTopList = self.topList[0:]
                      self.oldBotList = self.botList[0:]
                      self.printInfo()
                      if not self.isOwner:
                          self.__popupNotOwnerPanel()
                      else:
                          taskMgr.doMethodLater(0.5, self.popupChangeClothesGUI, self.uniqueName('popupChangeClothesGUI'))
                  self.fsm.request('open')
          return
  
      def _revertGender(self):
          if self.gender:
              self.av.style.gender = self.gender
              self.av.loop('neutral')
  
      def popupChangeClothesGUI(self, task):
          self.notify.debug('popupChangeClothesGUI')
          self.purchaseDoneEvent = self.uniqueName('purchaseDone')
          self.swapEvent = self.uniqueName('swap')
          self.cancelEvent = self.uniqueName('cancel')
          self.accept(self.purchaseDoneEvent, self.__proceedToCheckout)
          self.accept(self.swapEvent, self.__handleSwap)
          self.accept(self.cancelEvent, self._handleCancel)
          self.deleteEvent = self.uniqueName('delete')
          if self.isOwner:
              self.accept(self.deleteEvent, self.__handleDelete)
          if not self.closetGUI:
              self.closetGUI = ClosetGUI.ClosetGUI(self.isOwner, self.purchaseDoneEvent, self.cancelEvent, self.swapEvent, self.deleteEvent, self.topList, self.botList)
              self.closetGUI.load()
              if self.gender != self.ownerGender:
                  self.closetGUI.setGender(self.ownerGender)
              self.closetGUI.enter(base.localAvatar)
              self.closetGUI.showButtons()
              style = self.av.getStyle()
              self.oldStyle = ToonDNA.ToonDNA()
              self.oldStyle.makeFromNetString(style.makeNetString())
          return Task.done
  
      def resetCloset(self):
          self.ignoreAll()
          taskMgr.remove(self.uniqueName('popupChangeClothesGUI'))
          taskMgr.remove(self.uniqueName('lerpCamera'))
          taskMgr.remove(self.uniqueName('lerpToon'))
          if self.closetGUI:
              self.closetGUI.hideButtons()
              self.closetGUI.exit()
              self.closetGUI.unload()
              self.closetGUI = None
              del self.av
          self.av = base.localAvatar
          style = self.av.getStyle()
          self.oldStyle = ToonDNA.ToonDNA()
          self.oldStyle.makeFromNetString(style.makeNetString())
          self.topDeleted = 0
          self.bottomDeleted = 0
          return Task.done
  
      def __handleButton(self):
          messenger.send('next')
  
      def _handleCancel(self):
          if self.oldStyle:
              self.d_setDNA(self.oldStyle.makeNetString(), 1)
          else:
              self.notify.info('avoided crash in handleCancel')
              self._handlePurchaseDone()
          if self.closetGUI:
              self.closetGUI.resetClothes(self.oldStyle)
          if self.popupInfo != None:
              self.popupInfo.destroy()
              self.popupInfo = None
          return
  
      def __handleSwap(self):
          self.d_setDNA(self.av.getStyle().makeNetString(), 0)
  
      def __handleDelete(self, t_or_b):
          if t_or_b == ClosetGlobals.SHIRT:
              itemList = self.closetGUI.tops
              trashIndex = self.closetGUI.topChoice
              swapFunc = self.closetGUI.swapTop
              removeFunc = self.closetGUI.removeTop
              self.topDeleted = self.topDeleted | 1
  
              def setItemChoice(i):
                  self.closetGUI.topChoice = i
  
          else:
              itemList = self.closetGUI.bottoms
              trashIndex = self.closetGUI.bottomChoice
              swapFunc = self.closetGUI.swapBottom
              removeFunc = self.closetGUI.removeBottom
              self.bottomDeleted = self.bottomDeleted | 1
  
              def setItemChoice(i):
                  self.closetGUI.bottomChoice = i
  
          if len(itemList) > 1:
              trashDNA = ToonDNA.ToonDNA()
              trashItem = self.av.getStyle().makeNetString()
              trashDNA.makeFromNetString(trashItem)
              if trashIndex == 0:
                  swapFunc(1)
              else:
                  swapFunc(-1)
              removeFunc(trashIndex)
              self.sendUpdate('removeItem', [trashItem, t_or_b])
              swapFunc(0)
              self.closetGUI.updateTrashButtons()
          else:
              self.notify.warning("cant delete this item(type = %s), since we don't have a replacement" % t_or_b)
  
      def resetItemLists(self):
          self.topList = self.oldTopList[0:]
          self.botList = self.oldBotList[0:]
          self.closetGUI.tops = self.topList
          self.closetGUI.bottoms = self.botList
          self.topDeleted = 0
          self.bottomDeleted = 0
  
      def __proceedToCheckout(self):
          if self.topDeleted or self.bottomDeleted:
              self.__popupAreYouSurePanel()
          else:
              self._handlePurchaseDone()
  
      def _handlePurchaseDone(self, timeout = 0):
          if timeout == 1:
              self.d_setDNA(self.oldStyle.makeNetString(), 1)
          else:
              which = 0
              if hasattr(self.closetGUI, 'topChoice') and hasattr(self.closetGUI, 'bottomChoice'):
                  if self.closetGUI.topChoice != 0 or self.topDeleted:
                      which = which | 1
                  if self.closetGUI.bottomChoice != 0 or self.bottomDeleted:
                      which = which | 2
              self.d_setDNA(self.av.getStyle().makeNetString(), 2, which)
  
      def d_setDNA(self, dnaString, finished, whichItems = 3):
          self.sendUpdate('setDNA', [dnaString, finished, whichItems])
  
      def setCustomerDNA(self, avId, dnaString):
          if avId and avId != base.localAvatar.doId:
              av = base.cr.doId2do.get(avId, None)
              if av:
                  if self.av == base.cr.doId2do[avId]:
                      oldTorso = self.av.style.torso
                      self.av.style.makeFromNetString(dnaString)
                      if len(oldTorso) == 2 and len(self.av.style.torso) == 2 and self.av.style.torso[1] != oldTorso[1]:
                          self.av.swapToonTorso(self.av.style.torso, genClothes=0)
                          self.av.loop('neutral', 0)
                      self.av.generateToonClothes()
          return
  
      def printInfo(self):
          print('avid: %s, gender: %s' % (self.av.doId, self.av.style.gender))
          print('current top = %s,%s,%s,%s and  bot = %s,%s,' % (self.av.style.topTex,
           self.av.style.topTexColor,
           self.av.style.sleeveTex,
           self.av.style.sleeveTexColor,
           self.av.style.botTex,
           self.av.style.botTexColor))
          print('topsList = %s' % self.av.getClothesTopsList())
          print('bottomsList = %s' % self.av.getClothesBottomsList())
  
      def setMovie(self, mode, avId, timestamp):
          self.isLocalToon = avId == base.localAvatar.doId
          if avId != 0:
              self.lastAvId = avId
          self.lastTime = globalClock.getFrameTime()
          if mode == ClosetGlobals.CLOSET_MOVIE_CLEAR:
              return
          elif mode == ClosetGlobals.CLOSET_MOVIE_COMPLETE:
              if self.isLocalToon:
                  self._revertGender()
                  self.printInfo()
                  self.resetCloset()
                  self.freeAvatar()
                  return
          elif mode == ClosetGlobals.CLOSET_MOVIE_TIMEOUT:
              taskMgr.remove(self.uniqueName('lerpCamera'))
              taskMgr.remove(self.uniqueName('lerpToon'))
              if self.isLocalToon:
                  self.ignore(self.purchaseDoneEvent)
                  self.ignore(self.swapEvent)
                  if self.closetGUI:
                      self.closetGUI.resetClothes(self.oldStyle)
                      self._handlePurchaseDone(timeout=1)
                      self.resetCloset()
                  self._popupTimeoutPanel()
                  self.freeAvatar()
  
      def freeAvatar(self):
          self.notify.debug('freeAvatar()')
          if self.hasLocalAvatar:
              base.localAvatar.posCamera(0, 0)
              place = base.cr.playGame.getPlace()
              if place:
                  place.setState('walk')
              self.ignore('closetAsleep')
              base.localAvatar.startLookAround()
              self.hasLocalAvatar = 0
          self.lastTime = globalClock.getFrameTime()
  
      def setOwnerId(self, avId):
          self.ownerId = avId
  
      def _popupTimeoutPanel(self):
          if self.popupInfo != None:
              self.popupInfo.destroy()
              self.popupInfo = None
          buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui')
          okButtonImage = (buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr'))
          self.popupInfo = DirectFrame(parent=hidden, relief=None, state='normal', text=TTLocalizer.ClosetTimeoutMessage, frameSize=(-1, 1, -1, 1), geom=DGG.getDefaultDialogGeom(), geom_color=ToontownGlobals.GlobalDialogColor, geom_scale=(0.88, 1, 0.45), geom_pos=(0, 0, -.08), text_scale=0.08)
          DirectButton(self.popupInfo, image=okButtonImage, relief=None, text=TTLocalizer.ClosetPopupOK, text_scale=0.05, text_pos=(0.0, -0.1), textMayChange=0, pos=(0.0, 0.0, -0.16), command=self.__handleTimeoutMessageOK)
          buttons.removeNode()
          self.popupInfo.reparentTo(aspect2d)
          return
  
      def __handleTimeoutMessageOK(self):
          self.popupInfo.reparentTo(hidden)
  
      def __popupNotOwnerPanel(self):
          if self.popupInfo != None:
              self.popupInfo.destroy()
              self.popupInfo = None
          self.purchaseDoneEvent = self.uniqueName('purchaseDone')
          self.swapEvent = self.uniqueName('swap')
          self.cancelEvent = self.uniqueName('cancel')
          self.accept(self.purchaseDoneEvent, self.__proceedToCheckout)
          self.accept(self.swapEvent, self.__handleSwap)
          self.accept(self.cancelEvent, self._handleCancel)
          self.deleteEvent = self.uniqueName('delete')
          if self.isOwner:
              self.accept(self.deleteEvent, self.__handleDelete)
          buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui')
          okButtonImage = (buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr'))
          self.popupInfo = DirectFrame(parent=hidden, relief=None, state='normal', text=TTLocalizer.ClosetNotOwnerMessage, frameSize=(-1, 1, -1, 1), text_wordwrap=10, geom=DGG.getDefaultDialogGeom(), geom_color=ToontownGlobals.GlobalDialogColor, geom_scale=(0.88, 1, 0.55), geom_pos=(0, 0, -.08), text_scale=0.08, text_pos=(0, 0.06))
          DirectButton(self.popupInfo, image=okButtonImage, relief=None, text=TTLocalizer.ClosetPopupOK, text_scale=0.05, text_pos=(0.0, -0.1), textMayChange=0, pos=(0.0, 0.0, -0.21), command=self._handleNotOwnerMessageOK)
          buttons.removeNode()
          self.popupInfo.reparentTo(aspect2d)
          return
  
      def _handleNotOwnerMessageOK(self):
          self.popupInfo.reparentTo(hidden)
          taskMgr.doMethodLater(0.1, self.popupChangeClothesGUI, self.uniqueName('popupChangeClothesGUI'))
  
      def __popupAreYouSurePanel(self):
          if self.popupInfo != None:
              self.popupInfo.destroy()
              self.popupInfo = None
          buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui')
          okButtonImage = (buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr'))
          cancelButtonImage = (buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr'))
          self.popupInfo = DirectFrame(parent=hidden, relief=None, state='normal', text=TTLocalizer.ClosetAreYouSureMessage, frameSize=(-1, 1, -1, 1), text_wordwrap=10, geom=DGG.getDefaultDialogGeom(), geom_color=ToontownGlobals.GlobalDialogColor, geom_scale=(0.88, 1, 0.55), geom_pos=(0, 0, -.08), text_scale=0.08, text_pos=(0, 0.08))
          DirectButton(self.popupInfo, image=okButtonImage, relief=None, text=TTLocalizer.ClosetPopupOK, text_scale=0.05, text_pos=(0.0, -0.1), textMayChange=0, pos=(-0.1, 0.0, -0.21), command=self._handleYesImSure)
          DirectButton(self.popupInfo, image=cancelButtonImage, relief=None, text=TTLocalizer.ClosetPopupCancel, text_scale=0.05, text_pos=(0.0, -0.1), textMayChange=0, pos=(0.1, 0.0, -0.21), command=self._handleNotSure)
          buttons.removeNode()
          self.popupInfo.reparentTo(aspect2d)
          return
  
      def _handleYesImSure(self):
          self.popupInfo.reparentTo(hidden)
          self._handlePurchaseDone()
  
      def _handleNotSure(self):
          self.popupInfo.reparentTo(hidden)
  
      def _openDoors(self):
          if self.closetTrack:
              self.closetTrack.finish()
          leftHpr = Vec3(-110, 0, 0)
          rightHpr = Vec3(110, 0, 0)
          self.closetTrack = Parallel()
          if self.rightDoor:
              self.closetTrack.append(self.rightDoor.hprInterval(0.5, rightHpr))
          if self.leftDoor:
              self.closetTrack.append(self.leftDoor.hprInterval(0.5, leftHpr))
          self.closetTrack.start()
  
      def _closeDoors(self):
          if self.closetTrack:
              self.closetTrack.finish()
          leftHpr = Vec3(0, 0, 0)
          rightHpr = Vec3(0, 0, 0)
          self.closetTrack = Parallel()
          if self.rightDoor:
              self.closetTrack.append(self.rightDoor.hprInterval(0.5, rightHpr))
          if self.leftDoor:
              self.closetTrack.append(self.leftDoor.hprInterval(0.5, leftHpr))
          self.closetTrack.start()
  