from direct.gui.DirectGui import *
from panda3d.core import *
from direct.directnotify import DirectNotifyGlobal
from toontown.toonbase import ToontownGlobals
from toontown.toonbase import TTLocalizer
from direct.task import Task
from toontown.estate import GardenGlobals
from direct.interval.IntervalGlobal import *
from toontown.estate import SpecialsPhoto
USE_SCROLLING_BEAN_BOX = False
JELLY_BEAN_PICKER_HAS_EMPTY_BOX = False
CAN_CHANGE_BEAN_COLOR = True
FORCE_LEFT_TO_RIGHT = True
ONLY_ONE_SPIFFY_BOX_CAN_BE_CLICKED = True
DO_PICKER_INTERVAL = False
PICKER_ALWAYS_UP = True

def loadJellyBean(parent, beanIndex):
    gui = loader.loadModel('phase_5.5/models/estate/jellyBean')
    newBean = gui.instanceTo(parent)
    parent.setScale(0.09)
    colors = GardenGlobals.BeanColors[beanIndex]
    parent.setColorScale(colors[0] / 255.0 * 1.0, colors[1] / 255.0 * 1.0, colors[2] / 255.0 * 1.0, 1)


class GenericBoxScrollList(DirectScrolledList):

    def __init__(self, parent, items, **kw):
        gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui')
        self.forceHeight = 1
        optiondefs = (('parent', parent, None),
         ('relief', None, None),
         ('incButton_image', (gui.find('**/FndsLst_ScrollUp'),
           gui.find('**/FndsLst_ScrollDN'),
           gui.find('**/FndsLst_ScrollUp_Rllvr'),
           gui.find('**/FndsLst_ScrollUp')), None),
         ('incButton_relief', None, None),
         ('incButton_scale', (1.3, 1.3, -1.3), None),
         ('incButton_pos', (0, 0, -0.525), None),
         ('incButton_image3_color', Vec4(0.8, 0.8, 0.8, 0.5), None),
         ('decButton_image', (gui.find('**/FndsLst_ScrollUp'),
           gui.find('**/FndsLst_ScrollDN'),
           gui.find('**/FndsLst_ScrollUp_Rllvr'),
           gui.find('**/FndsLst_ScrollUp')), None),
         ('decButton_relief', None, None),
         ('decButton_scale', (1.3, 1.3, 1.3), None),
         ('decButton_pos', (0, 0, 0.525), None),
         ('decButton_image3_color', Vec4(0.8, 0.8, 0.8, 0.5), None),
         ('numItemsVisible', 1, None),
         ('items', items, None),
         ('scrollSpeed', 1.0, None),
         ('forceHeight', 1, None))
        gui.removeNode()
        self.defineoptions(kw, optiondefs)
        DirectScrolledList.__init__(self, parent, forceHeight=self.forceHeight)
        self.initialiseoptions(GenericBoxScrollList)
        return None


class BoxItem(NodePath):

    def getHeight(self):
        return 0.05


JellyBeanPickerEndPos = (0, 0, 0.1)
JellyBeanPickerScale = (1.1, 1.0, 0.13)
if JELLY_BEAN_PICKER_HAS_EMPTY_BOX:
    JellyBeanPickerGeomScale = (1.0, 1.0, 1.0)
else:
    JellyBeanPickerGeomScale = (0.9, 1.0, 1.0)
