#-----------------------------------------------------------------------------
# Name:        pyGPIBcope.py    
# Purpose:     
#
# Author:      Dalet Philippe
# Inspiration: Gordon Williams
#
# Created:     2003/01/06 
# Release:     2005/04/16
# 
# Copyright:   (c) 2004
# Licence:     Use as you wish.
#-----------------------------------------------------------------------------

"""
pyGPIBscope - 3.4

Based on wxPlotCanvas, Written by K.Hinsen, R. Srinivasan;
Ported to wxPython Harm van der Heijden, feb 1999
Based on wxPyPlot, Written by Gordon Williams

Tested with
Python   2.3.5
wxPython 2.6.0.0
Numarray 1.3.0

Philippe DALET 
Lycee Champollion
46100 FIGEAC
FRANCE

philippe.dalet@voila.fr
""" 

VER="3.4"
TITLE= "pyGPIBscope"

import string
import numarray
import re
import  wx
import  wx.lib.dialogs
from scope import *
from acquire  import *
from pspicebinaryfile import *
import ConfigParser



#---------------------------------------------------------------------------           


class AppFrame(wx.Frame):
        def __init__(self, parent, id, title):
            wx.Frame.__init__(self, parent, id, title,wx.DefaultPosition, wx.Size(800, 600))
            #path du script ou se trouvent les icones
            self.pathpic=os.path.abspath(os.path.dirname(sys.argv[0]))+os.sep
            #self.pathpic=".\bmp"
            
            # Now Create the Toolbar       
            self.tb = self.CreateToolBar(wx.TB_HORIZONTAL | wx.RAISED_BORDER | wx.TB_FLAT)
            self.tb.SetToolBitmapSize(wx.Size(22,22))
            self._AddTool(".\\bmp\\exit.bmp","Exit",self.OnFileExit)
            self._AddTool(".\\bmp\\Save.bmp","Save Plot",self.OnSaveFile)
            self._AddTool(".\\bmp\\Preview.bmp","Print Preview",self.OnFilePrintPreview)
            self._AddTool(".\\bmp\\Print.bmp","Print Plot",self.OnFilePrint)
            self._AddTool(".\\bmp\\Pspice.bmp","Save Plot as Binary Pspice File",self.OnPspiceSaveFile)
            self._AddTool(".\\bmp\\Stimuli.bmp","Save Plot as Stimuli Pspice File",self.OnStimuliSaveFile)
            self._AddTool(".\\bmp\\Help.bmp","Help",self.OnHelpAbout)
            self.tb.AddSeparator()
            self._AddTool(".\\bmp\\back.bmp","Back",self.OnBack)
            self._AddTool(".\\bmp\\forward.bmp","Forward",self.OnForward)
            self._AddTool(".\\bmp\\comment.bmp","Comments",self.OnTitle)
            self._AddTool(".\\bmp\\IEEE.bmp","Acquire",self.OnAcquire)
            
            #combo box
            self.tb.AddSeparator()
            cbID=wx.NewId()
            self.combo=wx.ComboBox(self.tb, cbID , 'Left', choices=['Left', 'Center', 'Right'],
                               size=(70,-1), style=wx.CB_DROPDOWN )
            self.tb.AddControl(self.combo)
            self.Bind(wx.EVT_COMBOBOX, self.OnCombo, id=cbID)
            # Final thing to do for a toolbar is call the Realize() method. This
            # causes it to render (more or less, that is).
            self.tb.Realize()
                    
            # Now Create the menu bar and items
            self.mainmenu = wx.MenuBar()

            menu = wx.Menu()
            menu.Append(200, 'Page Setup...', 'Setup the printer page')
            self.Bind(wx.EVT_MENU,self.OnFilePageSetup, id=200)
            
            menu.Append(201, 'Print Preview...', 'Show the current plot on page')
            self.Bind(wx.EVT_MENU,self.OnFilePrintPreview, id=201)
            
            menu.Append(202, 'Print Preview...', 'Show the current plot on page')
            self.Bind(wx.EVT_MENU,self.OnFilePrintPreview, id=202)

            menu.Append(203, 'Print...', 'Print the current plot')
            self.Bind(wx.EVT_MENU,self.OnFilePrint, id=203)
            
            menu.Append(204, 'GPIB Adress/SERIAL Port...', 'Change Adress')
            self.Bind(wx.EVT_MENU,self.OnAdress, id=204)
            
            menu.Append(205, 'Save Plot as Image', 'Save current plot image')
            self.Bind(wx.EVT_MENU,self.OnSaveFile, id=205)
            
            menu.Append(206, 'Save Plot as Binary Pspice File', 'Save current plot as binary file')
            self.Bind(wx.EVT_MENU,self.OnPspiceSaveFile, id=206)
            
            menu.Append(207, 'Save Plot as Stimuli Pspice File', 'Save current plot as stimuli file')
            self.Bind(wx.EVT_MENU,self.OnPspiceSaveFile, id=207)
            
            menu.Append(208, 'E&xit', '')
            self.Bind(wx.EVT_MENU,self.OnFileExit, id=208)

            self.mainmenu.Append(menu, '&File')

            menu = wx.Menu()
            menu.Append(300, '&About', 'About this thing...')
            self.Bind(wx.EVT_MENU,self.OnHelpAbout, id=300) 

            self.mainmenu.Append(menu, '&Help')

            self.SetMenuBar(self.mainmenu)

            # A status bar to tell people what's happening
            self.CreateStatusBar(1)
            
            self.client = PlotCanvas(self)
            #Create mouse event for showing cursor coords in status bar
            self.client.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown)
            
            _icon = wx.Icon('py.ico', wx.BITMAP_TYPE_ICO)
            self.SetIcon(_icon)
            
            self.combo.SetValue('Center')
    
            #acquire from oscilloscope IEEE or demo
            self.cfg = ConfigParser.ConfigParser()
            self.cfg.readfp(open("pyGPIBscope.ini"))
            
            self.lst=[]
            for i in range(100):
                field=self.cfg.get('modules','%d' %(i))
                if (field==''):
                   break
                self.lst.append(field)
            
            dlg = wx.SingleChoiceDialog(self, '', 'Devices',self.lst, wx.CHOICEDLG_STYLE)
            current = int(self.cfg.get('settings','default'))
            dlg.SetSelection(current) 
            
            if dlg.ShowModal() == wx.ID_OK:
               self.field= dlg.GetStringSelection()
               self.index = dlg.GetSelection()
            else:
               self.field='TDS200'
               self.index=1

            dlg.Destroy()

            self.Adress = self.cfg.get('%s' %(self.field),'Adress') 
            self.Title  = self.cfg.get('%s' %(self.field),'Title') 
            
            #default plot
            self.resetDefaults()
            self._drawObjects()

            #windows centre
            self.Centre(wx.BOTH)

        def OnCombo(self, event):
            st=event.GetString() 
            if   (st == 'Left'):
               self.start=self.left
            elif (st == 'Center'):
               self.start=self.center
            else:
               self.start=self.right
            self.DrawPlot()
            
        def _AddTool(self,pic,help,fonc):
            id=wx.NewId()
            self.tb.AddSimpleTool(id,wx.Bitmap(self.pathpic+pic,wx.BITMAP_TYPE_BMP),help)
            wx.EVT_TOOL(self,id,fonc)

        def OnMouseLeftDown(self,event):
            s= "Left Mouse Down at Point: (%.4f, %.4f)" % self.client.GetXY(event)
            self.SetStatusText(s)
            event.Skip()

        def OnFilePageSetup(self, event):
            self.client.PageSetup()
            
        def OnFilePrintPreview(self, event):
            self.client.PrintPreview()
            
        def OnFilePrint(self, event):
            self.client.Printout()
            
        def OnSaveFile(self, event):
            self.client.SaveFile()

        def OnPspiceSaveFile(self, event):
            dlg1 = wx.FileDialog(self,"Choose a filename", ".", "",
                                      "Dat files (*.dat)|*.dat", wx.SAVE|wx.OVERWRITE_PROMPT )
            if dlg1.ShowModal() == wx.ID_OK:
               fileName = dlg1.GetPath()
               data = zeros ((self.ChannelNumber ,self.buffersize ) , Float)
               #print data
               data [0,:]= self.data1[:,1]
               #print data [0,:] 
               #print data
               data [1,:]= self.data2[:,1]
               #print data [1,:] 
               #print data
               #print self.acquire.getXinc()
               if (self.ChannelNumber==4):
                  data [2,:]= self.data1[:,1]
                  data [3,:]= self.data2[:,1]
                      
               str=self.field+' - '+self.Title+self.acquire.isDemo()
               file = PspiceBinaryFile(self.ChannelNumber, self.buffersize , \
                      self.acquire.getXinc(), str)
               file.Open(fileName)
               for i in range (0, self.buffersize /100 ,1):
                   file.Write( take(data, range(i*100,i*100+100,1) ,1 ) ,100)
               file.Close()
            
        def OnStimuliSaveFile(self, event):
            dlg1 = wx.FileDialog(self,"Choose a filename", ".", "",
                                      "Stl files (*.stl)|*.stl", wx.SAVE|wx.OVERWRITE_PROMPT )
            if dlg1.ShowModal() == wx.ID_OK:
               fileName = dlg1.GetPath()
               data = zeros ((self.ChannelNumber ,self.buffersize ) , Float)
               data [0,:]= self.data1[:,1]
               data [1,:]= self.data2[:,1]
               if (self.ChannelNumber==4):
                  data [2,:]= self.data1[:,1]
                  data [3,:]= self.data2[:,1]    
                      
               file = PspiceStimuliFile(self.buffersize, self.acquire.getXinc())
               file.Open(fileName)
               file.Write( data [0,:] , "CH1")
               file.Write( data [1,:] , "CH2")
               if (self.ChannelNumber==4):
                   file.Write( data [2,:] , "CH3")
                   file.Write( data [3,:] , "CH4")
               file.Close()
               
        def OnAdress(self, event):
            dlg = wx.TextEntryDialog(self, 'Enter the adress','GPIB Adress or SERIAL Port', '')
            dlg.SetValue(self.acquire.getAdress())
            if dlg.ShowModal() == wx.ID_OK: 
                   st=dlg.GetValue()
                   self.acquire.setAdress(st)
                   self.cfg.set('%s' %(self.field),'adress',st) 
                   self.acquire.Restart()
                   #print 'You entered: <<%s>>\n' % dlg.GetValue()   
            dlg.Destroy()
            
        def OnTitle(self, event):
            dlg = wx.TextEntryDialog(self, 'Enter your Title','', self.Title)
            if dlg.ShowModal() == wx.ID_OK: 
                   self.Title=dlg.GetValue()
                   self.cfg.set('%s' %(self.field),'Title',self.Title) 
            dlg.Destroy()
            
        def OnFileExit(self, event):
            self.acquire.close()
            fp=open("pyGPIBscope.ini","w")
            self.cfg.write(fp)
            self.Close(True)
        
        def OnReset(self,event):
            self.client.Reset()

        def OnForward(self,event): 
            if (self.start<self.right):
                self.start=self.start+self.pointsperdiv
                #print self.start , self.right
            self.DrawPlot()

        def OnBack(self,event): 
            if (self.start>=self.pointsperdiv):
                self.start=self.start-self.pointsperdiv
                #print self.start,self.pointsperdiv
            self.DrawPlot()

        def OnHelpAbout(self, event):
            from wx.lib.dialogs import ScrolledMessageDialog
            about = ScrolledMessageDialog(self, __doc__, "About...")
            about.ShowModal()
             
        def resetDefaults(self):
            """Just to reset the fonts back to the PlotCanvas defaults"""
            self.client.SetFont(wx.Font(10,wx.SWISS,wx.NORMAL,wx.NORMAL))
            self.client.SetFontSizeAxis(12)

            self.client.SetEnableZoom(False)
            self.client.SetFontSizeLegend(9)
                
        def DrawPlot(self):
            self.client.SetXoffset(self.start*self.acquire.getXinc())
            #print self.start, '%.16f' % (self.start*self.acquire.getXinc())
            self.pdata1 = self.data1[self.start:self.start + self.pointsperdiv*10]
            self.pdata2 = self.data2[self.start:self.start + self.pointsperdiv*10]
            channel1 = PolyLine(self.pdata1, legend='CH1', colour='red') 
            channel2 = PolyLine(self.pdata2, legend='CH2', colour='green')
            
            str=self.field+' - '+self.Title+self.acquire.isDemo()
            if (self.ChannelNumber==2):
                self.client.Draw( PlotGraphics([channel1, channel2],str, \
                                  self.acquire.getYdivision ('1')+" - "+ self.acquire.getYdivision ('2')\
                                   +"    "+ self.acquire.getXdivision () , ""))
            else:
                self.pdata3 = self.data3[self.start:self.start + self.pointsperdiv*10]
                self.pdata4 = self.data4[self.start:self.start + self.pointsperdiv*10]
                channel3 = PolyLine(self.pdata3, legend='CH3', colour='blue') 
                channel4 = PolyLine(self.pdata4, legend='CH4', colour='orange')   
                self.client.Draw( PlotGraphics([channel1, channel2,channel3,channel4],str, \
                                  self.acquire.getYdivision ('1')+" - "+ self.acquire.getYdivision ('2')\
                                  +self.acquire.getYdivision ('3')+" - "+ self.acquire.getYdivision ('4')\
                                   +"    "+ self.acquire.getXdivision () , ""))

        def OnAcquire(self,event):
            self.acquire.ViewAll()
            dlg = wx.ProgressDialog("pyGPIBscope","Acquisition running ....",100, self, wx.PD_APP_MODAL)
            dlg.Update(0, "Acquisition running ....")

            self.acquire.GetPreamble()      
            self.Origin()  
            
            self.client.SetDiv(self.acquire.getXDIV(),self.acquire.getYDIV('1'))

            dlg.Update(25,"Acquisition running ....")
            self.acquire.NormalAcquire()
            self.data1[:,0]= self.data2[:,0] = self.acquire.getX()
            self.data1[:,1]= self.acquire.getY('1')
            self.data2[:,1]= self.acquire.getY('2')            
            if (self.ChannelNumber==4):
                self.data3[:,0]= self.data4[:,0] =self.acquire.getX()
                self.data3[:,1]= self.acquire.getY('3')
                self.data4[:,1]= self.acquire.getY('4')
                
            if   (self.acquire.getReference()=='LEFT  '):
               self.start=self.left
               choice='Left'
            elif (self.acquire.getReference()=='RIGH  '):
               self.start=self.right
               choice='Right'
            else:
               self.start=self.center
               choice='Center'
            
            self.combo.SetValue(choice)

            #print "Plotting"
            dlg.Update(50,"Acquisition running ....")
            self.DrawPlot()
            
            dlg.Destroy() 
            
        def Origin(self):
            self.pointsperdiv=self.acquire.getPointsPerDiv()
            #print self.pointsperdiv
            self.left=0
            self.right=self.buffersize-10*self.pointsperdiv
            
            if (self.right==0):
                self.center=0
            else:
                self.center=100*(int(1.0*self.buffersize/200))-5*self.pointsperdiv
            #print self.left, self.center, self.right
                
        def _drawObjects(self):
            self.acquire=ACQUIRE(self.Adress,self.field,self.Title)
            self.acquire.ViewAll()
            
            self.acquire.Acquire('1')
            self.acquire.Acquire('2')
            self.acquire.GetPreamble()
            
            self.buffersize=self.acquire.getSize()
            self.Origin()   
            
            self.pdata1 = zeros ( (10*self.pointsperdiv,2) , Float)
            self.pdata2 = zeros ( (10*self.pointsperdiv,2) , Float)
            self.data1 = zeros ( (self.buffersize,2) , Float)
            self.data2 = zeros ( (self.buffersize,2) , Float) 
            
            self.ChannelNumber=self.acquire.getChannelNumber()
            if (self.ChannelNumber==4):      
               self.pdata3 = zeros ( (10*self.pointsperdiv,2) , Float)  
               self.pdata4 = zeros ( (10*self.pointsperdiv,2) , Float)
               self.data3 = zeros ( (self.buffersize,2) , Float)
               self.data4 = zeros ( (self.buffersize,2) , Float) 
               
            self.client.SetDiv(self.acquire.getXDIV(),self.acquire.getYDIV('1'))

            #print "getX"
            self.data1[:,0]= self.acquire.getX()
            self.start=self.left

            self.DrawPlot()

class App(wx.App):
        def OnInit(self):
            wx.InitAllImageHandlers()
            frame = AppFrame(None, -1, "%s - %s" %(TITLE,VER) )
            frame.Show(True)
            self.SetTopWindow(frame)
            return True

if __name__ == '__main__':
    app = App(0)
    app.MainLoop()