import Object3DQt   as qt
import PyQt4.Qwt5 as Qwt5
from VerticalSpacer import VerticalSpacer
DEBUG = 0
DRAW_MODES = ['NONE',
              'POINT',
              'WIRE',
              'SURFACE']
class Object3DDrawingModeWidget(qt.QGroupBox):
    def __init__(self, parent = None):
        qt.QGroupBox.__init__(self, parent)
        self.setTitle('Drawing Mode')
        self.build()
        self.setDrawingMode(1)
    def build(self):
        self.l = qt.QVBoxLayout(self)
        self.l.setMargin(0)
        self.l.setSpacing(4)
        self.buttonGroup = qt.QButtonGroup(self)
        j = 0
        for mode in DRAW_MODES:
            rButton = qt.QRadioButton(self)
            rButton.setText(mode)
            self.l.addWidget(rButton)
            self.l.setAlignment(rButton, qt.Qt.AlignLeft)
            self.buttonGroup.addButton(rButton)
            self.buttonGroup.setId(rButton, j)
            j += 1
            self.connect(self.buttonGroup,
                         qt.SIGNAL('buttonPressed(QAbstractButton *)'),
                         self._slot)
    def _slot(self, button):
        button.setChecked(True)
        self._signal()
    def _signal(self, event = None):
        if DEBUG:
            print("emit Object3DDrawingModeSignal")
        if event is None:
            event = 'DrawModeUpdated'
        ddict = self.getParameters()
        ddict['event']  = event
        self.emit(qt.SIGNAL('Object3DDrawingModeSignal'), ddict)
    def getParameters(self):
        mode = self.getDrawingMode()
        ddict = {}
        ddict['mode']   = mode
        ddict['label']  = str(self.buttonGroup.button(mode).text())
        return ddict
    def setParameters(self, ddict = None):
        if DEBUG:
            print("setParameters")
        if ddict is None:
            ddict = {}
        mode = ddict.get('mode', 1)
        self.setDrawingMode(mode)
    def setDrawingMode(self, mode):
        if type(mode) == type(" "):
            if mode.upper() in DRAW_MODES:
                i = DRAW_MODES.index(mode)
            else:
                raise ValueError("Unknown drawing mode: %s "  % mode)
        else:
            i = mode
        self.buttonGroup.button(i).setChecked(True)
    
    def getDrawingMode(self):
        mode = 0
        n = self.buttonGroup.checkedId()
        if n >= 0:
            mode = n
        else:
            print("WARNING: getAnchor -> Unselected button")
        return mode
    def setSupportedModes(self, modes):
        current = self.getDrawingMode()
        for i in modes:
            if i < len(DRAW_MODES):
                self.buttonGroup.button(i).setEnabled(True)
        # always possible to draw nothing
        self.buttonGroup.button(i).setEnabled(True)
        if not self.buttonGroup.button(current).isEnabled():
            self.buttonGroup.button(0).setChecked(True)
            self._signal()
