# $Id: pyTDS.py,
# 2003/04/17
# 2005/05/30
# Author: Ph Dalet (philippe.dalet@voila.fr)
#

from PythonCard import dialog, graphic, log, model
import os,time
import wx.lib.iewin
from threading import * 
from struct import *
import time, math
from GaugeDialog import *
from PythonCard import EXIF
from PythonCard.components import button
from PythonCard.components import staticline
from PythonCard.components import statictext
from PythonCard.components import image
from PythonCard.components import combobox
from PythonCard.components import textfield
from PythonCard.components import bitmapcanvas
from PythonCard.components import gauge
import ConfigParser

from serial import *
from constants import *

VER = "1.9"

BORDER = 5
RESIZE_LEFT = 1
RESIZE_RIGHT = 2
DRAG_X = 3
RESIZE_TOP = 4
RESIZE_BOTTOM = 5
DRAG_Y = 6
        


class MyBackground(model.Background):

    def on_initialize(self,event): 
        self.cfg=ConfigParser.ConfigParser()
        self.cfg.readfp(open('pyTDS.ini'))
        
        #PORT       
        self.port=self.cfg.get('settings','port')
        self.components.cmbComboBox.SetValue(self.port)

        #FULLNAME        
        self.fullname=self.cfg.get('settings','name')
        self.name=os.path.basename(self.fullname)
        self.path=self.fullname[:len(self.fullname)-len(self.name)]    
            
        self.components.fldTextField.SetValue(self.fullname) 
        self.bitmapCanvasLoad()      
        self.Gauge = GaugeDialog(self,0)
        self.Timer = wx.Timer(self.components.btnTransfert, -1)
        
        #PORT
        self.nport = int(self.port[3])-1
        self.FILESIZE=FILESIZE_DEFAULT
        self.ID();

    def bitmapCanvasLoad(self):
        bufOff = self.components.bufOff
        if os.path.isfile(self.fullname) :
            self.ofile=open(self.fullname, 'rb')
            self.bitmap = wx.Bitmap(self.fullname)
            if os.path.getsize(self.fullname)==TDS210:  bufOff.drawBitmap(self.bitmap, (0, 0))
            else: bufOff.drawBitmapScaled(self.bitmap, (0, 0) , (640,480))
            self.ofile.close()    
        else:
            bufOff.clear()
            #print 'File ', self.fullname, ' doesn''t exist...'   
  
    def on_btnTransfert_mouseClick(self, event):
        try: self.serial=Serial(self.nport,19200,EIGHTBITS,PARITY_NONE,STOPBITS_ONE,1,0,0) 
        except:
           wx.MessageBox('Port %s already opened or does not exist!' %(self.port),'Error', wx.OK)
           return
           
        n=self.components.fldTextField.GetValue() 
        if n!=self.fullname:
           self.fullname=n
           self.name=os.path.basename(self.fullname)
           self.path=self.fullname[:len(self.fullname)-len(self.name)]          
     
        while (os.path.isfile(self.fullname)):
           DotChunks=string.split(self.name ,".")
           extension =DotChunks[-1]
           name=DotChunks[0]
           DotChunks=string.split(self.name ,"0")
           N=int(name[len(DotChunks[0]):])+1
           self.name=DotChunks[0] + '%03d.'%N + extension
           self.fullname=self.path+self.name
           self.components.fldTextField.SetValue(self.fullname)    

        try:
            self.ofile=open(self.fullname, 'wb')
            #print 'File ', self.fullname, ' opened...'
        except:
            #print 'Could not open file ', self.fullname, ' for writing...'
            return
            
        self.components.bufOff.clear()
        #print "command sended"
        time.sleep(.5)
        self.serial.flushInput()
        
        self.command('HARDC:LAY PORTR\n')
        self.command('HARDC:FORM BMP\n')
        self.command('HARDC:PORT RS232\n')
        self.command('ACQU:STATE STOP\n')
        self.command('*WAI\n')
        self.command('HARDC STAR\n')
        self.Size=0
        self.Timer.Start(3000)  # necessary for no detect 0 bytes [len(data)]
        self.Gauge.showModal()
        
        #   PB 19200bps No protocol , sending commands must be
        #   slow => def command(self,st) 
    def command(self,st):
        length=4
        i=len(st)
        while (i>0):
           self.serial.write(st[:length])
           st=st[length:]
           time.sleep(0.01)
           i-=length
        
    def on_timer(self, event):     
        if ( self.Gauge.getstate()==1 ):
           data=self.serial.read(1920)   # 19200/10 bytes in 1 second
           #print len(data)
           if (len(data)!=0):
               self.Size=self.Size +len(data)
               self.ofile.write(data)
               self.Gauge.update((self.Size*100)/self.FILESIZE)
               self.Timer.Start(1000)        # 1 second
           else:
               self.ofile.close()
               self.Gauge.reset()
               self.Gauge.close()
               self.Timer.Stop()
               self.bitmapCanvasLoad()
               self.serial.close() 
        else:
           print "abort"
           self.ofile.close()
           self.Gauge.reset()           
           self.Gauge.close()
           self.Timer.Stop()
           self.bitmapCanvasLoad()
           self.serial.close() 
   
    def on_btnQuit_mouseClick(self, event):
        self.Gauge.destroy()
        fp=open("pyTDS.ini","w")
        self.cfg.write(fp)
        self.Close()
        
    def ID(self):
        try: self.serial=Serial(self.nport,19200,EIGHTBITS,PARITY_NONE,STOPBITS_ONE,1,0,0) 
        except:
           wx.MessageBox('Port %s already opened or does not exist!' %(self.port),'Error', wx.OK)
           return
        for i in range(0,3):
            self.serial.write('ID?\n')   
            ch=self.serial.read(100)
            id=ch[:6]
            if id=="ID TEK":
               pos=ch.find(',')
               id=ch[:pos]
               id=id[7:]
               break
            
        if i==2: wx.MessageBox('No Link with a TDS Family Oscilloscope !','Error', wx.OK)
        else:
            wx.MessageBox('%s Oscilloscope Found!' %(id),'pyTDS', wx.OK)
            if id=="TDS 210":  self.FILESIZE= TDS210
            elif id=="TDS 1002":  self.FILESIZE= TDS1002
            else: print "Unknow FILESIZE !!!"
        self.serial.close()   

    def on_btnId_mouseClick(self, event): 
        self.ID();
                                
    def on_btnFolder_mouseClick(self, event):
        result = dialog.directoryDialog(self, 'Choose a directory', '')
        if result['accepted']==1:
           path = result['path']
           self.path=path
           self.fullname=path+'\\'+self.name
           self.cfg.set('settings','name',self.fullname)
           self.components.fldTextField.SetValue(self.fullname)     

    def on_cmbComboBox_select(self, event):
        select=self.components.cmbComboBox.GetSelection()
        if select==0:   self.port='COM1'
        elif select==1: self.port='COM2'
        elif select==2: self.port='COM3'
        elif select==3: self.port='COM4'
        elif select==4: self.port='COM5'
        elif select==5: self.port='COM6'
        elif select==6: self.port='COM7'
        elif select==7: self.port='COM8'
                      
        self.cfg.set('settings','port',self.port)
        self.nport = int(self.port[3])-1
           
    def on_menuFileExit_select(self, event):
        self.Gauge.destroy()
        self.Close()
        
    def on_menuAbout_select(self, event):   
        msg="""
        pyTDS - V%s - TDS Family Oscilloscope Hardcopy Utility
        
        Format: 19200bps, 8 bits, 1 stop,  No protocol
        
        19200
        NONE
        LF
        NONE

        Dalet Philippe
        Laboratoire STS Electronique
        Lyp Champollion 
        avenue pezet
        46100 FIGEAC
        FRANCE
        
        philippe.dalet@voila.fr       
        """  %(VER)
        dialog.scrolledMessageDialog(self, msg, "About")
        
    def on_btnPrint_mouseClick(self, event):
        pd = wx.PrintData()
        pd.SetPrinterName('')
        pd.SetOrientation(wx.LANDSCAPE)
        pd.SetPaperId(wx.PAPER_A4)
        pd.SetQuality(wx.PRINT_QUALITY_DRAFT)
        pd.SetColour(False) # black & white print
        pd.SetNoCopies(1)
        pd.SetCollate(True)

        pdd = wx.PrintDialogData()
        pdd.SetPrintData(pd)
        pdd.SetSetupDialog(False)
        pdd.SetMinPage(1)
        pdd.SetMaxPage(1)
        pdd.SetFromPage(1)
        pdd.SetToPage(1)
        pdd.SetPrintToFile(False)

        printdialog = wx.PrintDialog(self, pdd)
        if printdialog.ShowModal() != wx.ID_OK: return
        dc = printdialog.GetPrintDC()

        dc.StartDoc(self.fullname)
        dc.StartPage()
        dc.SetUserScale(8,8)    #scale
        if os.path.isfile(self.fullname) and os.path.getsize(self.fullname)==self.FILESIZE:
           self.ofile=open(self.fullname, 'rb')
           bitmap = wx.Bitmap(self.fullname,wx.BITMAP_TYPE_BMP)
           dc.DrawBitmap(bitmap, 100, 100,true)
           self.ofile.close()    

        dc.EndPage()
        dc.EndDoc()
        del dc

if __name__ == '__main__':
    import sys

    app = model.Application(MyBackground)
    wx.InitAllImageHandlers()  # bitmap print necessary
    app.MainLoop()