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

import threading
import time

EVT_WORKER_FINISHED_ID = wx.NewId()

def EVT_WORKER_FINISHED(win, func):
    win.Connect(-1, -1, EVT_WORKER_FINISHED_ID, func)
    return

class WorkerThread(threading.Thread):
    def __init__(self, workerMethod, notifyReceiver = None):
        threading.Thread.__init__(self)
        self.__workerMethod = workerMethod
        self.__notifyReceiver = notifyReceiver
        return

    def run(self):
        self.__workerMethod()

        if self.__notifyReceiver != None:
            event = wx.PyEvent()
            event.SetEventType(EVT_WORKER_FINISHED_ID)
            wx.PostEvent(self.__notifyReceiver, event)
            pass
        return

EVT_WATCHER_UPDATE_ID = wx.NewId()

def EVT_WATCHER_UPDATE(win, func):
    win.Connect(-1, -1, EVT_WATCHER_UPDATE_ID, func)
    return

class WorkerWatcher(threading.Thread):
    def __init__(self, workerMethod, updateReceiver = None, notifyReceiver = None):
        threading.Thread.__init__(self)
        self.__workerMethod = workerMethod
        self.__updateReceiver = updateReceiver
        self.__notifyReceiver = notifyReceiver
        return

    def run(self):
        worker = WorkerThread(self.__workerMethod, self.__notifyReceiver)
        worker.start()

        event = wx.PyEvent()
        event.SetEventType(EVT_WATCHER_UPDATE_ID)

        while worker.isAlive():
            if self.__updateReceiver != None:
                wx.PostEvent(self.__updateReceiver, event)
                pass

            time.sleep(0.1)
            pass
        return

import xrc.base
import VTKPanel
import qspace
import vector
import dialog
import define