JellyBeanPickerScaleInverse = (1.0 / JellyBeanPickerScale[0], 1.0 / JellyBeanPickerScale[1], 1.0 / JellyBeanPickerScale[2])

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

    def __init__(self, parent, callBack, boxPosition, **kw):
        self.index = 0
        self.selectedIndex = 0
        self.callBack = callBack
        self.boxPosition = boxPosition
        DirectFrame.__init__(self, relief=None, state='normal', geom=DGG.getDefaultDialogGeom(), geom_color=(0.8, 0.8, 0.8, 1.0), geom_scale=JellyBeanPickerGeomScale, scale=JellyBeanPickerScale, frameSize=(-1, 1, -1, 1), pos=(0, 0, 0))
        self.initialiseoptions(JellyBeanPicker)
        self.jellyBeanBoxList = []
        self.createJellyBeanBoxes()
        return

    def jellyBeanBoxClicked(self, beanIndex):
        if JELLY_BEAN_PICKER_HAS_EMPTY_BOX:
            self.callBack(self.boxPosition, beanIndex)
        else:
            self.callBack(self.boxPosition, beanIndex + 1)

    def createJellyBeanBox(self, beanIndex, xPos, zPos):
        geomColor = (1, 1, 1, 1)
        state = DGG.NORMAL
        command = self.jellyBeanBoxClicked
        newBox = DirectButton(parent=self, pos=(xPos, 0, zPos), geom=DGG.getDefaultDialogGeom(), geom_scale=(0.1, 1.0, 0.1), geom_color=geomColor, scale=JellyBeanPickerScaleInverse, relief=None, state=state, command=command, extraArgs=[beanIndex], text='', text_pos=(0.0, 0.1), text_scale=0.07, text_fg=Vec4(0, 0, 0, 0), text1_fg=Vec4(0, 0, 0, 0), text2_fg=Vec4(0, 0, 0, 1), text3_fg=Vec4(0, 0, 0, 0))
        if JELLY_BEAN_PICKER_HAS_EMPTY_BOX:
            if beanIndex:
                beanParent = newBox.attachNewNode('bean_%d' % (beanIndex - 1))
                loadJellyBean(beanParent, beanIndex - 1)
        else:
            beanParent = newBox.attachNewNode('bean_%d' % beanIndex)
            loadJellyBean(beanParent, beanIndex)
        self.jellyBeanBoxList.append(newBox)
        return

    def setColorText(self):
        for beanIndex in xrange(len(self.jellyBeanBoxList)):
            if JELLY_BEAN_PICKER_HAS_EMPTY_BOX:
                if beanIndex:
                    box = self.jellyBeanBoxList[beanIndex]
                    box['text'] = TTLocalizer.BeanColorWords[beanIndex - 1]
            else:
                box = self.jellyBeanBoxList[beanIndex]
                box['text'] = TTLocalizer.BeanColorWords[beanIndex]

    def createJellyBeanBoxes(self):
        zCoord = 0
        xIncrement = 0.095
        xPos = 0
        maxBoxes = len(GardenGlobals.BeanColors)
        if JELLY_BEAN_PICKER_HAS_EMPTY_BOX:
            maxBoxes += 1
        startingXCoord = -0.1 * float(maxBoxes) / 2.0 + 0.075
        for activeBox in xrange(maxBoxes):
            xPos = xIncrement * activeBox + startingXCoord
            self.createJellyBeanBox(activeBox, xPos, zCoord)