class Object3DAspect(qt.QGroupBox):
    def __init__(self, parent = None):
        qt.QGroupBox.__init__(self, parent)
        self.setTitle('Aspect')
        self.build()
    def build(self):
        self.l = qt.QGridLayout(self)
        i = 0
        # point size
        label = qt.QLabel('Point size')
        self.pointSize = Qwt5.QwtSlider(self, qt.Qt.Horizontal)
        self.pointSize.setRange(1.0, 1.0, 1.0)
        self.pointSize.setValue(1.0)
        self.l.addWidget(label, i, 0)
        self.l.addWidget(self.pointSize, i, 1)
        self.connect(self.pointSize,
                     qt.SIGNAL("valueChanged(double)"),
                     self._slot)
        # line width
        i += 1
        label = qt.QLabel('Line width')
        self.lineWidth = Qwt5.QwtSlider(self, qt.Qt.Horizontal)
        self.lineWidth.setRange(1.0, 1.0, 1.0)
        self.lineWidth.setValue(1.0)
        self.l.addWidget(label, i, 0)
        self.l.addWidget(self.lineWidth, i, 1)
        self.connect(self.lineWidth,
                     qt.SIGNAL("valueChanged(double)"),
                     self._slot)
        # transparency
        i += 1
        label = qt.QLabel('Transparency')
        self.transparency = Qwt5.QwtSlider(self, qt.Qt.Horizontal)
        self.transparency.setRange(0.0, 1.0, 0.01)
        self.transparency.setValue(0.0)
        self.l.addWidget(label, i, 0)
        self.l.addWidget(self.transparency, i, 1)
        self.connect(self.transparency,
                     qt.SIGNAL("valueChanged(double)"),
                     self._slot)
        # bounding box
        self.boundingBoxCheckBox = qt.QCheckBox(self)
        self.boundingBoxCheckBox.setText("Show bounding box")
        self.connect(self.boundingBoxCheckBox,
                                         qt.SIGNAL("stateChanged(int)"),
                                         self._signal)
        i = 0
        j = 2
        self.l.addWidget(self.boundingBoxCheckBox, i, j)
        self.showLimitsCheckBoxes = []
        for t in ['X', 'Y', 'Z']:
            i += 1
            checkBox = qt.QCheckBox(self)
            checkBox.setText('Show bbox %s limit' % t)
            self.l.addWidget(checkBox, i, j)
            self.connect(checkBox, qt.SIGNAL("stateChanged(int)"), self._slot)
            self.showLimitsCheckBoxes.append(checkBox)
    def _slot(self, *var):
        self._signal()
    def getParameters(self):
        pointSize = self.pointSize.value()
        lineWidth = self.lineWidth.value()
        transparency = self.transparency.value()
        if self.boundingBoxCheckBox.isChecked():
            showBBox = 1
        else:
            showBBox = 0
        showLimits   = [0, 0, 0]
        for i in range(3):
            if self.showLimitsCheckBoxes[i].isChecked():
                showLimits[i] = 1
        ddict = {}
        ddict['pointsize'] = pointSize
        ddict['pointsizecapabilities'] = [self.pointSize.minValue(),
                                          self.pointSize.maxValue(),
                                          self.pointSize.step()]
        ddict['linewidth'] = lineWidth
        ddict['linewidthcapabilities'] = [self.lineWidth.minValue(),
                                          self.lineWidth.maxValue(),
                                          self.lineWidth.step()]
        ddict['transparency'] = transparency
        ddict['bboxflag' ]  = showBBox
        ddict['showlimits'] = showLimits
        return ddict
    def setParameters(self, ddict = None):
        if DEBUG:
            print("setParameters")
        if ddict is None:
            ddict = {}
        pointSize = ddict.get('pointsize', 1.0)
        pointSizeCapabilities = ddict.get('pointsizecapabilities',
                                          [1.0, 1.0, 1.0])
        lineWidth = ddict.get('linewidth', 1.0)
        lineWidthCapabilities = ddict.get('linewidthcapabilities',
                                          [1.0, 1.0, 1.0])
        transparency = ddict.get('transparency', 0.0)
        showBBox =  ddict.get('bboxflag', 1)
        showLimits = ddict.get('showlimits', [1, 1, 1])
        self.pointSize.setRange(pointSizeCapabilities[0],
                                pointSizeCapabilities[1],
                                pointSizeCapabilities[2])
        self.pointSize.setValue(pointSize)
        self.lineWidth.setRange(lineWidthCapabilities[0],
                                lineWidthCapabilities[1],
                                lineWidthCapabilities[2])
        self.lineWidth.setValue(lineWidth)
        if lineWidth > lineWidthCapabilities[1]:
            lineWidth = lineWidthCapabilities[1]
        self.transparency.setValue(transparency)
        self.boundingBoxCheckBox.setChecked(showBBox)
        
        for i in [0, 1, 2]:
            self.showLimitsCheckBoxes[i].setChecked(showLimits[i])
    def _signal(self, event = None):
        if DEBUG:
            print("emitting Object3DAspectSignal")
        if event is None:
            event = "AspectUpdated"
        ddict = self.getParameters()
        ddict['event'] = event
        self.emit(qt.SIGNAL('Object3DAspectSignal'), ddict)