class MainFrame(xrc.base.FrameBase):
    def __init__(self, mode):
        xrc.base.FrameBase.__init__(self, 'resources/MainFrame.xrc', 'MainFrame')

        self.__mode = mode
        self.__isMeasurementDataLoaded = False

        self.__qPointSize = 0.01

        panel = self.getControl('VtkWindow')

        self.__vtkPanel = VTKPanel.VTKPanel(panel)

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

        listControl = self.getControl('QpListCtrl')
        listControl.Bind(wx.EVT_LIST_COL_CLICK, self.lstColumnClick)
        listControl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.lstSelected)
        listControl.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.lstDeselected)
        listControl.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.lstActivated)
        listControl.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.lstRightClicked)

        self.__qSpaceManager = qspace.QSpaceManager(mode)

        self.__createMenuBar()
        self.__createToolBar()

        self.__lstSortMode = 'IJK'
        self.__updateQPointList()
        self.UpdateView()

        self.Fit()

        self.__rotationControlDialog = dialog.RotationControlDialog(self)

        self.__vtkPanel.CreateQEGraphPlane()
        self.__vtkPanel.CreateQRegionGraphPlane()

        EVT_WORKER_FINISHED(self, self.WorkerFinished)
        return

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

    def __createMenuBar(self):
        menuBar = wx.MenuBar()
        self.SetMenuBar(menuBar)

        self.__createFileMenu(menuBar)
        self.__createViewMenu(menuBar)
        self.__createDisplayControlMenu(menuBar)
        self.__createRegionMenu(menuBar)
        self.__createControlMenu(menuBar)
        self.__createGraphMenu(menuBar)
        return

    def __createFileMenu(self, menuBar):
        self.__fileMenu = wx.Menu()

        menuItem = self.__fileMenu.Append(wx.ID_ANY, 'Sample Information')
        self.Bind(wx.EVT_MENU, self.PopupSampleInformationDialog, menuItem)

        self.__fileMenu.AppendSeparator()

        menuItem = self.__fileMenu.Append(wx.ID_ANY, 'Load method file')
        self.Bind(wx.EVT_MENU, self.MethodFileAccess, menuItem)

        menuItem = self.__fileMenu.Append(wx.ID_ANY, 'Save method file')
        self.Bind(wx.EVT_MENU, self.MethodFileAccess, menuItem)

        self.__fileMenu.AppendSeparator()

        import platform

        if platform.system() == 'Windows':
            menuItem = self.__fileMenu.Append(wx.ID_ANY, 'Load NeXus file')
            self.Bind(wx.EVT_MENU, self.LoadDataFile, menuItem)
            pass

        menuItem = self.__fileMenu.Append(wx.ID_ANY, 'Load Boost file')
        self.Bind(wx.EVT_MENU, self.LoadDataFile, menuItem)

        self.__fileMenu.AppendSeparator()

        menuItem = self.__fileMenu.Append(wx.ID_ANY, 'Exit')
        self.Bind(wx.EVT_MENU, self.close, menuItem)

        menuBar.Append(self.__fileMenu, 'File')
        return

    def __createViewMenu(self, menuBar):
        self.__viewMenu = wx.Menu()

        menuItem = self.__viewMenu.Append(wx.ID_ANY, 'qx view\tCtrl-X')
        self.Bind(wx.EVT_MENU, self.ViewControl, menuItem)
        menuItem = self.__viewMenu.Append(wx.ID_ANY, 'qy view\tCtrl-Y')
        self.Bind(wx.EVT_MENU, self.ViewControl, menuItem)
        menuItem = self.__viewMenu.Append(wx.ID_ANY, 'qz view\tCtrl-Z')
        self.Bind(wx.EVT_MENU, self.ViewControl, menuItem)

        self.__viewMenu.AppendSeparator()

        menuItem = self.__viewMenu.Append(wx.ID_ANY, 'qa view')
        self.Bind(wx.EVT_MENU, self.ViewControl, menuItem)
        menuItem = self.__viewMenu.Append(wx.ID_ANY, 'qb view')
        self.Bind(wx.EVT_MENU, self.ViewControl, menuItem)
        menuItem = self.__viewMenu.Append(wx.ID_ANY, 'qc view')
        self.Bind(wx.EVT_MENU, self.ViewControl, menuItem)

        self.__viewMenu.AppendSeparator()

        menuItem = self.__viewMenu.AppendRadioItem(wx.ID_ANY, 'Perspective view')
        self.Bind(wx.EVT_MENU, self.ProjectionControl, menuItem)
        menuItem = self.__viewMenu.AppendRadioItem(wx.ID_ANY, 'Parallel-projection view')
        self.Bind(wx.EVT_MENU, self.ProjectionControl, menuItem)

        menuBar.Append(self.__viewMenu, 'View')
        return

    def IsMeasurementDataLoaded(self):
        return self.__isMeasurementDataLoaded

    def GetBounds(self):
        return self.__qSpaceManager.GetBounds()

    def ViewControl(self, event):
        item = self.__viewMenu.FindItemById(event.GetId())
        if item == None:
            item = self.__toolBar.FindById(event.GetId())
            operation = item.GetShortHelp()
            pass
        else:
            operation = item.GetLabel()
            pass

        bounds = self.GetBounds()

        if operation == 'qx view':
            self.__vtkPanel.CreateCameraView('qx', self.__qSpaceManager.GetBoundingSize(), self.__qSpaceManager.GetCenter(), bounds[1], bounds[3], bounds[5])
            pass
        elif operation == 'qy view':
            self.__vtkPanel.CreateCameraView('qy', self.__qSpaceManager.GetBoundingSize(), self.__qSpaceManager.GetCenter(), bounds[1], bounds[3], bounds[5])
            pass
        elif operation == 'qz view':
            self.__vtkPanel.CreateCameraView('qz', self.__qSpaceManager.GetBoundingSize(), self.__qSpaceManager.GetCenter(), bounds[1], bounds[3], bounds[5])
            pass
        else:
            import math

            xw = bounds[1] - bounds[0]
            yw = bounds[3] - bounds[2]
            zw = bounds[5] - bounds[4]
            scale = math.sqrt(xw * xw + yw * yw + zw * zw)

            if operation == 'qa view':
                self.__vtkPanel.CreateLatticeView('qa', self.__qSpaceManager.ltc.ra_rotate,
                                               self.__qSpaceManager.ltc.rb_rotate,
                                               self.__qSpaceManager.ltc.rc_rotate, scale)
                pass
            elif operation == 'qb view':
                self.__vtkPanel.CreateLatticeView('qb', self.__qSpaceManager.ltc.ra_rotate,
                                               self.__qSpaceManager.ltc.rb_rotate,
                                               self.__qSpaceManager.ltc.rc_rotate, scale)
                pass
            elif operation == 'qc view':
                self.__vtkPanel.CreateLatticeView('qc', self.__qSpaceManager.ltc.ra_rotate,
                                               self.__qSpaceManager.ltc.rb_rotate,
                                               self.__qSpaceManager.ltc.rc_rotate, scale)
                pass
            pass

        self.__vtkPanel.Render()
        return

    def ProjectionControl(self, event):
        item = self.__viewMenu.FindItemById(event.GetId())
        if item == None:
            item = self.__toolBar.FindById(event.GetId())
            operation = item.GetShortHelp()
            pass
        else:
            operation = item.GetLabel()
            pass

        if operation == 'Perspective view':
            self.__vtkPanel.ProjectionControl(False)
            pass
        else:
            self.__vtkPanel.ProjectionControl(True)
            pass
        return

    def __createDisplayControlMenu(self, menuBar):
        self.__displayControlMenu = wx.Menu()

        self.__regionSurfaceControlMenuItem = self.__displayControlMenu.AppendCheckItem(wx.ID_ANY, 'Show region surface')
        self.Bind(wx.EVT_MENU, self.DisplayControl, self.__regionSurfaceControlMenuItem)
        self.__contourLineMenuItem = self.__displayControlMenu.AppendCheckItem(wx.ID_ANY, 'Show Et contour line')
        self.Bind(wx.EVT_MENU, self.DisplayControl, self.__contourLineMenuItem)
        self.__contourLineMenuItem.Enable(False)
        self.__etIsosurfaceControlMenuItem = self.__displayControlMenu.AppendCheckItem(wx.ID_ANY, 'Show Et isosurface')
        self.Bind(wx.EVT_MENU, self.DisplayControl, self.__etIsosurfaceControlMenuItem)
        self.__qPointDisplayMenuItem = self.__displayControlMenu.AppendCheckItem(wx.ID_ANY, 'Show Q points')
        self.Bind(wx.EVT_MENU, self.DisplayControl, self.__qPointDisplayMenuItem)
        self.__elasticScatteringLineMenuItem = self.__displayControlMenu.AppendCheckItem(wx.ID_ANY, 'Show elastic-scattering line')
        self.Bind(wx.EVT_MENU, self.DisplayControl, self.__elasticScatteringLineMenuItem)
        self.__cellDisplayMenuItem = self.__displayControlMenu.AppendCheckItem(wx.ID_ANY, 'Show cell')
        self.Bind(wx.EVT_MENU, self.DisplayControl, self.__cellDisplayMenuItem)
        self.__rotationGuideControlMenuItem = self.__displayControlMenu.AppendCheckItem(wx.ID_ANY, 'Show rotation guide')
        self.Bind(wx.EVT_MENU, self.DisplayControl, self.__rotationGuideControlMenuItem)
        self.__pixelIsosurfaceControlMenuItem = self.__displayControlMenu.AppendCheckItem(wx.ID_ANY, 'Show pixel isosurface')
        self.Bind(wx.EVT_MENU, self.DisplayControl, self.__pixelIsosurfaceControlMenuItem)
        self.__latticeAxesControlMenuItem = self.__displayControlMenu.AppendCheckItem(wx.ID_ANY, 'Show lattice axes')
        self.Bind(wx.EVT_MENU, self.DisplayControl, self.__latticeAxesControlMenuItem)

        psdMenu = wx.Menu()
        self.__displayControlMenu.AppendSubMenu(psdMenu, 'Show PSDs ...')

        self.__regionNameMap = dict()
        self.__PSDMenuItems = []

        for name in self.__qSpaceManager.param.GetAllRegionNames():
            subMenu = wx.Menu()
            psdMenu.AppendSubMenu(subMenu, name)

            regionProperty = self.__qSpaceManager.param.detectorProps[name]
            for i in xrange(regionProperty.nPSD):
                psdNumber = i + regionProperty.PSD0
                menuItem = subMenu.AppendCheckItem(wx.ID_ANY, str(psdNumber))
                self.Bind(wx.EVT_MENU, self.ShowPSD, menuItem)
                self.__regionNameMap[menuItem.GetId()] = name

                self.__PSDMenuItems.append(menuItem)
                pass
            pass

        psdMenu.AppendSeparator()
        menuItem = psdMenu.Append(wx.ID_ANY, 'Reset all check')
        self.Bind(wx.EVT_MENU, self.ResetPSDSelection, menuItem)

        self.__displayControlMenu.AppendSeparator()

        menuItem = self.__displayControlMenu.Append(wx.ID_ANY, 'Object settings...\tCtrl-O')
        self.Bind(wx.EVT_MENU, self.PopupObjectSettingDialog, menuItem)

        menuBar.Append(self.__displayControlMenu, '3D_objects')
        return

    def DisplayControl(self, event):
        menuItemLabel = self.__displayControlMenu.FindItemById(event.GetId()).GetLabel()

        if menuItemLabel == self.__regionSurfaceControlMenuItem.GetLabel() or menuItemLabel == self.__contourLineMenuItem.GetLabel():
            self.__RegionSurfaceControl()
            pass
        elif menuItemLabel == self.__etIsosurfaceControlMenuItem.GetLabel():
            self.__EtIsosurfaceControl()
            pass
        elif menuItemLabel == self.__qPointDisplayMenuItem.GetLabel():
            self.__vtkPanel.ShowQPoint(self.__qPointDisplayMenuItem.IsChecked())
            pass
        elif menuItemLabel == self.__elasticScatteringLineMenuItem.GetLabel():
            self.__ElasticScatteringLineControl()
            pass
        elif menuItemLabel == self.__cellDisplayMenuItem.GetLabel():
            self.__CellDisplayControl()
            pass
        elif menuItemLabel == self.__rotationGuideControlMenuItem.GetLabel():
            self.__RotationGuideControl()
            pass
        elif menuItemLabel == self.__pixelIsosurfaceControlMenuItem.GetLabel():
            self.__PixelIsosurfaceControl()
            pass
        elif menuItemLabel == self.__latticeAxesControlMenuItem.GetLabel():
            self.__LatticeAxesControl()
            pass

        self.__vtkPanel.Render()
        return

    def PopupSampleInformationDialog(self, event):
        dlgSample = dialog.SampleInformationDialog(self)

        if dlgSample.ShowModal() == wx.ID_OK:
            sampleName = dlgSample.GetSampleName()
            latticeSystem = dlgSample.GetLatticeSystem()
            latticeSystemKind = dlgSample.GetLatticeSystemKind()

            self.SetParameter(qspace.TAG_SAMPLE_LTCSYS, latticeSystem)
            self.SetParameter(qspace.TAG_SAMPLE_LTCKIND, latticeSystemKind)
            self.SetParameter(qspace.TAG_SAMPLE_NAME, sampleName)

            parameters = dlgSample.GetInputParameters()

            import decimal

            for name in parameters.keys():
                self.SetParameter(name, decimal.Decimal(parameters[name]))
                pass

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

            if latticeSystem == qspace.Lattice.LT_SYS_TRICLINIC:
                pass # Nothing to do
            elif latticeSystem == qspace.Lattice.LT_SYS_MONOCLINIC:
                self.SetParameter(qspace.TAG_SAMPLE_ALPHA, decimal.Decimal(90))
                self.SetParameter(qspace.TAG_SAMPLE_GAMMA, decimal.Decimal(90))
                pass
            elif latticeSystem == qspace.Lattice.LT_SYS_ORTHORHOMBIC:
                self.SetParameter(qspace.TAG_SAMPLE_ALPHA, decimal.Decimal(90))
                self.SetParameter(qspace.TAG_SAMPLE_BETA, decimal.Decimal(90))
                self.SetParameter(qspace.TAG_SAMPLE_GAMMA, decimal.Decimal(90))
                pass
            elif latticeSystem == qspace.Lattice.LT_SYS_TETRAGONAL:
                self.SetParameter(qspace.TAG_SAMPLE_B, a)
                self.SetParameter(qspace.TAG_SAMPLE_ALPHA, decimal.Decimal(90))
                self.SetParameter(qspace.TAG_SAMPLE_BETA, decimal.Decimal(90))
                self.SetParameter(qspace.TAG_SAMPLE_GAMMA, decimal.Decimal(90))
                pass
            elif latticeSystem == qspace.Lattice.LT_SYS_TRIGONAL:
                self.SetParameter(qspace.TAG_SAMPLE_B, a)
                self.SetParameter(qspace.TAG_SAMPLE_C, a)
                self.SetParameter(qspace.TAG_SAMPLE_BETA, alpha)
                self.SetParameter(qspace.TAG_SAMPLE_GAMMA, alpha)
                pass
            elif latticeSystem == qspace.Lattice.LT_SYS_HEXAGONAL:
                self.SetParameter(qspace.TAG_SAMPLE_B, a)
                self.SetParameter(qspace.TAG_SAMPLE_ALPHA, decimal.Decimal(90))
                self.SetParameter(qspace.TAG_SAMPLE_BETA, decimal.Decimal(90))
                self.SetParameter(qspace.TAG_SAMPLE_GAMMA, decimal.Decimal(120))
                pass
            elif latticeSystem == qspace.Lattice.LT_SYS_CUBIC:
                self.SetParameter(qspace.TAG_SAMPLE_B, a)
                self.SetParameter(qspace.TAG_SAMPLE_C, a)
                self.SetParameter(qspace.TAG_SAMPLE_ALPHA, decimal.Decimal(90))
                self.SetParameter(qspace.TAG_SAMPLE_BETA, decimal.Decimal(90))
                self.SetParameter(qspace.TAG_SAMPLE_GAMMA, decimal.Decimal(90))
                pass

            self.UpdateSampleInformation()
            pass
        return

    def ResetPSDSelection(self, event):
        for menuItem in self.__PSDMenuItems:
            if menuItem.IsChecked():
                menuItem.Check(False)
                regionName = self.__regionNameMap[menuItem.GetId()]
                psdNumber = int(menuItem.GetLabel())
                self.__vtkPanel.ShowPSDOutline(regionName, psdNumber, False)
                pass
            pass
        return

    def PopupObjectSettingDialog(self, event):
        dlg = dialog.ObjectSettingDialog(self)
        dlg.Show()
        return

    def ApplySettings(self):
        self.__progressBarDialog = dialog.ProgressBarDialog(self, 'Please wait for update view', 0)
        # self.__progressBarDialog.Show()

        self.__workerMode = 'update view'

        # EVT_WATCHER_UPDATE(self.__progressBarDialog, self.__progressBarDialog.Update)

        # WorkerWatcher(self.UpdateView, self.__progressBarDialog, self).start()

        self.UpdateView()

        self.__vtkPanel.ShowQPoint(self.__qPointDisplayMenuItem.IsChecked())

        qPointList = self.__qSpaceManager.GetVisibleQPoints()
        self.__vtkPanel.SetQPointColor(qPointList)
        self.__vtkPanel.SetQPointOpacity(qPointList)

        self.__vtkPanel.ShowQPoint(self.__qPointDisplayMenuItem.IsChecked())

        self.__UpdateRegionDisplay()
        return

    def __RegionSurfaceControl(self):
        regionNames = self.GetCheckedRegions()

        paintSurface = self.__regionSurfaceControlMenuItem.IsChecked()
        drawContour = self.__contourLineMenuItem.IsChecked()

        self.__contourLineMenuItem.Enable(paintSurface)

        for regionName in self.__qSpaceManager.param.GetAllRegionNames():
            try:
                regionNames.index(regionName)
                self.__vtkPanel.ShowDetectorSurface(regionName, paintSurface, drawContour)
                pass
            except ValueError:
                self.__vtkPanel.ShowDetectorSurface(regionName, False, drawContour)
                pass
            pass
        return

    def __EtIsosurfaceControl(self):
        regionNames = self.GetCheckedRegions()

        for regionName in self.__qSpaceManager.param.GetAllRegionNames():
            try:
                regionNames.index(regionName)
                self.__vtkPanel.ShowEtIsosurface(regionName, self.__etIsosurfaceControlMenuItem.IsChecked())
                pass
            except ValueError:
                self.__vtkPanel.ShowEtIsosurface(regionName, False)
                pass
            pass
        return

    def __ElasticScatteringLineControl(self):
        regionNames = self.GetCheckedRegions()

        for regionName in self.__qSpaceManager.param.GetAllRegionNames():
            try:
                regionNames.index(regionName)
                self.__vtkPanel.ShowElasticScatteringLine(regionName, self.__elasticScatteringLineMenuItem.IsChecked())
                pass
            except ValueError:
                self.__vtkPanel.ShowElasticScatteringLine(regionName, False)
                pass
            pass
        return

    def __CellDisplayControl(self):
        self.__vtkPanel.ShowCell(self.__cellDisplayMenuItem.IsChecked())
        return

    def __RotationGuideControl(self):
        listControl = self.getControl('QpListCtrl')
        item = listControl.GetFirstSelected()

        if item == -1:
            return

        selectedQPointKey = listControl.GetItemText(item)

        import math

        axisType = self.GetParameter(qspace.TAG_ROTATE_GUIDEAXIS)
        psi = math.radians(self.GetParameter(qspace.TAG_ROTATE_PSI))
        chi = math.radians(self.GetParameter(qspace.TAG_ROTATE_CHI))
        phi = math.radians(self.GetParameter(qspace.TAG_ROTATE_PHI))

        self.__vtkPanel.SetRotationGuide(axisType, psi, chi, phi,
                                         self.__qSpaceManager.ltc.ra_orig,
                                         self.__qSpaceManager.ltc.rb_orig,
                                         self.__qSpaceManager.ltc.rc_orig,
                                         self.__qSpaceManager.GetQPoint(selectedQPointKey))

        self.__vtkPanel.ShowRotationGuide(self.__rotationGuideControlMenuItem.IsChecked())
        return

    def __PixelIsosurfaceControl(self):
        regionNames = self.GetCheckedRegions()

        for regionName in self.__qSpaceManager.param.GetAllRegionNames():
            try:
                regionNames.index(regionName)
                self.__vtkPanel.SetPixelIsosurface(regionName, self.GetParameter(qspace.TAG_OBJ3D_SURFSCALAR), self.GetParameter(qspace.TAG_OBJ3D_PXNO))
                self.__vtkPanel.ShowPixelIsosurface(regionName, self.__pixelIsosurfaceControlMenuItem.IsChecked())
                pass
            except ValueError:
                self.__vtkPanel.ShowPixelIsosurface(regionName, False)
                pass
            pass
        return

    def __LatticeAxesControl(self):
        self.__vtkPanel.ShowLatticeAxes(self.__latticeAxesControlMenuItem.IsChecked())
        return

    def __UpdateRendering(self):
        self.__RegionSurfaceControl()
        self.__EtIsosurfaceControl()
        self.__vtkPanel.ShowQPoint(self.__qPointDisplayMenuItem.IsChecked())
        self.__ElasticScatteringLineControl()
        self.__CellDisplayControl()
        self.__RotationGuideControl()
        self.__PixelIsosurfaceControl()
        self.__LatticeAxesControl()
        return

    def ShowPSD(self, event):
        regionName = self.__regionNameMap[event.GetId()]
        menuItem = self.__displayControlMenu.FindItemById(event.GetId())
        psdNumber = int(menuItem.GetLabel())

        self.__vtkPanel.ShowPSDOutline(regionName, psdNumber, menuItem.IsChecked())
        return

    def __createRegionMenu(self, menuBar):
        regionMenu = wx.Menu()

        self.__regionDataSubMenu = wx.Menu()
        regionMenu.AppendSubMenu(self.__regionDataSubMenu, 'Data View')

        self.__selectAllRegionMenuItem = self.__regionDataSubMenu.Append(wx.ID_ANY, 'Select all').GetId()
        self.Bind(wx.EVT_MENU, self.AllRegionControl, id = self.__selectAllRegionMenuItem)

        self.__resetAllRegionMenuItem = self.__regionDataSubMenu.Append(wx.ID_ANY, 'Reset all').GetId()
        self.Bind(wx.EVT_MENU, self.AllRegionControl, id = self.__resetAllRegionMenuItem)

        self.__regionDataSubMenu.AppendSeparator()

        for name in self.__qSpaceManager.param.GetAllRegionNames():
            menuItem = self.__regionDataSubMenu.AppendCheckItem(wx.ID_ANY, name)
            menuItem.Check(True)
            self.Bind(wx.EVT_MENU, self.SelectRegionMenuItem, menuItem)
            self.Bind(wx.EVT_MENU_HIGHLIGHT, self.HighlightRegionMenuItem, menuItem)
            pass

        self.__regionFrameSubMenu = wx.Menu()
        regionMenu.AppendSubMenu(self.__regionFrameSubMenu, 'Frame View')

        self.__selectAllRegionFrameMenuItem = self.__regionFrameSubMenu.Append(wx.ID_ANY, 'Select all').GetId()
        self.Bind(wx.EVT_MENU, self.AllRegionFrameControl, id = self.__selectAllRegionFrameMenuItem)

        self.__resetAllRegionFrameMenuItem = self.__regionFrameSubMenu.Append(wx.ID_ANY, 'Reset all').GetId()
        self.Bind(wx.EVT_MENU, self.AllRegionFrameControl, id = self.__resetAllRegionFrameMenuItem)

        self.__regionFrameSubMenu.AppendSeparator()

        for name in self.__qSpaceManager.param.GetAllRegionNames():
            menuItem = self.__regionFrameSubMenu.AppendCheckItem(wx.ID_ANY, name)
            self.Bind(wx.EVT_MENU, self.SelectRegionFrameMenuItem, menuItem)
            self.Bind(wx.EVT_MENU_HIGHLIGHT, self.HighlightRegionMenuItem, menuItem)
            pass

        self.Bind(wx.EVT_MENU_CLOSE, self.RegionMenuClose)

        menuBar.Append(regionMenu, 'Region')
        return

    def AllRegionControl(self, event):
        for menuItem in self.__regionDataSubMenu.GetMenuItems():
            if menuItem.IsCheckable():
                if event.GetId() == self.__selectAllRegionMenuItem:
                    menuItem.Check(True)
                    pass
                else:
                    menuItem.Check(False)
                    pass
                pass
            pass

        if event.GetId() == self.__selectAllRegionMenuItem:
            self.__qSpaceManager.UpdateBoundingBox(self.GetCheckedRegions())
            bounds = self.GetBounds()
            self.__vtkPanel.SetAxesRange(bounds)
            pass

        self.__UpdateRegionDisplay()
        return

    def HighlightRegionMenuItem(self, event):
        item = self.__regionDataSubMenu.FindItemById(event.GetId())
        if item == None:
            item = self.__regionFrameSubMenu.FindItemById(event.GetId())
            pass

        regionName = item.GetLabel()

        self.__vtkPanel.ShowDetectorRegionHighlight(regionName)

        self.__vtkPanel.Render()
        return

    def __UpdateRegionDisplay(self):
        self.__qSpaceManager.UpdateBoundingBox(self.GetCheckedRegions())
        bounds = self.GetBounds()
        self.__vtkPanel.SetAxesRange(bounds)

        if self.__regionSurfaceControlMenuItem.IsChecked():
            self.__RegionSurfaceControl()
            pass

        if self.__etIsosurfaceControlMenuItem.IsChecked():
            self.__EtIsosurfaceControl()
            pass

        if self.__elasticScatteringLineMenuItem.IsChecked():
            self.__ElasticScatteringLineControl()
            pass

        if self.__pixelIsosurfaceControlMenuItem.IsChecked():
            self.__PixelIsosurfaceControl()
            pass

        for menuItem in self.__regionFrameSubMenu.GetMenuItems():
            if menuItem.IsCheckable():
                self.__vtkPanel.ShowDetectorRegion(menuItem.GetLabel(), menuItem.IsChecked())
                pass
            pass

        self.__vtkPanel.Render()
        return

    def SelectRegionMenuItem(self, event):
        menuItem = self.__regionDataSubMenu.FindItemById(event.GetId())

        self.__UpdateRegionDisplay()
        return

    def RegionMenuClose(self, event):
        self.__vtkPanel.HideDetectorRegionHighlight()
        self.__vtkPanel.Render()
        return

    def AllRegionFrameControl(self, event):
        for menuItem in self.__regionFrameSubMenu.GetMenuItems():
            if menuItem.IsCheckable():
                if event.GetId() == self.__selectAllRegionFrameMenuItem:
                    menuItem.Check(True)
                    pass
                else:
                    menuItem.Check(False)
                    pass

                self.__vtkPanel.ShowDetectorRegion(menuItem.GetLabel(), menuItem.IsChecked())
                pass
            pass

        self.__vtkPanel.Render()
        return

    def SelectRegionFrameMenuItem(self, event):
        menuItem = self.__regionFrameSubMenu.FindItemById(event.GetId())

        self.__vtkPanel.ShowDetectorRegion(menuItem.GetLabel(), menuItem.IsChecked())

        self.__vtkPanel.Render()
        return

    def __createControlMenu(self, menuBar):
        controlMenu = wx.Menu()

        menuItem = controlMenu.Append(wx.ID_ANY, 'Rotation control...\tCtrl-R')
        self.Bind(wx.EVT_MENU, self.PopupRotationControlDialog, menuItem)
        menuItem = controlMenu.Append(wx.ID_ANY, 'Energy control...\tCtrl-E')
        self.Bind(wx.EVT_MENU, self.PopupEnergyControlDialog, menuItem)
        menuItem = controlMenu.Append(wx.ID_ANY, 'Scalar Range Settings...')
        self.Bind(wx.EVT_MENU, self.PopupScalarRangeDialog, menuItem)

        menuBar.Append(controlMenu, 'Control')
        return

    def __createGraphMenu(self, menuBar):
        graphMenu = wx.Menu()
        menuBar.Append(graphMenu, 'Graph')

        menuItem = graphMenu.Append(wx.ID_ANY, 'QE Graph...\tCtrl-Q')
        self.Bind(wx.EVT_MENU, self.PopupQEGraphSetupDialog, menuItem)
        menuItem = graphMenu.Append(wx.ID_ANY, 'QRegion Graph...')
        self.Bind(wx.EVT_MENU, self.PopupQRegionSetupDialog, menuItem)
        return

    def __createToolBar(self):
        def AddTool(toolBar, pngPath, shortHelp, longHelp):
            import os

            image = wx.Image(os.path.join(os.path.abspath(os.path.dirname(__file__)), pngPath), wx.BITMAP_TYPE_PNG)
            bitmap = image.ConvertToBitmap()
            return toolBar.AddSimpleTool(wx.ID_ANY, bitmap, shortHelp, longHelp)

        self.__toolBar = wx.ToolBar(self)
        self.SetToolBar(self.__toolBar)

        toolItem = AddTool(self.__toolBar, 'logos/tool_s.png',
                           'Sample Information settings...', 'Open Sample Information settings dialog')
        self.Bind(wx.EVT_TOOL, self.PopupSampleInformationDialog, toolItem)
        toolItem = AddTool(self.__toolBar, 'logos/tool_ei.png',
                           'Incident energy control...', 'Open incident energy control dialog')
        self.Bind(wx.EVT_TOOL, self.PopupEnergyControlDialog, toolItem)
        toolItem = AddTool(self.__toolBar, 'logos/tool_qe.png',
                           'QE graph settings...', 'Open QE graph settings dialog')
        self.Bind(wx.EVT_TOOL, self.PopupQEGraphSetupDialog, toolItem)
        toolItem = AddTool(self.__toolBar, 'logos/tool_rc.png',
                           'Rotation control...', 'Open rotation control dialog')
        self.Bind(wx.EVT_TOOL, self.PopupRotationControlDialog, toolItem)

        self.__toolBar.AddSeparator()

        toolItem = AddTool(self.__toolBar, 'logos/tool_qr.png',
                           'QR graph settings...', 'Open QR graph settings dialog')
        self.Bind(wx.EVT_TOOL, self.PopupQRegionSetupDialog, toolItem)
        toolItem = AddTool(self.__toolBar, 'logos/tool_obj.png',
                           '3D object settings...', 'Open 3D Object settings dialog')
        self.Bind(wx.EVT_TOOL, self.PopupObjectSettingDialog, toolItem)

        self.__toolBar.AddSeparator()

        toolItem = AddTool(self.__toolBar, 'logos/tool_x.png',
                           'qx view', 'Change view along X axis')
        self.Bind(wx.EVT_TOOL, self.ViewControl, toolItem)
        toolItem = AddTool(self.__toolBar, 'logos/tool_y.png',
                           'qy view', 'Change view along Y axis')
        self.Bind(wx.EVT_TOOL, self.ViewControl, toolItem)
        toolItem = AddTool(self.__toolBar, 'logos/tool_z.png',
                           'qz view', 'Change view along Z axis')
        self.Bind(wx.EVT_TOOL, self.ViewControl, toolItem)

        self.__toolBar.AddSeparator()

        toolItem = AddTool(self.__toolBar, 'logos/tool_a.png',
                           'qa view', 'Change view along a axis of lattice')
        self.Bind(wx.EVT_TOOL, self.ViewControl, toolItem)
        toolItem = AddTool(self.__toolBar, 'logos/tool_b.png',
                           'qb view', 'Change view along b axis of lattice')
        self.Bind(wx.EVT_TOOL, self.ViewControl, toolItem)
        toolItem = AddTool(self.__toolBar, 'logos/tool_c.png',
                           'qc view', 'Change view along c axis of lattice')
        self.Bind(wx.EVT_TOOL, self.ViewControl, toolItem)

        self.__toolBar.AddSeparator()

        toolItem = AddTool(self.__toolBar, 'logos/tool_pev.png',
                           'Perspective view', 'Change perspective view mode')
        self.Bind(wx.EVT_TOOL, self.ProjectionControl, toolItem)
        toolItem = AddTool(self.__toolBar, 'logos/tool_ppv.png',
                           'Parallel-projection view', 'Change parallel-projection view mode')
        self.Bind(wx.EVT_TOOL, self.ProjectionControl, toolItem)
        self.__toolBar.Realize()
        return

    def __updateQPointList(self):
        listControl = self.getControl('QpListCtrl')
        listControl.ClearAll()
        listControl.InsertColumn(0, 'Point ID')
        listControl.InsertColumn(1, 'Et [meV]')
        listControl.SetColumnWidth(0, 100)
        listControl.SetColumnWidth(1, 100)

        colors = wx.ColourDatabase()
        pink = colors.Find("PINK")

        self.__qSpaceManager.CreateDetectableRegion(self.__mode)
        self.__qSpaceManager.UpdateBoundingBox(self.GetCheckedRegions())
        self.__qSpaceManager.UpdateQpPositions(self.__mode)
        qPointList = self.__qSpaceManager.GetVisibleQPoints()

        for p in qPointList:
            key = p.GetIndexString()
            index = listControl.InsertStringItem(0, key)

            if p.GetEtmax() == None:
                text = 'None'
                pass
            else:
                text = "% g" % p.GetEtmax()
                pass
            listControl.SetStringItem(index, 1, text)

            selectKey = self.GetParameter(qspace.TAG_SELECTQPINDEX)
            if selectKey != None and selectKey == key:
                listControl.SetItemState(index, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
                pass

            if p.numInsidePoints > 0:
                listControl.SetItemBackgroundColour(index, pink)
                pass
            pass
        return

    def GetScalarFieldRange(self, type):
        return self.__qSpaceManager.GetScalarFieldRange(type, self.__isMeasurementDataLoaded)

    def UpdateView(self):
        scalarKind = self.GetScalarKind()

        scalarRange = self.GetScalarFieldRange(scalarKind)

        self.__vtkPanel.CreateColorBar(scalarKind, scalarRange)

        drawingData = self.__qSpaceManager.GetDetectorRegions()
        self.__vtkPanel.CreateDetectorRegionView(drawingData, scalarRange,
                                                 self.__qSpaceManager.param.detectorProps)

        if self.GetScalarKind() == define.DETECT_INTENSITY:
            drawingData = self.__qSpaceManager.GetIntensityRegions()
            self.__vtkPanel.CreateIntensityRegionView(drawingData, scalarRange, self.__qSpaceManager.param.Eng_array)
            pass

        bounds = self.GetBounds()
        radius = max(bounds[1] - bounds[0],
                     bounds[3] - bounds[2],
                     bounds[5] - bounds[4]) * self.__qPointSize

        qPointList = self.__qSpaceManager.GetVisibleQPoints()
        self.__vtkPanel.CreateQPoints(qPointList, radius)

        self.__vtkPanel.SetAxesRange(bounds)
        self.__vtkPanel.CreateCameraView('qy', self.__qSpaceManager.GetBoundingSize(), self.__qSpaceManager.GetCenter(), bounds[1], bounds[3], bounds[5])

        self.__vtkPanel.CreateEtIsosurface()
        self.__vtkPanel.CreatePixelIsosurface()

        self.__vtkPanel.CreateElasticScatteringLines()
        self.__vtkPanel.CreateCell(self.__qSpaceManager.ltc.ra_rotate,
                                   self.__qSpaceManager.ltc.rb_rotate,
                                   self.__qSpaceManager.ltc.rc_rotate)
        self.__vtkPanel.CreateRotationGuide()
        self.__vtkPanel.CreateLatticeAxes((self.__qSpaceManager.ltc.ra_rotate,
                                           self.__qSpaceManager.ltc.rb_rotate,
                                           self.__qSpaceManager.ltc.rc_rotate),
                                          self.__qSpaceManager.GetDiagonalBoundingSize())
        return

    def GetCheckedRegions(self):
        regions = []

        for menuItem in self.__regionDataSubMenu.GetMenuItems():
            if menuItem.IsCheckable() and menuItem.IsChecked():
                regions.append(menuItem.GetItemLabel())
                pass
            pass
        return regions

    def MethodFileAccess(self, event):
        itemName = self.__fileMenu.FindItemById(event.GetId()).GetLabel()

        if itemName == 'Load method file':
            title = 'Select read file'
            dialogStyle = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST
            pass
        else:
            title = 'Save file'
            dialogStyle = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT
            pass

        dlg = wx.FileDialog(self,
                            title, defaultFile = 'Default.amt', wildcard = 'AMT Files (*.amt)|*.amt',
                            style = dialogStyle)

        if dlg.ShowModal() == wx.ID_OK:
            filepath = dlg.GetPath()

            if itemName == 'Load method file':
                self.__qSpaceManager.status.Read(filepath)

                self.__rotationControlDialog.ReloadParameters()
                pass
            else:
                self.__qSpaceManager.status.OutputStatus(filepath)
                pass
            pass
        return

    def __energyRangeCheck(self, energyRange):
        if energyRange[0] != self.GetFloatParameter(qspace.TAG_ENG_EI) or \
                energyRange[1] != self.GetFloatParameter(qspace.TAG_ENG_ETMIN) or \
                energyRange[2] != self.GetFloatParameter(qspace.TAG_ENG_ETMAX):
            message = 'Do you adjust current energy settings to following range of BINs in NeXus file ?\n' \
                + '  Ei, Etmin, Etmax: %g, %g, %g [meV]' % energyRange

            dlg = wx.MessageDialog(self, message, 'Question for energy settings',
                                   wx.YES_NO | wx.ICON_QUESTION | wx.STAY_ON_TOP)

            if dlg.ShowModal() == wx.ID_YES:
                import decimal

                # if self.__mode == 'DNA':
                #     self.SetParameter(qspace.TAG_ENG_EIMIN, decimal.Decimal(str(energyRange[1])))
                #     self.SetParameter(qspace.TAG_ENG_EIMAX, decimal.Decimal(str(energyRange[2])))
                #     pass
                # else:
                #     self.SetParameter(qspace.TAG_ENG_EI, decimal.Decimal(str(energyRange[0])))
                #     self.SetParameter(qspace.TAG_ENG_ETMIN, decimal.Decimal(str(energyRange[1])))
                #     self.SetParameter(qspace.TAG_ENG_ETMAX, decimal.Decimal(str(energyRange[2])))
                #     pass

                self.SetParameter(qspace.TAG_ENG_EI, decimal.Decimal(str(energyRange[0])))
                self.SetParameter(qspace.TAG_ENG_ETMIN, decimal.Decimal(str(energyRange[1])))
                self.SetParameter(qspace.TAG_ENG_ETMAX, decimal.Decimal(str(energyRange[2])))

                self.__qSpaceManager.UpdateEnergyRange()
                pass
            pass
        return

    def LoadDataFile(self, event):
        itemName = self.__fileMenu.FindItemById(event.GetId()).GetLabel()

        if itemName == 'Load Boost file':
            title = 'Load Boost file'
            wildcard = 'Boost files (*.bst)|*.bst'
            self.__isHDF = False
            pass
        else:
            title = 'Load Boost file'
            wildcard = 'NeXus files (*.nx)|*.nx'
            self.__isHDF = True
            pass

        dlg = wx.FileDialog(self,
                            title, wildcard = wildcard,
                            style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)

        if dlg.ShowModal() == wx.ID_OK:
            self.__filepath = dlg.GetPath()

            self.__workerMode = 'file loading'

            self.__progressBarDialog = dialog.ProgressBarDialog(self, 'Please wait for loading file', 0)
            self.__progressBarDialog.Show()

            EVT_WATCHER_UPDATE(self.__progressBarDialog, self.__progressBarDialog.Update)

            WorkerWatcher(self.FileLoading, self.__progressBarDialog, self).start()

            self.__isMeasurementDataLoaded = True
            pass
        return

    def FileLoading(self):
        self.__energyRange = self.__qSpaceManager.LoadDataFromFile(self.__filepath, self.__isHDF)
        return

    def DataMapping(self):
        self.__qSpaceManager.MeasurementDataMapping(self.__mode)

        # self.__updateQPointList()
        # self.UpdateView()
        # self.__UpdateRendering()
        print 'end'
        return

    def WorkerFinished(self, event):
        self.__progressBarDialog.Show(False)

        if self.__workerMode == 'file loading':
            self.__workerMode = 'data mapping'

            self.__energyRangeCheck(self.__energyRange)

            self.__progressBarDialog = dialog.ProgressBarDialog(self, 'Please wait for data mapping', 0)
            self.__progressBarDialog.Show()

            EVT_WATCHER_UPDATE(self.__progressBarDialog, self.__progressBarDialog.Update)

            WorkerWatcher(self.DataMapping, self.__progressBarDialog, self).start()
            pass
        elif self.__workerMode == 'data mapping':
            print 'update'
            self.__updateQPointList()
            self.UpdateView()
            self.__UpdateRendering()
            pass
        elif self.__workerMode == 'update view':
            self.__UpdateRendering()
            pass
        return

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

    def lstColumnClick(self, event):
        if self.__lstSortMode == 'IJK':
            self.__lstSortMode = 'ET'
            pass
        else:
            self.__lstSortMode = 'IJK'
            pass

        self.__updateQPointList()
        self.ApplySettings()
        return

    def __SelectQPoint(self, qPointIndex):
        self.__vtkPanel.SelectedQPoint(qPointIndex, self.__qSpaceManager.GetQPoint(qPointIndex))
        self.SetParameter(qspace.TAG_SELECTQPINDEX, qPointIndex)

        if self.__rotationGuideControlMenuItem.IsChecked():
            self.__RotationGuideControl()
            pass

        self.__vtkPanel.Render()
        return

    def QPointListSetSelected(self, qPointIndex):
        listControl = self.getControl('QpListCtrl')

        for i in xrange(listControl.GetItemCount()):
            if listControl.GetItemText(i) == qPointIndex:
                listControl.SetItemState(i, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
                break
            pass

        self.__PopupQPointInformationDialog(listControl.GetItemText(i))
        return

    def lstSelected(self, event):
        self.__SelectQPoint(event.GetItem().GetText())
        return

    def lstDeselected(self, event):
        key = event.GetItem().GetText()
        self.__vtkPanel.DeselectedQPoint(key, self.__qPointDisplayMenuItem.IsChecked())
        return

    def __PopupQPointInformationDialog(self, qPointIndex):
        qPoint = self.__qSpaceManager.GetQPoint(qPointIndex)

        dlgQpInfo = dialog.QPointInformationDialog(self, qPoint.GetInfoText())
        dlgQpInfo.ShowModal()
        dlgQpInfo.Destroy()
        return

    def lstActivated(self, event):
        listControl = self.getControl('QpListCtrl')
        item = listControl.GetFirstSelected()

        if item == -1:
            return

        self.__PopupQPointInformationDialog(listControl.GetItemText(item))
        return

    def lstRightClicked(self, event):
        # Test Script for BeamIntensity module
        import BeamIntensity

        mod = BeamIntensity.Moderator()
        mod.ReadIntensityData('Pulse_0310_mod_port02.csv')

        bl = BeamIntensity.BeamLine(mod)

        ch = BeamIntensity.DoubleDiskChopper("Pulse shaping chopper (No.1)", 7.75, 0.05, 300.0, 0.0246, 0.090, 0.3)
        ch.thisown = 0

        ch.AddSlitToForwardChopper(5.7, 0.0)
        ch.AddSlitToForwardChopper(5.7, 90.0)
        ch.AddSlitToForwardChopper(5.7, 180.0)
        ch.AddSlitToForwardChopper(1.9, 270.0)

        ch.AddSlitToBackwardChopper(5.7, 0.0)
        ch.AddSlitToBackwardChopper(5.7, -90.0)
        ch.AddSlitToBackwardChopper(5.7, -180.0)
        ch.AddSlitToBackwardChopper(1.9, -270.0)

        ch.SetInitialPhase(-74.40024511, 74.40024511) # for 2nd frame

        bl.AddChopper(ch)

        ch = BeamIntensity.DoubleDiskChopper('Slow double disk chopper (No.4)', 10.0, 0.04, 25.0, 0.0414, 0.090, 0.3)
        ch.thisown = 0
        ch.AddSlitToForwardChopper(85.7, 0.0)
        ch.AddSlitToBackwardChopper(85.7, 0.0)
        ch.SetInitialPhase(-123.8677683, 123.8677683) # for 2nd frame

        bl.AddChopper(ch)

        ch = BeamIntensity.SingleDiskChopper('Frame separation chopper (No.2)', 11.625, 200.0, 0.0492, 0.090, 0.3)
        ch.thisown = 0

        ch.AddSlit(24.7, 0.0)
        ch.AddSlit(24.7, 90.0)
        ch.AddSlit(24.7, 180.0)
        ch.AddSlit(24.7, 270.0)
        ch.SetInitialPhase(-70.80024511) # for 2nd frame

        bl.AddChopper(ch)

        ch = BeamIntensity.SingleDiskChopper('Slow single disk chopper (No.5)', 12.5, 25.0, 0.0525, 0.090, 0.3)
        ch.thisown = 0
        ch.AddSlit(118.9, 0.0)
        ch.SetInitialPhase(-154.6097104) # for 2nd frame

        bl.AddChopper(ch)

        ch = BeamIntensity.DoubleDiskChopper('Slow double disk chopper (No.6)', 15.0, 0.04, 25.0, 0.060, 0.090, 0.3)
        ch.thisown = 0
        ch.AddSlitToForwardChopper(128.6, 0.0)
        ch.AddSlitToBackwardChopper(128.6, 0.0)
        ch.SetInitialPhase(-185.3516524, 185.3516524) # for 2nd frame

        bl.AddChopper(ch)

        ch = BeamIntensity.SingleDiskChopper('Frame separation chopper (No.3)', 23.25, 200.0, 0.06, 0.090, 0.3)
        ch.thisown = 0
        ch.AddSlit(56.6, 0.0)
        ch.AddSlit(56.6, 180.0)
        ch.SetInitialPhase(-134.4004902) # for 2nd frame

        bl.AddChopper(ch)

        calculator = BeamIntensity.IntensityCalculator(1.0e-5, # [s]
                                                       90.0e-3, #[s]
                                                       8.0, # [meV]
                                                       1.0e-3, # [s]
                                                       46.3, # [m]
                                                       bl)
        calculator.CalculateIntensity()

        itval = numpy.zeros((2, calculator.GetNumberOfTimes()))
        ieval = numpy.zeros((2, calculator.GetNumberOfTimes()))

        for i in xrange(0, calculator.GetNumberOfTimes()):
            itval[0][i] = calculator.GetTimePoint(i)
            itval[1][i] = calculator.GetIntensityByTime(i)
            ieval[0][i] = calculator.GetEnergyPoint(i)
            ieval[1][i] = calculator.GetIntensityByEnergy(i)
            pass

        import matplotlib.pyplot as plt

        plt.subplot(211)
        plt.xlabel('Time of flight [s]')
        plt.ylabel('Energy integrated intensity\n[n/cm2/s/sr/pulse]')

        plt.xlim(itval[0][0], itval[0][calculator.GetNumberOfTimes() - 1])
        plt.plot(itval[0], itval[1])
        plt.grid()

        plt.subplot(212)
        plt.xlabel('Neutron energy [meV]')
        plt.ylabel('Time integrated intensity\n[n/cm2/sr/eV/pulse]')

        plt.xlim(ieval[0][calculator.GetNumberOfTimes() - 1], ieval[0][0])
        plt.plot(ieval[0], ieval[1])
        plt.grid()

        plt.show()
        plt.clf()

        del bl, mod, calculator
        return

    def PopupRotationControlDialog(self, event):
        listControl = self.getControl('QpListCtrl')
        item = listControl.GetFirstSelected()

        if item == -1:
            self.__rotationControlDialog.SetQPointInformation('No point selected.')
            pass
        else:
            qPoint = self.__qSpaceManager.GetQPoint(listControl.GetItemText(item))
            self.__rotationControlDialog.SetQPointInformation(qPoint.GetInfoText())
            pass

        self.__rotationControlDialog.Show()
        return

    def UpdateRotation(self):
        listControl = self.getControl('QpListCtrl')
        item = listControl.GetFirstSelected()

        import math

        psi = math.radians(self.GetParameter(qspace.TAG_ROTATE_PSI))
        chi = math.radians(self.GetParameter(qspace.TAG_ROTATE_CHI))
        phi = math.radians(self.GetParameter(qspace.TAG_ROTATE_PHI))

        self.__qSpaceManager.ltc.SetRotation(psi, chi, phi)

        self.__RotationGuideControl()

        self.__qSpaceManager.UpdateQpPositions(self.__mode)

        bounds = self.GetBounds()
        radius = max(bounds[1] - bounds[0],
                     bounds[3] - bounds[2],
                     bounds[5] - bounds[4]) * self.__qPointSize

        qPointList = self.__qSpaceManager.GetVisibleQPoints()
        self.__vtkPanel.CreateQPoints(qPointList, radius)

        self.__vtkPanel.ShowQPoint(self.__qPointDisplayMenuItem.IsChecked())

        self.__vtkPanel.UpdateCell(self.__qSpaceManager.ltc.ra_rotate,
                                   self.__qSpaceManager.ltc.rb_rotate,
                                   self.__qSpaceManager.ltc.rc_rotate)

        self.__vtkPanel.UpdateLatticeAxes((self.__qSpaceManager.ltc.ra_rotate,
                                           self.__qSpaceManager.ltc.rb_rotate,
                                           self.__qSpaceManager.ltc.rc_rotate),
                                          self.__qSpaceManager.GetDiagonalBoundingSize())

        qPointKey = listControl.GetItemText(item)

        if qPointKey != None and qPointKey != '':
            selectedQPoint = self.__qSpaceManager.GetQPoint(qPointKey)

            self.__rotationControlDialog.SetQPointInformation(selectedQPoint.GetInfoText())

            self.__vtkPanel.SelectedQPoint(qPointKey, selectedQPoint)
            pass

        self.__vtkPanel.Render()
        return

    def UpdateRotationGuideAxis(self):
        if self.__rotationGuideControlMenuItem.IsChecked():
            self.__RotationGuideControl()
            self.__vtkPanel.Render()
            pass
        return

    def UpdateSampleInformation(self):
        self.__qSpaceManager.ltc = qspace.Lattice(self.__qSpaceManager.status)

        self.UpdateRotation()
        return

    def PopupEnergyControlDialog(self, event):
        if self.__mode == 'DNA':
            dlg = dialog.DNAEnergyControlDialog(self)
            pass
        else:
            dlg = dialog.SIKEnergyControlDialog(self)
            pass

        if dlg.ShowModal() == wx.ID_OK:
            if self.__mode == 'DNA':
                range = dlg.GetEnergyRange()
                self.SetParameter(qspace.TAG_ENG_EIMIN, range[0])
                self.SetParameter(qspace.TAG_ENG_EIMAX, range[1])
                pass
            else:
                range = dlg.GetEnergyRange()
                self.SetParameter(qspace.TAG_ENG_EI, range[0])
                self.SetParameter(qspace.TAG_ENG_ETMIN, range[1])
                self.SetParameter(qspace.TAG_ENG_ETMAX, range[2])
                pass

            listControl = self.getControl('QpListCtrl')
            item = listControl.GetFirstSelected()

            if item != -1:
                qPointKey = listControl.GetItemText(item)
                pass
            else:
                qPointKey = None
                pass

            self.__qSpaceManager.UpdateEnergyRange()
            self.__updateQPointList()
            self.ApplySettings()

            if qPointKey != None:
                self.__vtkPanel.SelectedQPoint(qPointKey, self.__qSpaceManager.GetQPoint(qPointKey))
                pass

            self.__vtkPanel.Render()
            pass
        return

    def PopupScalarRangeDialog(self, event):
        dlg = dialog.ScalarRangeDialog(self)

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

    def PopupQEGraphSetupDialog(self, event):
        self.ShowQEGraphCutPlane(True)

        dlg = dialog.QEGraphSetupDialog(self)
        dlg.Show()
        return

    def GetQEGraphAxis(self):
        planeType = self.GetParameter(qspace.TAG_QEGRAPH_PLANEDEF)

        oid = [self.GetParameter(qspace.TAG_QEGRAPH_OH),
               self.GetParameter(qspace.TAG_QEGRAPH_OK),
               self.GetParameter(qspace.TAG_QEGRAPH_OL)]

        qO = self.__qSpaceManager.GetRotateQPosition(oid)

        if planeType == 0:
            qU = self.__qSpaceManager.ltc.ra_rotate
            qV = self.__qSpaceManager.ltc.rb_rotate
            pass
        elif planeType == 1:
            qU = self.__qSpaceManager.ltc.rb_rotate
            qV = self.__qSpaceManager.ltc.rc_rotate
            pass
        elif planeType == 2:
            qU = self.__qSpaceManager.ltc.rc_rotate
            qV = self.__qSpaceManager.ltc.ra_rotate
            pass
        else:
            uid = [self.GetParameter(qspace.TAG_QEGRAPH_UH),
                   self.GetParameter(qspace.TAG_QEGRAPH_UK),
                   self.GetParameter(qspace.TAG_QEGRAPH_UL)]

            vid = [self.GetParameter(qspace.TAG_QEGRAPH_VH),
                   self.GetParameter(qspace.TAG_QEGRAPH_VK),
                   self.GetParameter(qspace.TAG_QEGRAPH_VL)]

            qU = self.__qSpaceManager.GetRotateQPosition(uid)
            qV = self.__qSpaceManager.GetRotateQPosition(vid)
            pass

        qNormal = vector.GetCross(qU, qV)
        return qO, qU, qV, qNormal

    def UpdateQEGraphCutPlane(self):
        qOrigin, qU, qV, qNormal = self.GetQEGraphAxis()

        bounds = self.GetBounds()
        self.__vtkPanel.UpdateQEGraphPlane(bounds, qOrigin, qNormal)

        # if vector.GetNorm(qNormal) != 0.0:
        #     self.__vtkPanel.ShowQEGraphPlane(True)
        #     pass
        # else:
        #     self.__vtkPanel.ShowQEGraphPlane(False)
        #     pass

        self.__vtkPanel.Render()
        return

    def ShowQEGraphCutPlane(self, isShow):
        self.__vtkPanel.ShowQEGraphPlane(isShow)

        regionNames = self.GetCheckedRegions()

        for regionName in self.__qSpaceManager.param.GetAllRegionNames():
            try:
                regionNames.index(regionName)
                self.__vtkPanel.ShowQEGraphRegionPlane(regionName, isShow)
                pass
            except ValueError:
                self.__vtkPanel.ShowQEGraphRegionPlane(regionName, False)
                pass
            pass

        self.__vtkPanel.Render()
        return

    def PopupQRegionSetupDialog(self, event):
        regionPoints = self.GetAllThinDetectableRegions()
        self.__vtkPanel.CreateThinDetectableRegionShape(regionPoints)

        regionNames = self.GetCheckedRegions()

        for regionName in self.__qSpaceManager.param.GetAllRegionNames():
            try:
                regionNames.index(regionName)
                self.__vtkPanel.ShowThinDetectableRegionShape(regionName, True)
                pass
            except ValueError:
                self.__vtkPanel.ShowThinDetectableRegionShape(regionName, False)
                pass
            pass

        self.ShowQRigionGraphCutPlane(True)

        dlg = dialog.QRegionSetupDialog(self)
        dlg.Show()
        return

    def UpdateQRegionGraphCutPlane(self):
        bounds = self.GetBounds()

        qO0, qU0, qV0 = self.GetQRegionGraphAxis('start')
        qO1, qU1, qV1 = self.GetQRegionGraphAxis('end')

        qNormal0 = vector.GetCross(qU0, qV0)
        qNormal1 = vector.GetCross(qU1, qV1)

        self.__vtkPanel.UpdateQRegionGraphPlane(bounds, (qO0, qO1), (qNormal0, qNormal1), self.GetCheckedRegions())

        self.__vtkPanel.Render()
        return

    def ShowQRigionGraphCutPlane(self, isShow):
        self.__vtkPanel.ShowQRegionGraphPlane(isShow)

        regionNames = self.GetCheckedRegions()

        for regionName in self.__qSpaceManager.param.GetAllRegionNames():
            try:
                regionNames.index(regionName)
                self.__vtkPanel.ShowQRegionGraphCutRegion(regionName, isShow)
                pass
            except ValueError:
                self.__vtkPanel.ShowQRegionGraphCutRegion(regionName, False)
                pass
            pass

        self.__vtkPanel.Render()
        return

    def GetQRegionGraphAxis(self, rotatePosition = None):
        import math

        ra = self.__qSpaceManager.ltc.ra_orig
        rb = self.__qSpaceManager.ltc.rb_orig
        rc = self.__qSpaceManager.ltc.rc_orig

        qO = vector.GetVectorByIndex(ra, rb, rc,
                                     self.GetParameter(qspace.TAG_QRGRAPH_OH),
                                     self.GetParameter(qspace.TAG_QRGRAPH_OK),
                                     self.GetParameter(qspace.TAG_QRGRAPH_OL))

        planeType = self.GetParameter(qspace.TAG_QRGRAPH_PLANEDEF)

        if planeType == 0:
            qU = ra
            qV = rb
            pass
        elif planeType == 1:
            qU = rb
            qV = rc
            pass
        elif planeType == 2:
            qU = rc
            qV = ra
            pass
        else:
            qU = vector.GetVectorByIndex(ra, rb, rc,
                                         self.GetParameter(qspace.TAG_QRGRAPH_UH),
                                         self.GetParameter(qspace.TAG_QRGRAPH_UK),
                                         self.GetParameter(qspace.TAG_QRGRAPH_UL))

            qV = vector.GetVectorByIndex(ra, rb, rc,
                                         self.GetParameter(qspace.TAG_QRGRAPH_VH),
                                         self.GetParameter(qspace.TAG_QRGRAPH_VK),
                                         self.GetParameter(qspace.TAG_QRGRAPH_VL))
            pass

        psi = math.radians(self.GetParameter(qspace.TAG_QRGRAPH_PSI0))
        chi = math.radians(self.GetParameter(qspace.TAG_QRGRAPH_CHI0))
        phi = math.radians(self.GetParameter(qspace.TAG_QRGRAPH_PHI0))

        if rotatePosition == 'start':
            M = VTKPanel.GetRotationMatrix(psi, chi, phi)

            qO = qspace.ApplyRotMat(M, qO)
            qU = qspace.ApplyRotMat(M, qU)
            qV = qspace.ApplyRotMat(M, qV)
            pass
        elif rotatePosition == 'end':
            rotateAxis = self.GetParameter(qspace.TAG_QRGRAPH_ROTATEAXIS)
            dTheta = math.radians(self.GetParameter(qspace.TAG_QRGRAPH_INTERVAL)) * self.GetParameter(qspace.TAG_QRGRAPH_NSTEP)

            if rotateAxis == 0:
                psi += dTheta
                pass
            elif rotateAxis == 1:
                chi += dTheta
                pass
            elif rotateAxis == 2:
                phi += dTheta
                pass
            else:
                print 'Rotation axis error is found!'
                pass

            M = VTKPanel.GetRotationMatrix(psi, chi, phi)

            qO = qspace.ApplyRotMat(M, qO)
            qU = qspace.ApplyRotMat(M, qU)
            qV = qspace.ApplyRotMat(M, qV)
            pass
        return qO, qU, qV

    def SetQPointColor(self):
        qPointList = self.__qSpaceManager.GetVisibleQPoints()

        self.__vtkPanel.SetQPointColor(qPointList)
        self.__vtkPanel.Render()
        return

    def SetQPointOpacity(self):
        qPointList = self.__qSpaceManager.GetVisibleQPoints()

        self.__vtkPanel.SetQPointOpacity(qPointList)
        self.__vtkPanel.Render()
        return

    def EraseThinDetectableRegions(self):
        for regionName in self.__qSpaceManager.param.GetAllRegionNames():
            self.__vtkPanel.ShowThinDetectableRegionShape(regionName, False)
            pass

        self.__vtkPanel.Render()
        return

    def GetFloatParameter(self, parameterName):
        return self.__qSpaceManager.status.GetFloat(parameterName)

    def GetParameter(self, parameterName):
        return self.__qSpaceManager.status.GetValue(parameterName)

    def SetParameter(self, parameterName, value):
        self.__qSpaceManager.status.SetValue(parameterName, value)
        return

    def SetQPointSize(self, size):
        self.__qPointSize = size

        bounds = self.GetBounds()
        radius = max(bounds[1] - bounds[0], \
                     bounds[3] - bounds[2], \
                     bounds[5] - bounds[4]) * self.__qPointSize

        qPointList = self.__qSpaceManager.GetVisibleQPoints()
        self.__vtkPanel.CreateQPoints(qPointList, radius)

        self.__vtkPanel.ShowQPoint(self.__qPointDisplayMenuItem.IsChecked())
        return

    def GetQPointSize(self):
        return self.__qPointSize

    def GetLattice(self):
        return self.__qSpaceManager.ltc

    def GetRegionData(self, dataType):
        regionData = dict()

        for regionName in self.GetCheckedRegions():
            if dataType == define.ENERGY_TRANSFER:
                regionData[regionName] = self.__vtkPanel.GetGridData(regionName)
                pass
            else:
                regionData[regionName] = self.__vtkPanel.GetMeasurementData(regionName)
                pass
            pass
        return regionData

    def GetScalarKind(self):
        return self.GetParameter(qspace.TAG_OBJ3D_SURFSCALAR)

    def GetQPPotionOnQECutPlane(self, normal, origin):
        return self.__vtkPanel.GetQPPotionOnQECutPlane(normal, origin)

    def GetAllThinDetectableRegions(self):
        etmin = self.__qSpaceManager.status.GetFloat(qspace.TAG_QRGRAPH_ETMIN)
        etmax = self.__qSpaceManager.status.GetFloat(qspace.TAG_QRGRAPH_ETMAX)
        regionPoints = self.__qSpaceManager.CreateThinDetectableRegion(self.__mode, etmin, etmax)
        return regionPoints

    def GetThinDetectableRegions(self, etmin, etmax):
        regionPoints = self.__qSpaceManager.CreateThinDetectableRegion(self.__mode, etmin, etmax)
        return regionPoints

if __name__ == "__main__":
    import sys

    if len(sys.argv) <= 1 or sys.argv[1] == 'DNA':
        mode = 'DNA'
        pass
    else:
        mode = 'SIK'
        pass

    app = wx.App(0)
    frame = MainFrame(mode)
    app.SetTopWindow(frame)
    frame.CenterOnScreen()
    frame.Show()
    app.MainLoop()
    pass
