# -*- coding: utf-8 -*-
#
# $Date: 2013-03-15 17:48:48 +0900 (金, 15 3 2013) $
# $Rev: 69 $
#
import wx
import decimal
import math

import xrc.base
import qspace
import define

# FPS:Floating point representation for wxSlider
FPS = 100

class DecimalValidator(wx.PyValidator):
    def __init__(self, min, max):
        wx.PyValidator.__init__(self)

        if min != None:
            self.__min = decimal.Decimal(min)
            pass
        else:
            self.__min = None
            pass

        if max != None:
            self.__max = decimal.Decimal(max)
            pass
        else:
            self.__max = None
            pass

        self.Bind(wx.EVT_TEXT_ENTER, self.TextEnter)
        self.Bind(wx.EVT_LEAVE_WINDOW, self.TextEnter)
        return

    def Clone(self):
        return DecimalValidator(self.__min, self.__max)

    def Validate(self, parent):
        textCtrl = self.GetWindow()
        value = textCtrl.GetValue()

        flag = True

        try:
            num = decimal.Decimal(value)
            if (self.__min != None and num < self.__min) or \
                    (self.__max != None and self.__max < num):
                wx.MessageBox("This value is range out.", "Illegal value error")
                              
                flag = False
                pass
        except:
            wx.MessageBox("This value is not numeric value.", "Illegal value error")
            flag = False
            pass

        if flag:
            textCtrl.SetBackgroundColour("white")
            textCtrl.Refresh()
            pass
        else:
            textCtrl.SetBackgroundColour("pink")
            textCtrl.SetFocus()
            textCtrl.Refresh()
            textCtrl.SetValue(self.__initialValue)
            pass
        return flag

    def TransferToWindow(self):
        self.__initialValue = self.GetWindow().GetValue()
        return True

    def TransferFromWindow(self):
        return True

    def TextEnter(self, event):
        if self.Validate(None):
            event.Skip()
            pass
        return

class RotationControlDialog(xrc.base.DialogBase):
    def __init__(self, parent):
        xrc.base.DialogBase.__init__(self, parent, 'resources/RotCtrlDlg.xrc', "RotCtrlDlg")

        button = self.getControl('resetButton')
        button.Bind(wx.EVT_BUTTON, self.Reset)
        button = self.getControl('convertButton')
        button.Bind(wx.EVT_BUTTON, self.Convert)

        for name in ['psiTextCtrl', 'chiTextCtrl', 'phiTextCtrl']:
            text = self.getControl(name)
            text.SetValidator(DecimalValidator(-180, 180))
            text.Bind(wx.EVT_TEXT_ENTER, self.TextEnter)
            pass

        for name in ['psiSlider', 'chiSlider', 'phiSlider']:
            slider = self.getControl(name)
            slider.SetRange(-180 * FPS, 180 * FPS)
            slider.Bind(wx.EVT_SCROLL, self.SliderMove)
            pass

        for name in ['psiRadioButton', 'chiRadioButton', 'phiRadioButton']:
            radioButton = self.getControl(name)
            radioButton.Bind(wx.EVT_RADIOBUTTON, self.RadioButtonControl)
            pass

        button = self.getControl('wxID_OK')
        # self.Bind(wx.EVT_CLOSE, self.OnClose)

        self.ReloadParameters()
        return

    def SetQPointInformation(self, information):
        self.getControl('QpInfoTextCtrl').SetValue(information)
        return

    def Reset(self, event):
        for name in ['psiTextCtrl', 'chiTextCtrl', 'phiTextCtrl']:
            text = self.getControl(name)
            text.SetValue('0.0')
            pass

        for name in ['psiSlider', 'chiSlider', 'phiSlider']:
            slider = self.getControl(name)
            slider.SetValue(0)
            pass

        self.GetParent().SetParameter(qspace.TAG_ROTATE_PSI, decimal.Decimal(0))
        self.GetParent().SetParameter(qspace.TAG_ROTATE_CHI, decimal.Decimal(0))
        self.GetParent().SetParameter(qspace.TAG_ROTATE_PHI, decimal.Decimal(0))

        self.GetParent().UpdateRotation()
        return

    def Convert(self, event):
        message = wx.MessageDialog(self,
                                   'Change the origin of angles to current position.',
                                   'Convert origin', wx.OK | wx.CANCEL)
        message.CenterOnParent()

        if message.ShowModal() == wx.ID_OK:
            mainFrame = self.GetParent()

            lattice = mainFrame.GetLattice()

            mainFrame.SetParameter(qspace.TAG_SAMPLE_UH, decimal.Decimal(str(lattice.rotUh)))
            mainFrame.SetParameter(qspace.TAG_SAMPLE_UK, decimal.Decimal(str(lattice.rotUk)))
            mainFrame.SetParameter(qspace.TAG_SAMPLE_UL, decimal.Decimal(str(lattice.rotUl)))
            mainFrame.SetParameter(qspace.TAG_SAMPLE_VH, decimal.Decimal(str(lattice.rotVh)))
            mainFrame.SetParameter(qspace.TAG_SAMPLE_VK, decimal.Decimal(str(lattice.rotVk)))
            mainFrame.SetParameter(qspace.TAG_SAMPLE_VL, decimal.Decimal(str(lattice.rotVl)))

            self.Reset(None)
            pass
        return

    def TextEnter(self, event):
        name = event.GetEventObject().GetName()

        if name == 'psiTextCtrl':
            slider = self.getControl('psiSlider')
            parameterName = qspace.TAG_ROTATE_PSI
            pass
        elif name == 'chiTextCtrl':
            slider = self.getControl('chiSlider')
            parameterName = qspace.TAG_ROTATE_CHI
            pass
        else:
            slider = self.getControl('phiSlider')
            parameterName = qspace.TAG_ROTATE_PHI
            pass

        angle = int(decimal.Decimal(event.GetEventObject().GetValue()) * FPS) * 1.0
        slider.SetValue(angle)

        angle = angle / FPS
        self.GetParent().SetParameter(parameterName, angle)

        event.GetEventObject().SetValue(str(angle))

        self.GetParent().UpdateRotation()
        return

    def SliderMove(self, event):
        slider = event.GetEventObject()

        if slider == self.getControl('psiSlider'):
            textCtrlName = 'psiTextCtrl'
            parameterName = qspace.TAG_ROTATE_PSI
            pass
        elif slider == self.getControl('chiSlider'):
            textCtrlName = 'chiTextCtrl'
            parameterName = qspace.TAG_ROTATE_CHI
            pass
        else:
            textCtrlName = 'phiTextCtrl'
            parameterName = qspace.TAG_ROTATE_PHI
            pass

        angle = decimal.Decimal(slider.GetValue()) / FPS
        self.getControl(textCtrlName).SetValue(str(angle))
        self.GetParent().SetParameter(parameterName, angle)

        self.GetParent().UpdateRotation()
        return

    def RadioButtonControl(self, event):
        buttonName = event.GetEventObject().GetName()

        if buttonName == 'psiRadioButton':
            value = 'psi'
            pass
        elif buttonName == 'chiRadioButton':
            value = 'chi'
            pass
        else:
            value = 'phi'
            pass

        self.GetParent().SetParameter(qspace.TAG_ROTATE_GUIDEAXIS, value)

        self.GetParent().UpdateRotationGuideAxis()
        return

    def ReloadParameters(self):
        parameterNameList = (qspace.TAG_ROTATE_PSI, qspace.TAG_ROTATE_CHI, qspace.TAG_ROTATE_PHI)
        textControlNameList = ('psiTextCtrl', 'chiTextCtrl', 'phiTextCtrl')
        sliderNameList = ('psiSlider', 'chiSlider', 'phiSlider')

        for i in xrange(len(parameterNameList)):
            value = str(self.GetParent().GetParameter(parameterNameList[i]))

            text = self.getControl(textControlNameList[i])
            text.SetValue(value)

            slider = self.getControl(sliderNameList[i])

            angle = int(decimal.Decimal(value) * FPS) * 1.0
            slider.SetValue(angle)
            pass
        return