class Object3DScale(qt.QGroupBox):
    def __init__(self, parent = None):
        qt.QGroupBox.__init__(self, parent)
        self.setTitle('Object Scaling')
        self.l = qt.QGridLayout(self)
        self.__disconnect = False
        self.__oldScale = [1.0, 1.0, 1.0]
        self.lineEditList = []
        self.validatorList = []
        i = 0
        self._lineSlotList =[self._xLineSlot,
                             self._yLineSlot,
                             self._zLineSlot]
        for axis in ['x', 'y', 'z']:
            label = qt.QLabel("%s Scale" % axis)
            lineEdit = qt.QLineEdit(self)
            v = qt.QDoubleValidator(lineEdit)
            lineEdit.setValidator(v)
            
            self.validatorList.append(v)
            self.l.addWidget(label, i, 0)
            self.l.addWidget(lineEdit, i, 1)
            self.lineEditList.append(lineEdit)
            lineEdit.setText('1.0')
            lineEdit.setFixedWidth(lineEdit.fontMetrics().width('######.#####'))
            self.connect(lineEdit,
                         qt.SIGNAL('editingFinished()'),
                         self._lineSlotList[i])
            i+= 1
        # xScaling
        i = 0
        self.xScaleSlider = Qwt5.QwtSlider(self, qt.Qt.Horizontal)
        self.xScaleSlider.setScale(-10.0, 10.0, 0.001)
        self.xScaleSlider.setValue(1.0)
        self.l.addWidget(self.xScaleSlider, i, 2)
        self.connect(self.xScaleSlider,
                     qt.SIGNAL("valueChanged(double)"),
                     self._xSliderSlot)
        # yScaling
        i += 1
        self.yScaleSlider = Qwt5.QwtSlider(self, qt.Qt.Horizontal)
        self.yScaleSlider.setRange(-100.0, 100.0, 0.01)
        self.yScaleSlider.setValue(1.0)
        self.l.addWidget(self.yScaleSlider, i, 2)
        self.connect(self.yScaleSlider,
                     qt.SIGNAL("valueChanged(double)"),
                     self._ySliderSlot)
        # zScaling
        i += 1
        self.zScaleSlider = Qwt5.QwtSlider(self, qt.Qt.Horizontal)
        self.zScaleSlider.setRange(-100.0, 100.0, 0.01)
        self.zScaleSlider.setValue(1.0)
        self.l.addWidget(self.zScaleSlider, i, 2)
        self.connect(self.zScaleSlider,
                     qt.SIGNAL("valueChanged(double)"),
                     self._zSliderSlot)
    def _xSliderSlot(self, *var):
        if not self.__disconnect:
            scale = [self.xScaleSlider.value(),
                     self.yScaleSlider.value(),
                     self.zScaleSlider.value()]
            self.__disconnect = True
            for i in [0, 1, 2]:
                if scale[i] != float(str(self.lineEditList[i].text())):
                    self.lineEditList[i].setText("%.7g" % scale[i])
            self.__disconnect = False
            if (self.__oldScale[0] != scale[0]) or \
               (self.__oldScale[1] != scale[1]) or \
               (self.__oldScale[2] != scale[2]) :
                self.__oldScale = scale
                self._signal("xScaleUpdated")
    def _ySliderSlot(self, *var):
        if not self.__disconnect:
            scale = [self.xScaleSlider.value(),
                     self.yScaleSlider.value(),
                     self.zScaleSlider.value()]
            self.__disconnect = True
            for i in [0, 1, 2]:
                if scale[i] != float(str(self.lineEditList[i].text())):
                    self.lineEditList[i].setText("%.7g" % scale[i])
            self.__disconnect = False
            if (self.__oldScale[0] != scale[0]) or \
               (self.__oldScale[1] != scale[1]) or \
               (self.__oldScale[2] != scale[2]) :
                self.__oldScale = scale
                self._signal("yScaleUpdated")
    def _zSliderSlot(self, *var):
        if not self.__disconnect:
            scale = [self.xScaleSlider.value(),
                     self.yScaleSlider.value(),
                     self.zScaleSlider.value()]
            self.__disconnect = True
            for i in [0, 1, 2]:
                if scale[i] != float(str(self.lineEditList[i].text())):
                    self.lineEditList[i].setText("%.7g" % scale[i])
            self.__disconnect = False
            if (self.__oldScale[0] != scale[0]) or \
               (self.__oldScale[1] != scale[1]) or \
               (self.__oldScale[2] != scale[2]) :
                self.__oldScale = scale
                self._signal("zScaleUpdated")
    def _xLineSlot(self):
        if not self.__disconnect:
            self.__disconnect = True
            scale = [1, 1, 1]
            for i in [0, 1 , 2]:
                scale[i] = float(str(self.lineEditList[i].text()))
            self.xScaleSlider.setValue(scale[0])
            self.yScaleSlider.setValue(scale[1])
            self.zScaleSlider.setValue(scale[2])
            self.__disconnect = False
            self._signal("xScaleUpdated")
    def _yLineSlot(self):
        if not self.__disconnect:
            self.__disconnect = True
            scale = [1, 1, 1]
            for i in [0, 1 , 2]:
                scale[i] = float(str(self.lineEditList[i].text()))
            self.xScaleSlider.setValue(scale[0])
            self.yScaleSlider.setValue(scale[1])
            self.zScaleSlider.setValue(scale[2])
            self.__disconnect = False
            self._signal("yScaleUpdated")
    def _zLineSlot(self):
        if not self.__disconnect:
            self.__disconnect = True
            scale = [1, 1, 1]
            for i in [0, 1 , 2]:
                scale[i] = float(str(self.lineEditList[i].text()))
            self.xScaleSlider.setValue(scale[0])
            self.yScaleSlider.setValue(scale[1])
            self.zScaleSlider.setValue(scale[2])
            self.__disconnect = False
            self._signal("zScaleUpdated")
    def _signal(self, event = None):
        if DEBUG:
            print("emitting Object3DScaleSignal")
        if self.__disconnect: return
        if event is None:
            event = "ScaleUpdated"
        oldScale = self._lastParameters * 1
        ddict = self.getParameters()
        scale = ddict['scale']
        emit = False
        for i in range(3):
            if abs((scale[i]-oldScale[i])) > 1.0e-10:
                emit = True
                ddict['magnification'] = scale[i]/oldScale[i] 
                break
        if not emit:
            return
        ddict['event'] = event
        self.emit(qt.SIGNAL('Object3DScaleSignal'), ddict)
    def getParameters(self):
        scale = [1.0, 1.0, 1.0]
        for i in [0, 1 , 2]:
            scale[i] = float(str(self.lineEditList[i].text()))
        ddict = {}
        ddict['scale'] = scale
        self._lastParameters = scale
        return ddict
    def setParameters(self, ddict = None):
        if DEBUG:
            print("setParameters", ddict)
        if ddict is None:ddict = {}
        scale = ddict.get('scale', [1.0, 1.0, 1.0])
        
        self.xScaleSlider.setValue(scale[0])
        self.yScaleSlider.setValue(scale[1])
        self.zScaleSlider.setValue(scale[2])
        for i in [0, 1, 2]:
            self.lineEditList[i].setText("%.7g" % scale[i])
        self._lastParameters = scale
class Object3DPrivateInterface(qt.QGroupBox):
    def __init__(self, parent = None):
        qt.QGroupBox.__init__(self, parent)
        self.setTitle('Private Configuration')
        self.mainLayout = qt.QVBoxLayout(self)
        self.button = qt.QPushButton(self)
        self.button.setText("More")
        self.mainLayout.addWidget(self.button)
        self.mainLayout.addWidget(VerticalSpacer(self))
class Object3DProperties(qt.QWidget):
    def __init__(self, parent = None):
        qt.QWidget.__init__(self, parent)
        self.l = qt.QHBoxLayout(self)
        self.drawingModeWidget = Object3DDrawingModeWidget(self)


Answer:         self.aspectWidget = Object3DAspect(self)