from direct.distributed.DistributedObject import DistributedObject
from direct.distributed.DistributedObjectGlobal import DistributedObjectGlobal

from toontown.chat.ChatGlobals import *
from toontown.parties import PartyGlobals
from toontown.toon import ToonDNA
from toontown.toonbase import TTLocalizer
from toontown.toonbase import ToontownGlobals


class DistributedPartyManager(DistributedObject):
    neverDisable = 1
    notify = directNotify.newCategory('DistributedPartyManager')
    PartyStatusChangedEvent = 'changePartyStatusResponseReceived'

    def __init__(self, cr):
        DistributedObject.__init__(self, cr)
        base.cr.partyManager = self
        self.allowUnreleased = False
        self.partyPlannerStyle = None
        self.partyPlannerName = None
        self.showDoid = False
        return

    def delete(self):
        DistributedObject.delete(self)
        self.cr.partyManager = None
        return

    def disable(self):
        self.notify.debug("i'm disabling DistributedPartyManager rightnow.")
        self.ignore('deallocateZoneIdFromPlannedParty')
        self.ignoreAll()
        DistributedObject.disable(self)

    def generate(self):
        self.notify.debug('BASE: generate')
        DistributedObject.generate(self)
        self.accept('deallocateZoneIdFromPlannedParty', self.deallocateZoneIdFromPlannedParty)
        self.announceGenerateName = self.uniqueName('generate')

    def deallocateZoneIdFromPlannedParty(self, zoneId):
        self.sendUpdate('freeZoneIdFromPlannedParty', [base.localAvatar.doId, zoneId])

    def allowUnreleasedClient(self):
        return self.allowUnreleased

    def setAllowUnreleaseClient(self, newValue):
        self.allowUnreleased = newValue

    def toggleAllowUnreleasedClient(self):
        self.allowUnreleased = not self.allowUnreleased
        return self.allowUnreleased

    def sendAddParty(self, hostId, startTime, endTime, isPrivate, inviteTheme, activities, decorations, inviteeIds):
        self.sendUpdate('addPartyRequest', [hostId,
         startTime,
         endTime,
         isPrivate,
         inviteTheme,
         activities,
         decorations,
         inviteeIds])

    def addPartyResponse(self, hostId, errorCode):
        messenger.send('addPartyResponseReceived', [hostId, errorCode])
        if hasattr(base.localAvatar, 'creatingNewPartyWithMagicWord'):
            if base.localAvatar.creatingNewPartyWithMagicWord:
                base.localAvatar.creatingNewPartyWithMagicWord = False
                if errorCode == PartyGlobals.AddPartyErrorCode.AllOk:
                    base.localAvatar.setChatAbsolute('New party entered into database successfully.', CFSpeech | CFTimeout)
                else:
                    base.localAvatar.setChatAbsolute('New party creation failed : %s' % PartyGlobals.AddPartyErrorCode.getString(errorCode), CFSpeech | CFTimeout)

    def requestPartyZone(self, avId, zoneId, callback):
        if zoneId < 0:
            zoneId = 0
        self.acceptOnce('requestPartyZoneComplete', callback)
        if hasattr(base.localAvatar, 'aboutToPlanParty'):
            if base.localAvatar.aboutToPlanParty:
                self.sendUpdate('getPartyZone', [avId, zoneId, True])
                return
        self.sendUpdate('getPartyZone', [avId, zoneId, False])

    def receivePartyZone(self, hostId, partyId, zoneId):
        if partyId != 0 and zoneId != 0:
            if base.localAvatar.doId == hostId:
                for partyInfo in base.localAvatar.hostedParties:
                    if partyInfo.partyId == partyId:
                        partyInfo.status == PartyGlobals.PartyStatus.Started

        messenger.send('requestPartyZoneComplete', [hostId, partyId, zoneId])

    def sendChangePrivateRequest(self, partyId, newPrivateStatus):
        self.sendUpdate('changePrivateRequest', [partyId, newPrivateStatus])

    def changePrivateResponse(self, partyId, newPrivateStatus, errorCode):
        if errorCode == PartyGlobals.ChangePartyFieldErrorCode.AllOk:
            self.notify.info('succesfully changed private field for the party')
            for partyInfo in localAvatar.hostedParties:
                if partyInfo.partyId == partyId:
                    partyInfo.isPrivate = newPrivateStatus

            messenger.send('changePartyPrivateResponseReceived', [partyId, newPrivateStatus, errorCode])
        else:
            messenger.send('changePartyPrivateResponseReceived', [partyId, newPrivateStatus, errorCode])
            self.notify.info('FAILED changing private field for the party')

    def sendChangePartyStatusRequest(self, partyId, newPartyStatus):
        self.sendUpdate('changePartyStatusRequest', [partyId, newPartyStatus])

    def changePartyStatusResponse(self, partyId, newPartyStatus, errorCode, beansRefunded):
        self.notify.debug('changePartyStatusResponse : partyId=%s newPartyStatus=%s errorCode=%s' % (partyId, newPartyStatus, errorCode))
        for partyInfo in localAvatar.hostedParties:
            if partyInfo.partyId == partyId:
                partyInfo.status = newPartyStatus

        messenger.send(self.PartyStatusChangedEvent, [partyId,
         newPartyStatus,
         errorCode,
         beansRefunded])

    def setNeverStartedPartyRefunded(self, partyId, newStatus, refund):
        partyInfo = None
        for pInfo in localAvatar.hostedParties:
            if pInfo.partyId == partyId:
                partyInfo = pInfo
                break

        if partyInfo:
            partyInfo.status = newStatus
            messenger.send(self.PartyStatusChangedEvent, [partyId,
             newStatus,
             0,
             refund])
        return

    def sendAvToPlayground(self, avId, retCode):
        messenger.send(PartyGlobals.KICK_TO_PLAYGROUND_EVENT, [retCode])
        self.notify.debug('sendAvToPlayground: %d' % avId)

    def leaveParty(self):
        if self.isDisabled():
            self.notify.warning('DistributedPartyManager disabled; unable to leave party.')
            return
        self.sendUpdate('exitParty', [localAvatar.zoneId])

    def removeGuest(self, ownerId, avId):
        self.notify.debug('removeGuest ownerId = %s, avId = %s' % (ownerId, avId))
        self.sendUpdate('removeGuest', [ownerId, avId])

    def isToonAllowedAtParty(self, avId, partyId):
        return PartyGlobals.GoToPartyStatus.AllowedToGo

    def getGoToPartyFailedMessage(self, reason):
        return ''

    def sendAvatarToParty(self, hostId):
        DistributedPartyManager.notify.debug('sendAvatarToParty hostId = %s' % hostId)
        self.sendUpdate('requestShardIdZoneIdForHostId', [hostId])

    def sendShardIdZoneIdToAvatar(self, shardId, zoneId):
        DistributedPartyManager.notify.debug('sendShardIdZoneIdToAvatar shardId = %s  zoneId = %s' % (shardId, zoneId))
        if shardId == 0 or zoneId == 0:
            base.cr.playGame.getPlace().handleBookClose()
            return
        hoodId = ToontownGlobals.PartyHood
        if shardId == base.localAvatar.defaultShard:
            shardId = None
        base.cr.playGame.getPlace().requestLeave({'loader': 'safeZoneLoader',
         'where': 'party',
         'how': 'teleportIn',
         'hoodId': hoodId,
         'zoneId': zoneId,
         'shardId': shardId,
         'avId': -1})
        return

    def setPartyPlannerStyle(self, dna):
        self.partyPlannerStyle = dna

    def getPartyPlannerStyle(self):
        if self.partyPlannerStyle:
            return self.partyPlannerStyle
        else:
            dna = ToonDNA.ToonDNA()
            dna.newToonRandom()
            return dna

    def setPartyPlannerName(self, name):
        self.partyPlannerName = name

    def getPartyPlannerName(self):
        if self.partyPlannerName:
            return self.partyPlannerName
        else:
            return TTLocalizer.PartyPlannerGenericName

    def toggleShowDoid(self):
        self.showDoid = not self.showDoid
        return self.showDoid

    def getShowDoid(self):
        return self.showDoid