class SpiffyBeanBox(DirectButton):

    def __init__(self, parent, index, **kw):
        self.boxIndex = index
        self.selectedIndex = 0
        optiondefs = ()
        self.defineoptions(kw, optiondefs)
        DirectButton.__init__(self, parent=parent)
        self.initialiseoptions(SpiffyBeanBox)
        self.selectedBean = self.attachNewNode('selectedBean')

    def getSelectedIndex(self):
        if hasattr(self, 'selectedIndex'):
            return self.selectedIndex
        return 0

    def setSelectedIndex(self, newIndex):
        self.selectedIndex = newIndex
        self.selectedBean.removeNode()
        self.selectedBean = self.attachNewNode('selectedBean')
        if newIndex:
            newIndex -= 1
            loadJellyBean(self.selectedBean, newIndex)


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

    def __init__(self, doneEvent, specialBoxActive = False):
        if specialBoxActive:
            instructions = TTLocalizer.GardeningChooseBeansItem
            instructionsPos = (0, 0.4)
        else:
            instructions = TTLocalizer.GardeningChooseBeans
            instructionsPos = (0, 0.35)
        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=20, text_scale=0.08, text_pos=instructionsPos)
        self.initialiseoptions(PlantingGUI)
        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'))
        resetImageList = (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.__doPlant)
        self.resetButton = DirectButton(parent=self, relief=None, image=resetImageList, pos=(0.0, 0, -0.35), text=TTLocalizer.PlantingGuiReset, text_scale=0.06, text_pos=(0, -0.1), command=self.__reset)
        buttons.removeNode()
        self.availableBoxes = base.localAvatar.getBoxCapability()
        self.maxBoxes = GardenGlobals.getNumberOfShovelBoxes()
        self.activeBoxesList = []
        self.specialBox = None
        self.specialBoxActive = specialBoxActive
        self.boxList = []
        self.jellyBeanPicker = None
        self.jellyBeanPickerInterval = None
        self.createBoxes()
        guiItems = loader.loadModel('phase_5.5/models/gui/catalog_gui')
        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(), pos=(-0.85, 0, 0.2), scale=0.5)
        self.matchBoxesToAvailableMoney()
        if PICKER_ALWAYS_UP:
            self.spiffyBeanBoxClicked(0)
        return

    def destroy(self):
        if self.boxList:
            for box in self.boxList:
                box.destroy()

        self.boxList = []
        DirectFrame.destroy(self)
        self.doneEvent = None
        if self.jellyBeanPickerInterval:
            self.jellyBeanPickerInterval.finish()
        self.jellyBeanPickerInterval = None
        if self.jellyBeanPicker:
            self.jellyBeanPicker.destroy()
        self.jellyBeanPicker = None
        if hasattr(self, 'specialPhotoList') and self.specialPhotoList:
            for photo in self.specialPhotoList:
                photo.destroy()

            self.specialPhotoList = []
        return

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

    def __reset(self):
        if self.jellyBeanPicker:
            self.jellyBeanPicker.destroy()
        for box in self.boxList:
            box.setSelectedIndex(0)

        self.beanBank['text'] = str(base.localAvatar.getMoney() + base.localAvatar.getBankMoney())
        self.matchBoxesToAvailableMoney()
        if PICKER_ALWAYS_UP:
            self.spiffyBeanBoxClicked(0)
        messenger.send('wakeup')

    def getRecipeStr(self):
        retval = ''
        for box in self.boxList:
            beanIndex = box.getSelectedIndex()
            if beanIndex:
                beanIndex -= 1
                beanLetter = GardenGlobals.BeanColorLetters[beanIndex]
                retval += beanLetter

        return retval

    def __doPlant(self):
        recipeStr = self.getRecipeStr()
        selectedSpecial = self.specialButton.getSelectedIndex()
        selectedSpecial -= 1
        messenger.send(self.doneEvent, [1, recipeStr, selectedSpecial])
        messenger.send('wakeup')

    def createBoxes(self):
        zCoord = -0.15
        xIncrement = 0.1
        xPos = 0
        startingXCoord = -0.1 * float(self.maxBoxes) / 2.0 + 0.05
        for activeBox in xrange(self.availableBoxes):
            xPos = xIncrement * activeBox + startingXCoord
            if USE_SCROLLING_BEAN_BOX:
                self.createScrollingBeanBox(activeBox, xPos, zCoord, True)
            else:
                self.createSpiffyBeanBox(activeBox, xPos, zCoord, True)

        for disabledBox in xrange(self.availableBoxes, self.maxBoxes):
            xPos = xIncrement * disabledBox + startingXCoord
            if USE_SCROLLING_BEAN_BOX:
                self.createScrollingBeanBox(disabledBox, xPos, zCoord, False)
            else:
                self.createSpiffyBeanBox(disabledBox, xPos, zCoord, False)

        xPos += xIncrement * 2
        self.createSpecialBox(xPos, zCoord)

    def createSpecialBox(self, xPos, zPos):
        geomColor = (1, 1, 1, 1)
        if not self.specialBoxActive:
            geomColor = (0.5, 0.5, 0.5, 1)
        geomScaleX = 0.2
        geomScaleZ = 0.2
        self.specialButtonFrame = DirectFrame(parent=self, pos=(xPos, 0, zPos), geom=DGG.getDefaultDialogGeom(), geom_scale=(geomScaleX, 1.0, geomScaleZ), geom_color=geomColor, relief=None)
        items = []
        if self.specialBoxActive:
            gardenSpecials = base.localAvatar.getGardenSpecials()
            tempItem = BoxItem(self.attachNewNode('blankSpecial'))
            items.append(tempItem)
            self.specialPhotoList = []
            for item in gardenSpecials:
                tempItem = BoxItem(self.specialButtonFrame.attachNewNode('temp1'))
                specialsPhoto = SpecialsPhoto.SpecialsPhoto(item[0], parent=tempItem)
                specialsPhoto.setBackBounds(-geomScaleX / 2.0, geomScaleX / 2.0, -geomScaleZ / 2.0, geomScaleZ / 2.0)
                specialsPhoto.setBackColor(1.0, 1.0, 1.0, 1.0)
                items.append(tempItem)
                self.specialPhotoList.append(specialsPhoto)

        self.specialButton = GenericBoxScrollList(self.specialButtonFrame, items, incButton_pos=(0, 0, -0.135), incButton_scale=(0.75, 1.0, -1.0), decButton_pos=(0, 0, 0.135), decButton_scale=(0.75, 1.0, 1.0), command=self.photoSpecialChanged)
        return

    def photoSpecialChanged(self):
        if not hasattr(self, 'specialButton'):
            return
        messenger.send('wakeup')
        selectedSpecial = self.specialButton.getSelectedIndex()
        if selectedSpecial == 0:
            for photo in self.specialPhotoList:
                photo.hide()

        else:
            selectedSpecial -= 1
            self.specialPhotoList[selectedSpecial].show()

    def showFirstSpecial(self):
        if len(self.specialButton['items']) > 1:
            self.specialButton.scrollTo(self.specialButton.getSelectedIndex() + 1)

    def createScrollingBeanBox(self, index, xPos, zPos, active):
        geomColor = (1, 1, 1, 1)
        if not active:
            geomColor = (0.5, 0.5, 0.5, 1)
        boxFrame = DirectFrame(parent=self, pos=(xPos, 0, zPos), geom=DGG.getDefaultDialogGeom(), geom_scale=(0.1, 1.0, 0.1), geom_color=geomColor, relief=None)
        items = []
        if active:
            tempItem = BoxItem(self.attachNewNode('emptyBean'))
            items.append(tempItem)
            for curBean in xrange(len(GardenGlobals.BeanColors)):
                tempItem = BoxItem(self.attachNewNode('bean-%d-%d' % (index, curBean)))
                loadJellyBean(tempItem, curBean)
                items.append(tempItem)

        box = GenericBoxScrollList(boxFrame, items, incButton_pos=(0, 0, -0.07), incButton_scale=(0.4, 1.0, -1.0), decButton_pos=(0, 0, 0.065), decButton_scale=(0.4, 1.0, 1.0))
        self.boxList.append(box)
        return

    def spiffyBeanBoxClicked(self, index):
        if self.jellyBeanPicker:
            self.jellyBeanPicker.destroy()
        outOfMoney = int(self.beanBank['text']) <= 0
        if self.boxList[index].getSelectedIndex() == 0 and outOfMoney:
            return
        if not CAN_CHANGE_BEAN_COLOR and self.boxList[index].getSelectedIndex():
            return
        self.jellyBeanPicker = JellyBeanPicker(self, self.selectedNewBeanColor, index)
        self.jellyBeanPicker.setPos(*JellyBeanPickerEndPos)
        if DO_PICKER_INTERVAL:
            boxPos = self.boxList[index].getPos()
            self.jellyBeanPicker.setPos(boxPos)
            self.jellyBeanPickerInterval = Sequence(Parallel(self.jellyBeanPicker.posInterval(duration=0.3, pos=VBase3(*JellyBeanPickerEndPos)), self.jellyBeanPicker.scaleInterval(duration=0.3, startScale=VBase3(JellyBeanPickerScale[0] / 10.0, JellyBeanPickerScale[1], JellyBeanPickerScale[2]), scale=VBase3(*JellyBeanPickerScale))), Func(self.jellyBeanPicker.setColorText))
            self.jellyBeanPickerInterval.start()
        else:
            self.jellyBeanPicker.setColorText()

    def matchBoxesToAvailableMoney(self):
        outOfMoney = int(self.beanBank['text']) <= 0
        if outOfMoney:
            for box in self.boxList:
                if box.getSelectedIndex() == 0:
                    box['state'] = DGG.DISABLED
                    box.setState()
                    box.setColorScale(0.5, 0.5, 0.5, 1)

        else:
            for box in self.boxList:
                box['state'] = DGG.NORMAL
                box.setState()
                box.setColorScale(1, 1, 1, 1)

        if FORCE_LEFT_TO_RIGHT:
            boxIndexToEnable = len(self.getRecipeStr())
            for i in xrange(0, boxIndexToEnable):
                box = self.boxList[i]
                if ONLY_ONE_SPIFFY_BOX_CAN_BE_CLICKED:
                    box['state'] = DGG.DISABLED
                    box.setState()
                    box.setColorScale(0.875, 0.875, 0.875, 1)

            if boxIndexToEnable < self.maxBoxes:
                box = self.boxList[boxIndexToEnable]
                if boxIndexToEnable >= self.availableBoxes:
                    box['state'] = DGG.DISABLED
                    box.setState()
                    box.setColorScale(0.5, 0.5, 0.5, 1)
            for i in xrange(boxIndexToEnable + 1, len(self.boxList)):
                box = self.boxList[i]
                box['state'] = DGG.DISABLED
                box.setState()
                box.setColorScale(0.5, 0.5, 0.5, 1)

    def selectedNewBeanColor(self, boxPosition, beanIndex):
        self.boxList[boxPosition].setSelectedIndex(beanIndex)
        if self.jellyBeanPicker:
            self.jellyBeanPicker.destroy()
            self.jellyBeanPicker = None
        cost = len(self.getRecipeStr())
        newMoney = base.localAvatar.getMoney() + base.localAvatar.getBankMoney() - cost
        self.beanBank['text'] = str(newMoney)
        self.matchBoxesToAvailableMoney()
        messenger.send('wakeup')
        if PICKER_ALWAYS_UP:
            numBoxesFilled = len(self.getRecipeStr())
            if numBoxesFilled < self.availableBoxes:
                self.spiffyBeanBoxClicked(numBoxesFilled)
        return

    def createSpiffyBeanBox(self, index, xPos, zPos, active):
        geomColor = (1, 1, 1, 1)
        state = DGG.NORMAL
        command = self.spiffyBeanBoxClicked
        if not active:
            geomColor = (0.5, 0.5, 0.5, 1)
            command = None
            state = DGG.DISABLED
        newBox = SpiffyBeanBox(index=index, parent=self, pos=(xPos, 0, zPos), geom=DGG.getDefaultDialogGeom(), geom_scale=(0.1, 1.0, 0.1), geom_color=geomColor, relief=None, state=state, command=command, extraArgs=[index])
        self.boxList.append(newBox)
        return