class DNAEnergyControlDialog(xrc.base.DialogBase):
    def __init__(self, parent):
        xrc.base.DialogBase.__init__(self, parent, 'resources/EngCtrlDlg.xrc', "EngCtrlDlg")

        text = self.getControl('eiminTextCtrl')
        text.SetValidator(DecimalValidator(0, None))
        text.SetValue(str(parent.GetParameter(qspace.TAG_ENG_EIMIN)))

        text = self.getControl('eimaxTextCtrl')
        text.SetValidator(DecimalValidator(0, None))
        text.SetValue(str(parent.GetParameter(qspace.TAG_ENG_EIMAX)))

        button = self.getControl('wxID_OK')
        button.Bind(wx.EVT_BUTTON, self.InputCheck)
        return

    def InputCheck(self, event):
        event.Skip()
        return

    def GetEnergyRange(self):
        min = decimal.Decimal(self.getControl('eiminTextCtrl').GetValue())
        max = decimal.Decimal(self.getControl('eimaxTextCtrl').GetValue())
        return (min, max)

class SIKEnergyControlDialog(xrc.base.DialogBase):
    def __init__(self, parent):
        xrc.base.DialogBase.__init__(self, parent, 'resources/EngCtrlDlg2.xrc', "EngCtrlDlg2")

        text = self.getControl('eiTextCtrl')
        text.SetValidator(DecimalValidator(0, None))
        text.SetValue(str(parent.GetParameter(qspace.TAG_ENG_EI)))

        text = self.getControl('etminTextCtrl')
        text.SetValidator(DecimalValidator(None, None))
        text.SetValue(str(parent.GetParameter(qspace.TAG_ENG_ETMIN)))

        text = self.getControl('etmaxTextCtrl')
        text.SetValidator(DecimalValidator(0, None))
        text.SetValue(str(parent.GetParameter(qspace.TAG_ENG_ETMAX)))
        return

    def GetEnergyRange(self):
        ei = decimal.Decimal(self.getControl('eiTextCtrl').GetValue())
        min = decimal.Decimal(self.getControl('etminTextCtrl').GetValue())
        max = decimal.Decimal(self.getControl('etmaxTextCtrl').GetValue())
        return (ei, min, max)

class CutPlaneSpecifyPanel(xrc.base.PanelBase):
    def __init__(self, parent):
        xrc.base.PanelBase.__init__(self, parent, 'resources/CutPlaneSpecifyPanel.xrc', 'cut plane specify panel')

        self.Fit()

        self.__mainFrame = parent.GetParent()

        while not isinstance(self.__mainFrame, wx.Frame):
            self.__mainFrame = self.__mainFrame.GetParent()
            pass

        radioBox = self.getControl('plane definition radio box')
        if isinstance(self.GetParent().GetParent(), QEGraphSetupDialog):
            radioBox.SetSelection(self.__mainFrame.GetParameter(qspace.TAG_QEGRAPH_PLANEDEF))
            pass
        else:
            radioBox.SetSelection(self.__mainFrame.GetParameter(qspace.TAG_QRGRAPH_PLANEDEF))
            pass
        radioBox.Bind(wx.EVT_RADIOBOX, self.UpdateSetting)

        planeType = radioBox.GetSelection()

        isUVControl = planeType == 3

        controlNameList = ('origin h input', 'origin k input', 'origin l input',
                           'u vector h input', 'u vector k input', 'u vector l input',
                           'v vector h input', 'v vector k input', 'v vector l input')

        if isinstance(self.GetParent().GetParent(), QEGraphSetupDialog):
            parameterNameList = (qspace.TAG_QEGRAPH_OH, qspace.TAG_QEGRAPH_OK, qspace.TAG_QEGRAPH_OL,
                                 qspace.TAG_QEGRAPH_UH, qspace.TAG_QEGRAPH_UK, qspace.TAG_QEGRAPH_UL,
                                 qspace.TAG_QEGRAPH_VH, qspace.TAG_QEGRAPH_VK, qspace.TAG_QEGRAPH_VL)
            pass
        else:
            parameterNameList = (qspace.TAG_QRGRAPH_OH, qspace.TAG_QRGRAPH_OK, qspace.TAG_QRGRAPH_OL,
                                 qspace.TAG_QRGRAPH_UH, qspace.TAG_QRGRAPH_UK, qspace.TAG_QRGRAPH_UL,
                                 qspace.TAG_QRGRAPH_VH, qspace.TAG_QRGRAPH_VK, qspace.TAG_QRGRAPH_VL)
            pass

        bounds = self.__mainFrame.GetBounds()

        for i in xrange(3):
            textControl = self.getControl(controlNameList[i])
            textControl.SetValidator(DecimalValidator(str(bounds[i * 2]), str(bounds[i * 2 + 1])))
            textControl.SetValue(unicode(self.__mainFrame.GetParameter(parameterNameList[i])))
            textControl.Bind(wx.EVT_TEXT_ENTER, self.UpdateSetting)
            textControl.Bind(wx.EVT_LEAVE_WINDOW, self.UpdateSetting)
            pass

        for i in xrange(3, len(parameterNameList)):
            textControl = self.getControl(controlNameList[i])
            textControl.SetValue(unicode(self.__mainFrame.GetParameter(parameterNameList[i])))
            textControl.Enable(isUVControl)
            textControl.Bind(wx.EVT_TEXT_ENTER, self.UpdateSetting)
            textControl.Bind(wx.EVT_LEAVE_WINDOW, self.UpdateSetting)
            pass
        return

    def UpdateSetting(self, event):
        control = event.GetEventObject()
        controlName = control.GetName()

        if controlName == 'plane definition radio box':
            if isinstance(self.GetParent().GetParent(), QEGraphSetupDialog):
                self.__mainFrame.SetParameter(qspace.TAG_QEGRAPH_PLANEDEF, control.GetSelection())
                pass
            else:
                self.__mainFrame.SetParameter(qspace.TAG_QRGRAPH_PLANEDEF, control.GetSelection())
                pass

            isUVControl = control.GetSelection() == 3

            for name in ('u vector h input', 'u vector k input', 'u vector l input', 'v vector h input', 'v vector k input', 'v vector l input'):
                self.getControl(name).Enable(isUVControl)
                pass
            pass
        else:
            controlNameList = ['origin h input', 'origin k input', 'origin l input',
                               'u vector h input', 'u vector k input', 'u vector l input',
                               'v vector h input', 'v vector k input', 'v vector l input']

            if isinstance(self.GetParent().GetParent(), QEGraphSetupDialog):
                parameterNameList = (qspace.TAG_QEGRAPH_OH, qspace.TAG_QEGRAPH_OK, qspace.TAG_QEGRAPH_OL,
                                     qspace.TAG_QEGRAPH_UH, qspace.TAG_QEGRAPH_UK, qspace.TAG_QEGRAPH_UL,
                                     qspace.TAG_QEGRAPH_VH, qspace.TAG_QEGRAPH_VK, qspace.TAG_QEGRAPH_VL)
                pass
            else:
                parameterNameList = (qspace.TAG_QRGRAPH_OH, qspace.TAG_QRGRAPH_OK, qspace.TAG_QRGRAPH_OL,
                                     qspace.TAG_QRGRAPH_UH, qspace.TAG_QRGRAPH_UK, qspace.TAG_QRGRAPH_UL,
                                     qspace.TAG_QRGRAPH_VH, qspace.TAG_QRGRAPH_VK, qspace.TAG_QRGRAPH_VL)
                pass

            index = controlNameList.index(controlName)
            self.__mainFrame.SetParameter(parameterNameList[index], float(control.GetValue()))
            pass

        if isinstance(self.GetParent().GetParent(), QEGraphSetupDialog):
            self.__mainFrame.UpdateQEGraphCutPlane()
            pass
        else:
            self.__mainFrame.UpdateQRegionGraphCutPlane()
            pass
        return

