"""Undocumented Module"""

__all__ = ['DirectRadioButton']

from pandac.PandaModules import *
import DirectGuiGlobals as DGG
from DirectButton import *
from DirectLabel import *

class DirectRadioButton(DirectButton):
    """
    DirectRadioButton(parent) - Create a DirectGuiWidget which responds
    to mouse clicks by setting given value to given variable and
    execute a callback function (passing that state through) if defined
    """
    def __init__(self, parent = None, **kw):
        # Inherits from DirectButton
        # A Direct Frame can have:
        # - A background texture (pass in path to image, or Texture Card)
        # - A midground geometry item (pass in geometry)
        # - A foreground text Node (pass in text string or Onscreen Text)
        # For a direct button:
        # Each button has 4 states (ready, press, rollover, disabled)
        # The same image/geom/text can be used for all four states or each
        # state can have a different text/geom/image
        # State transitions happen automatically based upon mouse interaction
        # Responds to click event and calls command if None

        self.colors = None
        optiondefs = (
            ('indicatorValue', 0, self.setIndicatorValue),
            # variable is a list whose value will be set by this radio button
            ('variable', [], None),
            # value is the value to be set when this radio button is selected
            ('value', [], None),
            # others is a list of other radio buttons sharing same variable
            ('others', [], None),
            # boxBorder defines the space created around the check box
            ('boxBorder', 0, None),
            # boxPlacement maps left, above, right, below
            ('boxPlacement', 'left', None),
            # boxGeom defines geom to indicate current radio button is selected or not
            ('boxGeom', None, None),
            ('boxGeomColor', None, None),
            ('boxGeomScale', 1.0, None),
            ('boxImage', loader.loadModel('models/gui/radio_button_gui'), None),
            ('boxImageScale', 1.0, None),
            ('boxImageColor', VBase4(1, 1, 1, 1), None),
            ('boxRelief', None, None),
            )
        # Merge keyword options with default options
        self.defineoptions(kw, optiondefs)
        # Initialize superclasses
        DirectButton.__init__(self, parent)
        self.indicator = self.createcomponent("indicator", (), None,
                                              DirectLabel, (self,),
                                              numStates = 2,
                                              image = self['boxImage'],
                                              image_scale = self['boxImageScale'],
                                              image_color = self['boxImageColor'],
                                              geom = self['boxGeom'],
                                              geom_scale = self['boxGeomScale'],
                                              geom_color = self['boxGeomColor'],
                                              state = 'disabled',
                                              text = ('X', 'X'),
                                              relief = self['boxRelief'],
                                              )

        # Call option initialization functions
        self.initialiseoptions(DirectRadioButton)
        # After initialization with X giving it the correct size, put back space
        if self['boxGeom'] ==  None:
            self.indicator['text'] = (' ', '*')
            self.indicator['text_pos'] = (0, -.5)
        else:
            self.indicator['text'] = (' ', ' ')

        if self['boxGeomColor'] != None and self['boxGeom'] != None:
            self.colors = [VBase4(1, 1, 1, 0), self['boxGeomColor']]
            self.component('indicator')['geom_color'] = VBase4(1, 1, 1, 0)

        needToCheck = True
        if len(self['value']) == len(self['variable']) != 0:
            for i in range(len(self['value'])):
                if self['variable'][i] != self['value'][i]:
                    needToCheck = False
                    break

        if needToCheck:
            self.check()

    # Override the resetFrameSize of DirectGuiWidget inorder to provide space for label
    def resetFrameSize(self):
        self.setFrameSize(fClearFrame = 1)

    def setFrameSize(self, fClearFrame = 0):

        if self['frameSize']:
            # Use user specified bounds
            self.bounds = self['frameSize']
            frameType = self.frameStyle[0].getType()
            ibw = self.indicator['borderWidth']
        else:
            # Use ready state to compute bounds
            frameType = self.frameStyle[0].getType()
            if fClearFrame and (frameType != PGFrameStyle.TNone):
                self.frameStyle[0].setType(PGFrameStyle.TNone)
                self.guiItem.setFrameStyle(0, self.frameStyle[0])
                # To force an update of the button
                self.guiItem.getStateDef(0)
            # Clear out frame before computing bounds
            self.getBounds()
            # Restore frame style if necessary
            if (frameType != PGFrameStyle.TNone):
                self.frameStyle[0].setType(frameType)
                self.guiItem.setFrameStyle(0, self.frameStyle[0])

            # Ok, they didn't set specific bounds,
            #  let's add room for the label indicator
            #  get the difference in height

            ibw = self.indicator['borderWidth']
            indicatorWidth = (self.indicator.getWidth() + (2*ibw[0]))
            indicatorHeight = (self.indicator.getHeight() + (2*ibw[1]))
            diff = (indicatorHeight + (2*self['boxBorder']) -
                    (self.bounds[3] - self.bounds[2]))
            # If background is smaller then indicator, enlarge background
            if diff > 0:
                if self['boxPlacement'] == 'left':            #left
                    self.bounds[0] += -(indicatorWidth + (2*self['boxBorder']))
                    self.bounds[3] += diff/2
                    self.bounds[2] -= diff/2
                elif self['boxPlacement'] == 'below':          #below
                    self.bounds[2] += -(indicatorHeight+(2*self['boxBorder']))
                elif self['boxPlacement'] == 'right':          #right
                    self.bounds[1] += indicatorWidth + (2*self['boxBorder'])
                    self.bounds[3] += diff/2
                    self.bounds[2] -= diff/2
                else:                                    #above
                    self.bounds[3] += indicatorHeight + (2*self['boxBorder'])

            # Else make space on correct side for indicator
            else:
                if self['boxPlacement'] == 'left':            #left
                    self.bounds[0] += -(indicatorWidth + (2*self['boxBorder']))
                elif self['boxPlacement'] == 'below':          #below
                    self.bounds[2] += -(indicatorHeight + (2*self['boxBorder']))
                elif self['boxPlacement'] == 'right':          #right
                    self.bounds[1] += indicatorWidth + (2*self['boxBorder'])
                else:                                    #above
                    self.bounds[3] += indicatorHeight + (2*self['boxBorder'])

        # Set frame to new dimensions
        if ((frameType != PGFrameStyle.TNone) and
            (frameType != PGFrameStyle.TFlat)):
            bw = self['borderWidth']
        else:
            bw = (0, 0)
        # Set frame to new dimensions
        self.guiItem.setFrame(
            self.bounds[0] - bw[0],
            self.bounds[1] + bw[0],
            self.bounds[2] - bw[1],
            self.bounds[3] + bw[1])

        # If they didn't specify a position, put it in the center of new area
        if not self.indicator['pos']:
            bbounds = self.bounds
            lbounds = self.indicator.bounds
            newpos = [0, 0, 0]

            if self['boxPlacement'] == 'left':            #left
                newpos[0] += bbounds[0]-lbounds[0] + self['boxBorder'] + ibw[0]
                dropValue = (bbounds[3]-bbounds[2]-lbounds[3]+lbounds[2])/2 + self['boxBorder']
                newpos[2] += (bbounds[3]-lbounds[3] + self['boxBorder'] -
                              dropValue)
            elif self['boxPlacement'] == 'right':            #right
                newpos[0] += bbounds[1]-lbounds[1] - self['boxBorder'] - ibw[0]
                dropValue = (bbounds[3]-bbounds[2]-lbounds[3]+lbounds[2])/2 + self['boxBorder']
                newpos[2] += (bbounds[3]-lbounds[3] + self['boxBorder']
                              - dropValue)
            elif self['boxPlacement'] == 'above':            #above
                newpos[2] += bbounds[3]-lbounds[3] - self['boxBorder'] - ibw[1]
            else:                                      #below
                newpos[2] += bbounds[2]-lbounds[2] + self['boxBorder'] + ibw[1]

            self.indicator.setPos(newpos[0], newpos[1], newpos[2])


    def commandFunc(self, event):
        if len(self['value']) == len(self['variable']) != 0:            
            for i in range(len(self['value'])):
                self['variable'][i] = self['value'][i]
        self.check()

    def check(self):
        self['indicatorValue'] = 1
        self.setIndicatorValue()

        for other in self['others']:
            if other != self:
                other.uncheck()

        if self['command']:
            # Pass any extra args to command
            apply(self['command'], self['extraArgs'])

    def setOthers(self, others):
        self['others'] = others

    def uncheck(self):
        self['indicatorValue'] = 0
        if self.colors != None:
            self.component('indicator')['geom_color'] = self.colors[self['indicatorValue']]

    def setIndicatorValue(self):
        self.component('indicator').guiItem.setState(self['indicatorValue'])
        if self.colors != None:
            self.component('indicator')['geom_color'] = self.colors[self['indicatorValue']]