class QEGraphSetupDialog(xrc.base.DialogBase):
    def __init__(self, parent):
        xrc.base.DialogBase.__init__(self, parent, 'resources/QEGraphSetsDlg.xrc', "QEGraphSetsDlg")

        panel = self.getControl('plane definition panel')

        planePanel = CutPlaneSpecifyPanel(panel)
        panel.GetSizer().Add(planePanel, flag = wx.EXPAND)
        planePanel.InitDialog()

        self.Fit()

        radioBox = self.getControl('surfScalarRadioBox')
        radioBox.EnableItem(1, parent.IsMeasurementDataLoaded())

        button = self.getControl('draw graph')
        button.Bind(wx.EVT_BUTTON, self.PopupQEGraphDialog)

        button = self.getControl('draw contour')
        button.Bind(wx.EVT_BUTTON, self.PopupQEContourDialog)

        button = self.getControl('wxID_OK')
        button.Bind(wx.EVT_BUTTON, self.close)

        self.Bind(wx.EVT_CLOSE, self.close)

        self.GetParent().UpdateQEGraphCutPlane()
        return

    def close(self, event):
        self.GetParent().ShowQEGraphCutPlane(False)

        event.Skip()
        return

    def PopupQEGraphDialog(self, event):
        dialog = QEGraphDialog(self)
        dialog.Show()
        return

    def PopupQEContourDialog(self, event):
        dialog = QEContourDialog(self)
        dialog.Show()
        return

    def GetScalarKind(self):
        return self.getControl('surfScalarRadioBox').GetStringSelection()

import VTKPanel

class QEGraphDialogBase(xrc.base.DialogBase):
    def __init__(self, parent, filename, dialogName):
        xrc.base.DialogBase.__init__(self, parent, filename, dialogName)

        button = self.getControl('wxID_OK')
        button.Bind(wx.EVT_BUTTON, self.close)
        self.Bind(wx.EVT_CLOSE, self.close)
        return

    def SetGraphPanel(self, graphPanel, isContour):
        self._qeGraphPanel = graphPanel

        mainFrame = self.GetParent()

        while not isinstance(mainFrame, wx.Frame):
            mainFrame = mainFrame.GetParent()
            pass

        qOrigin, qU, qV, qNormal = mainFrame.GetQEGraphAxis()

        self._qeGraphPanel.SetupTransformMatrix(qOrigin, qU, qV)
        if not isContour:
            self._qeGraphPanel.CreateWarpSurface(qOrigin, qNormal)
            pass
        else:
            self._qeGraphPanel.CreateContour(qOrigin, qNormal)
            pass
        self._qeGraphPanel.SetupRanges()
        self._qeGraphPanel.SetupQPoints(mainFrame.GetQPPotionOnQECutPlane(qNormal, qOrigin))
        self._qeGraphPanel.SetupUVAxis()
        self._qeGraphPanel.SetupGridLines()
        self._qeGraphPanel.SetupAxes()
        self._qeGraphPanel.SetupCamera()
        self._qeGraphPanel.SetLegendBox()
        return

    def close(self, event):
        self.Destroy()
        return

    def resize(self, event):
        self._qeGraphPanel.SetSize(event.GetSize())
        return

class QEGraphDialog(QEGraphDialogBase):
    def __init__(self, parent):
        QEGraphDialogBase.__init__(self, parent, 'resources/QEGraphWindow.xrc', 'QEGraphWindow')

        panel = self.getControl('QEGraphPanel')

        graphPanel = VTKPanel.QEGraphPanel(panel)

        panel.GetSizer().Add(graphPanel)
        panel.Bind(wx.EVT_SIZE, self.resize)

        self.SetGraphPanel(graphPanel, False)

        mainFrame = parent.GetParent()
        etMin, etMax = mainFrame.GetScalarFieldRange(define.ENERGY_TRANSFER)

        graphPanel.CreateColorBar(define.ENERGY_TRANSFER, (etMin, etMax))

        etMin = decimal.Decimal(str(etMin))
        etMax = decimal.Decimal(str(etMax))

        self.getControl('etMinText').SetLabel(str(etMin))
        self.getControl('etMaxText').SetLabel(str(etMax))

        text = self.getControl('etTextCtrl')
        text.SetValidator(DecimalValidator(etMin, etMax))
        text.SetValue(str(etMin))
        text.Bind(wx.EVT_TEXT_ENTER, self.SetEtValue)

        slider = self.getControl('etSlider')
        slider.SetRange(int(etMin * FPS), int(etMax * FPS))
        slider.SetValue(int(etMin * FPS))
        slider.Bind(wx.EVT_SCROLL, self.SliderMove)
        return

    def SliderMove(self, event):
        slider = event.GetEventObject()

        value = decimal.Decimal(slider.GetValue()) / FPS
        self.getControl('etTextCtrl').SetValue(str(value))

        self._qeGraphPanel.UpdateGridPosition(float(value))
        self._qeGraphPanel.Render()
        return

    def SetEtValue(self, event):
        text = event.GetEventObject()

        et = decimal.Decimal(text.GetValue())
        et = decimal.Decimal(int(et * FPS)) / FPS

        slider = self.getControl('etSlider')
        slider.SetValue(int(et * FPS))

        text.SetValue(str(et))

        self._qeGraphPanel.UpdateGridPosition(float(et))
        self._qeGraphPanel.Render()
        return

class QEContourDialog(QEGraphDialogBase):
    def __init__(self, parent):
        QEGraphDialogBase.__init__(self, parent, 'resources/QEContourDialog.xrc', 'qe contour dialog')

        panel = self.getControl('contour panel')

        self.__graphPanel = VTKPanel.QEContourPanel(panel)

        panel.GetSizer().Add(self.__graphPanel)
        panel.Bind(wx.EVT_SIZE, self.resize)

        self.SetGraphPanel(self.__graphPanel, True)

        mainFrame = parent.GetParent()

        etMin, etMax = mainFrame.GetScalarFieldRange(define.ENERGY_TRANSFER)
        self.__graphPanel.CreateColorBar(define.ENERGY_TRANSFER, (etMin, etMax))

        checkBox = self.getControl('q point display')
        checkBox.Bind(wx.EVT_CHECKBOX, self.QPointVisibilityControl)

        button = self.getControl('save image button')
        button.Bind(wx.EVT_BUTTON, self.PopupFileDialog)
        return

    def QPointVisibilityControl(self, event):
        checkBox = self.getControl('q point display')

        self.__graphPanel.ShowQPoint(checkBox.GetValue())
        self.__graphPanel.Render()
        return

    def PopupFileDialog(self, event):
        fileDialog = wx.FileDialog(self,
                                   'Save Image Data', wildcard = 'PostScript (*.ps)|*.ps|JPEG (*.jpg;*.jpeg)|*.jpg;*.jpeg|PNM (*.pnm)|*.pnm|TIFF (*.tif;*.tiff)|*.tif;*.tiff',
                                   style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
        fileDialog.CenterOnParent()

        if fileDialog.ShowModal() == wx.ID_OK:
            if fileDialog.GetFilterIndex() == 0:
                imageType = 'PostScript'
                pass
            elif fileDialog.GetFilterIndex() == 1:
                imageType = 'JPEG'
                pass
            elif fileDialog.GetFilterIndex() == 2:
                imageType = 'PNM'
                pass
            elif fileDialog.GetFilterIndex() == 3:
                imageType = 'TIFF'
                pass

            self.__graphPanel.CreateImageDataFile(imageType, fileDialog.GetPath())
            pass
        return

class QRegionSetupDialog(xrc.base.DialogBase):
    def __init__(self, parent):
        xrc.base.DialogBase.__init__(self, parent, 'resources/QRegionGraphSetsDlg.xrc', "QRegionGraphSetsDlg")

        text = self.getControl('psiTextCtrl')
        text.SetValidator(DecimalValidator(-180, 180))
        text.SetValue(str(parent.GetParameter(qspace.TAG_QRGRAPH_PSI0)))
        text.Bind(wx.EVT_TEXT_ENTER, self.UpdateSetting)
        text.Bind(wx.EVT_LEAVE_WINDOW, self.UpdateSetting)

        text = self.getControl('chiTextCtrl')
        text.SetValidator(DecimalValidator(-180, 180))
        text.SetValue(str(parent.GetParameter(qspace.TAG_QRGRAPH_CHI0)))
        text.Bind(wx.EVT_TEXT_ENTER, self.UpdateSetting)
        text.Bind(wx.EVT_LEAVE_WINDOW, self.UpdateSetting)

        text = self.getControl('phiTextCtrl')
        text.SetValidator(DecimalValidator(-180, 180))
        text.SetValue(str(parent.GetParameter(qspace.TAG_QRGRAPH_PHI0)))
        text.Bind(wx.EVT_TEXT_ENTER, self.UpdateSetting)
        text.Bind(wx.EVT_LEAVE_WINDOW, self.UpdateSetting)

        text = self.getControl('intervalTextCtrl')
        text.SetValidator(DecimalValidator(-180, 180))
        text.SetValue(str(parent.GetParameter(qspace.TAG_QRGRAPH_INTERVAL)))
        text.Bind(wx.EVT_TEXT_ENTER, self.UpdateSetting)
        text.Bind(wx.EVT_LEAVE_WINDOW, self.UpdateSetting)

        spinControl = self.getControl('nstepSpinCtrl')
        spinControl.SetValue(parent.GetParameter(qspace.TAG_QRGRAPH_NSTEP))
        spinControl.Bind(wx.EVT_SPINCTRL, self.UpdateSetting)

        comboBox = self.getControl('rotateAxisComboBox')
        comboBox.SetSelection(parent.GetParameter(qspace.TAG_QRGRAPH_ROTATEAXIS))
        comboBox.Bind(wx.EVT_COMBOBOX, self.UpdateSetting)

        text = self.getControl('etminTextCtrl')
        text.SetValidator(DecimalValidator(None, None))
        text.SetValue(str(parent.GetParameter(qspace.TAG_QRGRAPH_ETMIN)))
        text.Bind(wx.EVT_TEXT_ENTER, self.UpdateSetting)
        text.Bind(wx.EVT_LEAVE_WINDOW, self.UpdateSetting)

        text = self.getControl('etmaxTextCtrl')
        text.SetValidator(DecimalValidator(None, None))
        text.SetValue(str(parent.GetParameter(qspace.TAG_QRGRAPH_ETMAX)))
        text.Bind(wx.EVT_TEXT_ENTER, self.UpdateSetting)
        text.Bind(wx.EVT_LEAVE_WINDOW, self.UpdateSetting)

        text = self.getControl('step')
        text.SetValue('1')
        text.Bind(wx.EVT_TEXT_ENTER, self.UpdateSetting)
        text.Bind(wx.EVT_LEAVE_WINDOW, self.UpdateSetting)

        text = self.getControl('delta e')
        text.SetValue('1')
        text.Bind(wx.EVT_TEXT_ENTER, self.UpdateSetting)
        text.Bind(wx.EVT_LEAVE_WINDOW, self.UpdateSetting)

        panel = self.getControl('plane definition panel')

        planePanel = CutPlaneSpecifyPanel(panel)
        panel.GetSizer().Add(planePanel, flag = wx.EXPAND)
        planePanel.InitDialog()

        self.Fit()

        button = self.getControl('drawButton')
        button.Bind(wx.EVT_BUTTON, self.PopupQRegionGraphDialog)

        button = self.getControl('wxID_OK')
        button.Bind(wx.EVT_BUTTON, self.close)

        self.Bind(wx.EVT_CLOSE, self.close)

        button = self.getControl('gonio control')
        button.Bind(wx.EVT_BUTTON, self.gonioControl)

        self.GetParent().UpdateQRegionGraphCutPlane()
        return

    def close(self, event):
        self.GetParent().EraseThinDetectableRegions()
        self.GetParent().ShowQRigionGraphCutPlane(False)

        event.Skip()
        return

    def gonioControl(self, event):
        text = self.getControl('intervalTextCtrl')

        print 'PM16C.Move("GONIO", "OMG", ' + text.GetValue() + ')'
        return

    def UpdateSetting(self, event):
        mainFrame = self.GetParent()
        control = event.GetEventObject()
        controlName = control.GetName()

        if controlName == 'planeDefRadioBox':
            mainFrame.SetParameter(qspace.TAG_QRGRAPH_PLANEDEF, control.GetSelection())

            isUVControl = control.GetSelection() == 3

            for name in ('qUhSpinCtrl', 'qUkSpinCtrl', 'qUlSpinCtrl', 'qVhSpinCtrl', 'qVkSpinCtrl', 'qVlSpinCtrl'):
                self.getControl(name).Enable(isUVControl)
                pass
            pass
        elif controlName == 'psiTextCtrl':
            mainFrame.SetParameter(qspace.TAG_QRGRAPH_PSI0, decimal.Decimal(control.GetValue()))
            pass
        elif controlName == 'chiTextCtrl':
            mainFrame.SetParameter(qspace.TAG_QRGRAPH_CHI0, decimal.Decimal(control.GetValue()))
            pass
        elif controlName == 'phiTextCtrl':
            mainFrame.SetParameter(qspace.TAG_QRGRAPH_PHI0, decimal.Decimal(control.GetValue()))
            pass
        elif controlName == 'rotateAxisComboBox':
            mainFrame.SetParameter(qspace.TAG_QRGRAPH_ROTATEAXIS, control.GetSelection())
            pass
        elif controlName == 'intervalTextCtrl':
            mainFrame.SetParameter(qspace.TAG_QRGRAPH_INTERVAL, decimal.Decimal(control.GetValue()))
            pass
        elif controlName == 'nstepSpinCtrl':
            mainFrame.SetParameter(qspace.TAG_QRGRAPH_NSTEP, control.GetValue())
            pass
        elif controlName == 'etminTextCtrl' or controlName == 'etmaxTextCtrl':
            etmin = decimal.Decimal(self.getControl('etminTextCtrl').GetValue())
            etmax = decimal.Decimal(self.getControl('etmaxTextCtrl').GetValue())

            if etmax <= etmin:
                wx.MessageBox("Etmin must be smaller than Etmax.",
                              "Illegal energy range error")
                return

            if controlName == 'etminTextCtrl':
                mainFrame.SetParameter(qspace.TAG_QRGRAPH_ETMIN, etmin)
                pass
            elif controlName == 'etmaxTextCtrl':
                mainFrame.SetParameter(qspace.TAG_QRGRAPH_ETMAX, etmax)
                pass
            pass

        self.GetParent().UpdateQRegionGraphCutPlane()
        return

    def PopupQRegionGraphDialog(self, event):
        etmin = decimal.Decimal(self.getControl('etminTextCtrl').GetValue())
        etmax = decimal.Decimal(self.getControl('etmaxTextCtrl').GetValue())
        step = decimal.Decimal(self.getControl('step').GetValue())
        deltaE = decimal.Decimal(self.getControl('delta e').GetValue())

        dialog = QRegionGraphDialog(self, etmin, etmax, step, deltaE)
        dialog.Show()
        return

class SampleInformationDialog(xrc.base.DialogBase):
    @staticmethod
    def __getImage(filename):
        import os

        image = wx.Image(os.path.join(os.path.abspath(os.path.dirname(__file__)), filename), wx.BITMAP_TYPE_ANY)
        return image.ConvertToBitmap()

    def __init__(self, parent):
        xrc.base.DialogBase.__init__(self, parent, 'resources/SampleInfoDlg.xrc', "SampleInfoDlg")

        comboBox = self.getControl('ltcSysComboBox')

        self.__mainFrame = parent

        while not isinstance(self.__mainFrame, wx.Frame):
            self.__mainFrame = self.__mainFrame.GetParent()
            pass

        textBox = self.getControl('sampleNameTextCtrl')
        textBox.SetValue(self.__mainFrame.GetParameter(qspace.TAG_SAMPLE_NAME))

        for item in qspace.Lattice.LATTICE_SYSTEMS.keys():
            comboBox.Append(item)
            pass
        comboBox.SetStringSelection(self.__mainFrame.GetParameter(qspace.TAG_SAMPLE_LTCSYS))
        comboBox.Bind(wx.EVT_COMBOBOX, self.ComboBoxSelected)

        comboBox = self.getControl('ltcKindComboBox')

        for item in qspace.Lattice.LATTICE_SYSTEMS[self.__mainFrame.GetParameter(qspace.TAG_SAMPLE_LTCSYS)]:
            comboBox.Append(item)
            pass
        comboBox.SetStringSelection(self.__mainFrame.GetParameter(qspace.TAG_SAMPLE_LTCKIND))
        comboBox.Bind(wx.EVT_COMBOBOX, self.ComboBoxSelected)

        figurePanel = self.getControl('ltcFigPanel')
        figurePanel.Bind(wx.EVT_PAINT, self.UpdateLatticeFigure)

        lattice = self.__mainFrame.GetLattice()

        initialDataTable = {'aTextCtrl': (qspace.TAG_SAMPLE_A, '0.001', '10000.0'),
                            'bTextCtrl': (qspace.TAG_SAMPLE_B, '0.001', '10000.0'),
                            'cTextCtrl': (qspace.TAG_SAMPLE_C, '0.001', '10000.0'),
                            'alphaTextCtrl': (qspace.TAG_SAMPLE_ALPHA, '0.0', '180.0'),
                            'betaTextCtrl': (qspace.TAG_SAMPLE_BETA, '0.0', '180.0'),
                            'gammaTextCtrl': (qspace.TAG_SAMPLE_GAMMA, '0.0', '180.0'),
                            'uhTextCtrl': (qspace.TAG_SAMPLE_UH, '-100.0', '100.0'),
                            'ukTextCtrl': (qspace.TAG_SAMPLE_UK, '-100.0', '100.0'),
                            'ulTextCtrl': (qspace.TAG_SAMPLE_UL, '-100.0', '100.0'),
                            'vhTextCtrl': (qspace.TAG_SAMPLE_VH, '-100.0', '100.0'),
                            'vkTextCtrl': (qspace.TAG_SAMPLE_VK, '-100.0', '100.0'),
                            'vlTextCtrl': (qspace.TAG_SAMPLE_VL, '-100.0', '100.0')}

        for name, parameters in initialDataTable.items():
            text = self.getControl(name)
            text.SetValidator(DecimalValidator(parameters[1], parameters[2]))
            text.SetValue(str(self.__mainFrame.GetParameter(parameters[0])))
            pass

        text = self.getControl('rotUhTextCtrl').SetValue(str(lattice.rotUh))
        text = self.getControl('rotUkTextCtrl').SetValue(str(lattice.rotUk))
        text = self.getControl('rotUlTextCtrl').SetValue(str(lattice.rotUl))
        text = self.getControl('rotVhTextCtrl').SetValue(str(lattice.rotVh))
        text = self.getControl('rotVkTextCtrl').SetValue(str(lattice.rotVk))
        text = self.getControl('rotVlTextCtrl').SetValue(str(lattice.rotVl))

        self.__UpdateLatticeInput()

        self.__latticeFigures = dict()
        self.__latticeFigures[qspace.Lattice.LT_SYS_TRICLINIC] = dict()
        self.__latticeFigures[qspace.Lattice.LT_SYS_TRICLINIC][qspace.Lattice.LT_TYPE_SIMPLE] = SampleInformationDialog.__getImage('figs/triclinic_simple.png')
        self.__latticeFigures[qspace.Lattice.LT_SYS_MONOCLINIC] = dict()
        self.__latticeFigures[qspace.Lattice.LT_SYS_MONOCLINIC][qspace.Lattice.LT_TYPE_SIMPLE] = SampleInformationDialog.__getImage('figs/monoclinic_simple.png')
        self.__latticeFigures[qspace.Lattice.LT_SYS_MONOCLINIC][qspace.Lattice.LT_TYPE_BASE_CENTERED] = SampleInformationDialog.__getImage('figs/monoclinic_base_centered.png')
        self.__latticeFigures[qspace.Lattice.LT_SYS_ORTHORHOMBIC] = dict()
        self.__latticeFigures[qspace.Lattice.LT_SYS_ORTHORHOMBIC][qspace.Lattice.LT_TYPE_SIMPLE] = SampleInformationDialog.__getImage('figs/orthorHombic_simple.png')
        self.__latticeFigures[qspace.Lattice.LT_SYS_ORTHORHOMBIC][qspace.Lattice.LT_TYPE_BASE_CENTERED] = SampleInformationDialog.__getImage('figs/orthorHombic_base_centered.png')
        self.__latticeFigures[qspace.Lattice.LT_SYS_ORTHORHOMBIC][qspace.Lattice.LT_TYPE_BODY_CENTERED] = SampleInformationDialog.__getImage('figs/orthorHombic_body_centered.png')
        self.__latticeFigures[qspace.Lattice.LT_SYS_ORTHORHOMBIC][qspace.Lattice.LT_TYPE_FACE_CENTERED] = SampleInformationDialog.__getImage('figs/orthorHombic_face_centered.png')
        self.__latticeFigures[qspace.Lattice.LT_SYS_TETRAGONAL] = dict()
        self.__latticeFigures[qspace.Lattice.LT_SYS_TETRAGONAL][qspace.Lattice.LT_TYPE_SIMPLE] = SampleInformationDialog.__getImage('figs/tetragonal_simple.png')
        self.__latticeFigures[qspace.Lattice.LT_SYS_TETRAGONAL][qspace.Lattice.LT_TYPE_BODY_CENTERED] = SampleInformationDialog.__getImage('figs/tetragonal_body_centered.png')
        self.__latticeFigures[qspace.Lattice.LT_SYS_TRIGONAL] = dict()
        self.__latticeFigures[qspace.Lattice.LT_SYS_TRIGONAL][qspace.Lattice.LT_TYPE_RHOMBOHEDRAL] = SampleInformationDialog.__getImage('figs/trigonal_rhombohedral.png')
        self.__latticeFigures[qspace.Lattice.LT_SYS_HEXAGONAL] = dict()
        self.__latticeFigures[qspace.Lattice.LT_SYS_HEXAGONAL][qspace.Lattice.LT_TYPE_SIMPLE] = SampleInformationDialog.__getImage('figs/hexagonal_simple.png')
        self.__latticeFigures[qspace.Lattice.LT_SYS_CUBIC] = dict()
        self.__latticeFigures[qspace.Lattice.LT_SYS_CUBIC][qspace.Lattice.LT_TYPE_SIMPLE] = SampleInformationDialog.__getImage('figs/cubic_simple.png')
        self.__latticeFigures[qspace.Lattice.LT_SYS_CUBIC][qspace.Lattice.LT_TYPE_BODY_CENTERED] = SampleInformationDialog.__getImage('figs/cubic_body_centered.png')
        self.__latticeFigures[qspace.Lattice.LT_SYS_CUBIC][qspace.Lattice.LT_TYPE_FACE_CENTERED] = SampleInformationDialog.__getImage('figs/cubic_face_centered.png')
        return

    def UpdateLatticeFigure(self, event):
        system = self.getControl('ltcSysComboBox').GetStringSelection()
        type = self.getControl('ltcKindComboBox').GetStringSelection()

        panel = self.getControl('ltcFigPanel')

        dc = wx.ClientDC(panel)
        dc.SetTextBackground(wx.WHITE)
        dc.Clear()
        dc.DrawBitmap(self.__latticeFigures[system][type], 0, 0, False)

        if event != None:
            event.Skip()
            pass
        return

    def ComboBoxSelected(self, event):
        comboBox = event.GetEventObject()

        if comboBox.GetName() == 'ltcSysComboBox':
            typeComboBox = self.getControl('ltcKindComboBox')

            typeComboBox.Clear()
            for item in qspace.Lattice.LATTICE_SYSTEMS[comboBox.GetStringSelection()]:
                typeComboBox.Append(item)
                pass
            typeComboBox.SetSelection(0)

            self.__UpdateLatticeInput()
            pass

        self.UpdateLatticeFigure(None)
        return

    def __UpdateLatticeInput(self):
        system = self.getControl('ltcSysComboBox').GetStringSelection()

        a = str(self.__mainFrame.GetParameter(qspace.TAG_SAMPLE_A))
        alpha = str(self.__mainFrame.GetParameter(qspace.TAG_SAMPLE_ALPHA))

        if system == qspace.Lattice.LT_SYS_TRICLINIC:
            self.__LatticeParameterInputControl((True, True, True, True, True, True))
            pass
        elif system == qspace.Lattice.LT_SYS_MONOCLINIC:
            self.__LatticeParameterInputControl((True, True, True, False, True, False))
            self.__SetLatticeParameter((None, None, None, '90', None, '90'))
            pass
        elif system == qspace.Lattice.LT_SYS_ORTHORHOMBIC:
            self.__LatticeParameterInputControl((True, True, True, False, False, False))
            self.__SetLatticeParameter((None, None, None, '90', '90', '90'))
            pass
        elif system == qspace.Lattice.LT_SYS_TETRAGONAL:
            self.__LatticeParameterInputControl((True, False, True, False, False, False))
            self.__SetLatticeParameter((None, a, None, '90', '90', '90'))
            pass
        elif system == qspace.Lattice.LT_SYS_TRIGONAL:
            self.__LatticeParameterInputControl((True, False, False, True, False, False))
            self.__SetLatticeParameter((None, a, a, None, alpha, alpha))
            pass
        elif system == qspace.Lattice.LT_SYS_HEXAGONAL:
            self.__LatticeParameterInputControl((True, False, True, False, False, False))
            self.__SetLatticeParameter((None, a, None, '90', '90', '120'))
            pass
        elif system == qspace.Lattice.LT_SYS_CUBIC:
            self.__LatticeParameterInputControl((True, False, False, False, False, False))
            self.__SetLatticeParameter((None, a, a, '90', '90', '90'))
            pass
        return

    def __LatticeParameterInputControl(self, enables):
        nameList = ('aTextCtrl', 'bTextCtrl', 'cTextCtrl', 'alphaTextCtrl', 'betaTextCtrl', 'gammaTextCtrl')

        for i in xrange(len(nameList)):
            self.getControl(nameList[i]).Enable(enables[i])
            pass
        return

    def __SetLatticeParameter(self, parameters):
        nameList = ('aTextCtrl', 'bTextCtrl', 'cTextCtrl', 'alphaTextCtrl', 'betaTextCtrl', 'gammaTextCtrl')

        for i in xrange(len(nameList)):
            if parameters[i] != None:
                self.getControl(nameList[i]).SetValue(parameters[i])
                pass
            pass
        return

    def GetSampleName(self):
        return self.getControl('sampleNameTextCtrl').GetValue()

    def GetLatticeSystem(self):
        comboBox = self.getControl('ltcSysComboBox')
        return comboBox.GetStringSelection()

    def GetLatticeSystemKind(self):
        comboBox = self.getControl('ltcKindComboBox')
        return comboBox.GetStringSelection()

    def GetInputParameters(self):
        parameters = dict()

        textControlList = {qspace.TAG_SAMPLE_A: 'aTextCtrl',
                           qspace.TAG_SAMPLE_B: 'bTextCtrl',
                           qspace.TAG_SAMPLE_C: 'cTextCtrl',
                           qspace.TAG_SAMPLE_ALPHA: 'alphaTextCtrl',
                           qspace.TAG_SAMPLE_BETA: 'betaTextCtrl',
                           qspace.TAG_SAMPLE_GAMMA: 'gammaTextCtrl',
                           qspace.TAG_SAMPLE_UH: 'uhTextCtrl',
                           qspace.TAG_SAMPLE_UK: 'ukTextCtrl',
                           qspace.TAG_SAMPLE_UL: 'ulTextCtrl',
                           qspace.TAG_SAMPLE_VH: 'vhTextCtrl',
                           qspace.TAG_SAMPLE_VK: 'vkTextCtrl',
                           qspace.TAG_SAMPLE_VL: 'vlTextCtrl'}

        for key in textControlList.keys():
            parameters[key] = self.getControl(textControlList[key]).GetValue()
            pass
        return parameters

class QRegionGraphDialog(xrc.base.DialogBase):
    def __init__(self, parent, etmin, etmax, step, deltaE):
        xrc.base.DialogBase.__init__(self, parent, 'resources/QRegionGraphWindow.xrc', 'QRegionGraphWindow')

        panel = self.getControl('QRegionGraphPanel')
        self.__qRegionGraphPanel = VTKPanel.QRegionGraphPanel(panel)

        panel.GetSizer().Add(self.__qRegionGraphPanel)
        panel.Bind(wx.EVT_SIZE, self.resize)

        panel = self.getControl('check box panel')
        sizer = panel.GetSizer()

        self.__checkBoxes = []

        diff = (etmax - etmin) / step
        for i in xrange(step + 1):
            stepEmin = etmin + diff * i - deltaE / 2
            stepEmax = stepEmin + deltaE
            checkBox = wx.CheckBox(panel, wx.ID_ANY, '%.3f - %.3f' % (stepEmin, stepEmax))
            checkBox.SetValue(True)
            checkBox.Bind(wx.EVT_CHECKBOX, self.graphControl)
            sizer.Add(checkBox, flag = wx.TOP | wx.LEFT | wx.RIGHT, border = 5)

            self.__checkBoxes.append(checkBox)

            self.__qRegionGraphPanel.SetupGraph(float(stepEmin), float(stepEmax), i)
            pass
        self.__qRegionGraphPanel.SetupLight()
        self.__qRegionGraphPanel.SetupCamera()
        self.__qRegionGraphPanel.SetLegendBox()

        self.Fit()

        button = self.getControl('wxID_OK')
        button.Bind(wx.EVT_BUTTON, self.close)
        self.Bind(wx.EVT_CLOSE, self.close)
        return

    def graphControl(self, event):
        checkBox = event.GetEventObject()

        self.__qRegionGraphPanel.GraphControl(self.__checkBoxes.index(checkBox), checkBox.GetValue())
        return

    def close(self, event):
        self.Destroy()
        return

    def resize(self, event):
        self.__qRegionGraphPanel.SetSize(event.GetSize())
        return

class ObjectSettingDialog(xrc.base.DialogBase):
    def __init__(self, parent):
        xrc.base.DialogBase.__init__(self, parent, 'resources/Obj3dSetsDlg.xrc', 'Obj3dSetsDlg')

        radioBox = self.getControl('QpColorRadioBox')
        radioBox.Bind(wx.EVT_RADIOBOX, self.UpdateSettings)
        radioBox.SetSelection(parent.GetParameter(qspace.TAG_OBJ3D_QPCOLOR))
        radioBox = self.getControl('QpDisplayRadioBox')
        radioBox.Bind(wx.EVT_RADIOBOX, self.UpdateSettings)
        radioBox.SetSelection(parent.GetParameter(qspace.TAG_OBJ3D_QPDISPLAY))

        spinControl = self.getControl('pixelNoSpinCtrl')
        spinControl.Bind(wx.EVT_SPINCTRL, self.UpdateSettings)
        spinControl = self.getControl('pixelRangeSpinCtrl')
        spinControl.Bind(wx.EVT_SPINCTRL, self.UpdateSettings)

        radioBox = self.getControl('surfScalarRadioBox')
        radioBox.SetStringSelection(parent.GetParameter(qspace.TAG_OBJ3D_SURFSCALAR))
        radioBox.EnableItem(1, parent.IsMeasurementDataLoaded())
        radioBox.Bind(wx.EVT_RADIOBOX, self.UpdateSettings)

        text = self.getControl('q point size')
        text.Bind(wx.EVT_TEXT_ENTER, self.UpdateSettings)
        text.SetValue(str(self.GetParent().GetQPointSize()))

        etMin, etMax = parent.GetScalarFieldRange(define.ENERGY_TRANSFER)

        etMin = decimal.Decimal(str(etMin))
        etMax = decimal.Decimal(str(etMax))
        widthMax = max(abs(etMin), abs(etMax))

        value = parent.GetParameter(qspace.TAG_OBJ3D_ETVAL)

        text = self.getControl('etVTextCtrl')
        text.SetValue(str(value))
        text.SetValidator(DecimalValidator(etMin, etMax))
        text.Bind(wx.EVT_TEXT_ENTER, self.UpdateSettings)
        text.Bind(wx.EVT_LEAVE_WINDOW, self.UpdateSettings)

        label = self.getControl('etVMinText')
        label.SetLabel(str(etMin))

        slider = self.getControl('etVSlider')
        slider.SetRange(int(etMin * FPS), int(etMax * FPS))
        slider.SetValue(int(value * FPS))
        slider.Bind(wx.EVT_SCROLL, self.UpdateSettings)

        label = self.getControl('etVMaxText')
        label.SetLabel(str(etMax))

        value = parent.GetParameter(qspace.TAG_OBJ3D_ETWIDTH)

        text = self.getControl('etWTextCtrl')
        text.SetValue(str(value))
        text.SetValidator(DecimalValidator(decimal.Decimal(0), widthMax))
        text.Bind(wx.EVT_TEXT_ENTER, self.UpdateSettings)
        text.Bind(wx.EVT_LEAVE_WINDOW, self.UpdateSettings)

        label = self.getControl('etWMinText')
        label.SetLabel('0.0')

        slider = self.getControl('etWSlider')
        slider.SetRange(0, int(widthMax * FPS))
        slider.SetValue(int(value * FPS))
        slider.Bind(wx.EVT_SCROLL, self.UpdateSettings)

        label = self.getControl('etWMaxText')
        label.SetLabel(str(widthMax))

        button = self.getControl('axisSetsButton')
        button.Bind(wx.EVT_BUTTON, self.PopupAxisSettingDialog)

        button = self.getControl('wxID_OK')
        button.Bind(wx.EVT_BUTTON, self.ApplySettings)
        return

    def PopupAxisSettingDialog(self, event):
        dlg = AxisSettingDialog(self)

        if dlg.ShowModal() == wx.ID_OK:
            dlg.UpdateSettings()
            pass
        return

    def UpdateSettings(self, event):
        control = event.GetEventObject()
        controlName = control.GetName()

        mainFrame = self.GetParent()

        if controlName == 'QpColorRadioBox':
            mainFrame.SetParameter(qspace.TAG_OBJ3D_QPCOLOR, control.GetSelection())
            pass
        elif controlName == 'QpDisplayRadioBox':
            mainFrame.SetParameter(qspace.TAG_OBJ3D_QPDISPLAY, control.GetSelection())
            pass
        elif controlName == 'pixelNoSpinCtrl':
            mainFrame.SetParameter(qspace.TAG_OBJ3D_PXNO, control.GetValue())
            pass
        elif controlName == 'pixelRangeSpinCtrl':
            mainFrame.SetParameter(qspace.TAG_OBJ3D_PXRANGE, control.GetValue())
            pass
        elif controlName == 'surfScalarRadioBox':
            mainFrame.SetParameter(qspace.TAG_OBJ3D_SURFSCALAR, control.GetStringSelection())
            pass
        elif controlName == 'q point size':
            mainFrame.SetQPointSize(float(control.GetValue()))
            pass
        elif controlName == 'etVTextCtrl':
            value = decimal.Decimal(control.GetValue())
            value = decimal.Decimal(int(value * FPS)) / FPS
            mainFrame.SetParameter(qspace.TAG_OBJ3D_ETVAL, value)

            self.getControl('etVSlider').SetValue(int(value * FPS))
            pass
        elif controlName == 'etVSlider':
            value = decimal.Decimal(control.GetValue()) / FPS
            mainFrame.SetParameter(qspace.TAG_OBJ3D_ETVAL, value)

            self.getControl('etVTextCtrl').SetValue(str(value))
            pass
        elif controlName == 'etWTextCtrl':
            value = decimal.Decimal(control.GetValue())
            value = decimal.Decimal(int(value * FPS)) / FPS
            mainFrame.SetParameter(qspace.TAG_OBJ3D_ETWIDTH, value)

            self.getControl('etWSlider').SetValue(int(value * FPS))
            pass
        elif controlName == 'etWSlider':
            value = decimal.Decimal(control.GetValue()) / FPS
            mainFrame.SetParameter(qspace.TAG_OBJ3D_ETWIDTH, value)

            self.getControl('etWTextCtrl').SetValue(str(value))
            pass

        mainFrame.SetQPointColor()
        mainFrame.SetQPointOpacity()
        return

    def ApplySettings(self, event):
        self.GetParent().SetQPointSize(float(self.getControl('q point size').GetValue()))

        self.GetParent().ApplySettings()
        event.Skip()
        return

class ScalarRangeDialog(xrc.base.DialogBase):
    def __init__(self, parent):
        xrc.base.DialogBase.__init__(self, parent, 'resources/ScalarRangeDlg.xrc', 'ScalarRangeDlg')

        radioButton = self.getControl('autoRadioButton')
        radioButton.Bind(wx.EVT_RADIOBUTTON, self.ModeChange)

        radioButton = self.getControl('manualRadioButton')
        radioButton.Bind(wx.EVT_RADIOBUTTON, self.ModeChange)

        self.__mainFrame = parent

        while not isinstance(self.__mainFrame, wx.Frame):
            self.__mainFrame = self.__mainFrame.GetParent()
            pass

        if self.__mainFrame.GetScalarKind() == define.ENERGY_TRANSFER:
            modeParameterName = qspace.TAG_OBJ3D_ETRANGE_MODE
            pass
        else:
            modeParameterName = qspace.TAG_OBJ3D_INTENSITYRANGE_MODE
            pass

        if self.__mainFrame.GetParameter(modeParameterName) != 'auto':
            radioButton.SetValue(True)

            if self.__mainFrame.GetScalarKind() == define.ENERGY_TRANSFER:
                minParameterName = qspace.TAG_OBJ3D_ETRANGE_MIN
                maxParameterName = qspace.TAG_OBJ3D_INTENSITYRANGE_MAX
                pass
            else:
                minParameterName = qspace.TAG_OBJ3D_INTENSITYRANGE_MIN
                maxParameterName = qspace.TAG_OBJ3D_ETRANGE_MAX
                pass

            text = self.getControl('minTextCtrl')
            text.SetValue(str(self.__mainFrame.GetParameter(minParameterName)))

            text = self.getControl('maxTextCtrl')
            text.SetValue(str(self.__mainFrame.GetParameter(maxParameterName)))
            pass

        button = self.getControl('wxID_OK')
        button.Bind(wx.EVT_BUTTON, self.InputCheck)

        self.ModeChange(None)
        return

    def ModeChange(self, evnet):
        if self.getControl('autoRadioButton').GetValue():
            etMin, etMax = self.GetParent().GetScalarFieldRange(define.ENERGY_TRANSFER)

            text = self.getControl('minTextCtrl')
            text.SetValue(str(etMin))
            text.Enable(False)

            text = self.getControl('maxTextCtrl')
            text.SetValue(str(etMax))
            text.Enable(False)
            pass
        else:
            self.getControl('minTextCtrl').Enable(True)
            self.getControl('maxTextCtrl').Enable(True)
            pass
        return

    def InputCheck(self, event):
        min = decimal.Decimal(self.getControl('minTextCtrl').GetValue())
        max = decimal.Decimal(self.getControl('maxTextCtrl').GetValue())

        if max < min:
            wx.MessageBox("Min value must be smaller than max value.",
                          "Illegal energy range error")
            return

        event.Skip()
        return

    def UpdateSettings(self):
        if self.__mainFrame.GetScalarKind() == define.ENERGY_TRANSFER:
            modeParameterName = qspace.TAG_OBJ3D_ETRANGE_MODE
            minParameterName = qspace.TAG_OBJ3D_ETRANGE_MIN
            maxParameterName = qspace.TAG_OBJ3D_INTENSITYRANGE_MAX
            pass
        else:
            modeParameterName = qspace.TAG_OBJ3D_INTENSITYRANGE_MODE
            minParameterName = qspace.TAG_OBJ3D_INTENSITYRANGE_MIN
            maxParameterName = qspace.TAG_OBJ3D_ETRANGE_MAX
            pass

        if self.getControl('autoRadioButton').GetValue():
            self.__mainFrame.SetParameter(modeParameterName, 'auto')
            pass
        else:
            self.__mainFrame.SetParameter(modeParameterName, 'manual')
            pass

        text = self.getControl('minTextCtrl')
        self.__mainFrame.SetParameter(minParameterName, decimal.Decimal(str(text.GetValue())))

        text = self.getControl('maxTextCtrl')
        self.__mainFrame.SetParameter(maxParameterName, decimal.Decimal(str(text.GetValue())))
        return

class AxisSettingDialog(xrc.base.DialogBase):
    def __init__(self, parent):
        xrc.base.DialogBase.__init__(self, parent, 'resources/AxisSetsDlg.xrc', 'AxisSetsDlg')

        mainFrame = parent.GetParent()

        text = self.getControl('qxMarginTextCtrl')
        text.SetValue(str(mainFrame.GetParameter(qspace.TAG_GRAPH_AXISMARGIN_X)))
        text.SetValidator(DecimalValidator(decimal.Decimal(0), decimal.Decimal(10)))

        checkBox = self.getControl('xAxisCheckBox')
        checkBox.SetValue(mainFrame.GetParameter(qspace.TAG_GRAPH_AXISDISPLAY_X))

        text = self.getControl('qyMarginTextCtrl')
        text.SetValue(str(mainFrame.GetParameter(qspace.TAG_GRAPH_AXISMARGIN_Y)))
        text.SetValidator(DecimalValidator(decimal.Decimal(0), decimal.Decimal(10)))

        checkBox = self.getControl('yAxisCheckBox')
        checkBox.SetValue(mainFrame.GetParameter(qspace.TAG_GRAPH_AXISDISPLAY_Y))

        text = self.getControl('qzMarginTextCtrl')
        text.SetValue(str(mainFrame.GetParameter(qspace.TAG_GRAPH_AXISMARGIN_Z)))
        text.SetValidator(DecimalValidator(decimal.Decimal(0), decimal.Decimal(10)))

        checkBox = self.getControl('zAxisCheckBox')
        checkBox.SetValue(mainFrame.GetParameter(qspace.TAG_GRAPH_AXISDISPLAY_Z))
        return

    def UpdateSettings(self):
        mainFrame = self.GetParent().GetParent()

        text = self.getControl('qxMarginTextCtrl')
        mainFrame.SetParameter(qspace.TAG_GRAPH_AXISMARGIN_X, decimal.Decimal(text.GetValue()))

        checkBox = self.getControl('xAxisCheckBox')
        mainFrame.SetParameter(qspace.TAG_GRAPH_AXISDISPLAY_X, checkBox.GetValue())

        text = self.getControl('qyMarginTextCtrl')
        mainFrame.SetParameter(qspace.TAG_GRAPH_AXISMARGIN_Y, decimal.Decimal(text.GetValue()))

        checkBox = self.getControl('yAxisCheckBox')
        mainFrame.SetParameter(qspace.TAG_GRAPH_AXISDISPLAY_Y, checkBox.GetValue())

        text = self.getControl('qzMarginTextCtrl')
        mainFrame.SetParameter(qspace.TAG_GRAPH_AXISMARGIN_Z, decimal.Decimal(text.GetValue()))

        checkBox = self.getControl('zAxisCheckBox')
        mainFrame.SetParameter(qspace.TAG_GRAPH_AXISDISPLAY_Z, checkBox.GetValue())
        return

class ProgressBarDialog(xrc.base.DialogBase):
    def __init__(self, parent, text, maxValue):
        xrc.base.DialogBase.__init__(self, parent, 'resources/ProgressBarDialog.xrc', 'progress bar dialog')

        label = self.getControl('label')
        label.SetLabel(text)

        gauge = self.getControl('gauge')

        gauge.SetRange(maxValue)

        if maxValue == 0:
            gauge.Pulse()
            pass

        self.getControl('panel').GetSizer().Layout()
        self.Fit()
        self.CenterOnParent()
        return

    def Update(self, event):
        gauge = self.getControl('gauge')

        if gauge.GetRange() != 0:
            if gauge.GetValue() == gauge.GetRange():
                self.Close()
                pass

            gauge.SetValue(gauge.GetValue() + 1)
            pass
        else:
            gauge.Pulse()
            pass
        return

class QPointInformationDialog(xrc.base.DialogBase):
    def __init__(self, parent, info):
        xrc.base.DialogBase.__init__(self, parent, 'resources/QpInfoDlg.xrc', 'QpInfoDlg')

        self.getControl('QpInfoTextCtrl').SetValue(info)
        return
