#!/usr/bin/python

"""
__version__ = "$Revision: 1.0 $"
__date__ = "$Date: 2003/11/01 08:00:29 $"
"""

import os,time
import wx

if wx.Platform == '__WXMSW__':
    from wx.lib.pdfwin import PDFWindow
    
from PythonCard import dialog, graphic, log, model
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 textarea
from PythonCard.components import gauge
from PythonCard.components import imagebutton
from PythonCard.components import slider
import ConfigParser

from serial import *

wildcardFILE = "txt file (*.txt)|*.txt|" \
               "All files (*.*)|*.*"

VER="1.6"

class MyBackground(model.Background):

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

        #FILE 
        self.file=self.cfg.get('settings','file')
        if (len(self.file)!=0):
            self.pathFILE=os.path.dirname(self.file)
        else:
            self.pathFILE=''
        self.components.TextFieldFILE.SetValue(self.file) 
        
        self.number=0
        
        #PORT
        self.nport = int(self.port[3])-1
        self.baud=9600


        #open Serial port
        try:
            self.serial=Serial(self.nport,self.baud,EIGHTBITS,PARITY_NONE,STOPBITS_ONE,1,0,0)
        except:
            wx.MessageBox('Port %s already opened or not exist!' %(self.port),'Error', wx.OK)
            return
        
        self.serial.setRTS(1)
        self.serial.flushInput()
        self.serial.flushOutput()

    def on_btnBrowseFILE_mouseClick(self, event):
        dlg = wx.FileDialog(self, "Choose a file", self.pathFILE, "", wildcardFILE,wx.OPEN)
        if dlg.ShowModal() == wx.ID_OK:
           files = dlg.GetPaths()
           self.file=files[0]
           self.pathFILE=os.path.dirname(self.file)
           if len(self.file)>48:
              self.components.TextFieldFILE.SetValue(files[0])
              self.cfg.set('settings','file',files[0])
           else:
              self.components.TextFieldFILE.SetValue(self.file)
              self.cfg.set('settings','file',files[0])
        dlg.Destroy()


    def on_menuFileAbout_select(self, event):
        msg="""
        pyRS485 - V%s 
        RS485 Terminal 9600bps
        
        Dalet Philippe
        Laboratoire STS Electronique
        Lyp Champollion 
        avenue pezet
        46100 FIGEAC
        FRANCE
        
        philippe.dalet@voila.fr       
        """ %(VER)
        dialog.scrolledMessageDialog(self, msg, "About")
        
    def on_menuFileHelp_select(self, event):
        msg="""
        All characters sent are colored in blue and all received in red
        
        Alphanumeric characters are displayed normally, the others are displayed
        in hexadecimal like this "[0x81]" except '\\r' like "[\\r]"
        
        Protocol:
        MASTER: Adress:0x81 + Command + '\\r' =>  '\\x81GetVoltage\\r'
        SLAVE:     Adress:0x81 + Response +'\\r' =>  '\\x8112.5\\r'
        
        """
        dialog.scrolledMessageDialog(self, msg, "Help")
        
    def on_menuFileExit_select(self, event):
        self.refresh()
        try:
            self.serial.close()
        except:
            pass
        self.Close()
    
    def on_menuFileSchema_select(self, event):
        self.process = wx.Process(self)
        #self.process.Redirect();
        pid = wx.Execute("layout.pdf", wx.EXEC_ASYNC, self.process)
    
    def on_btnQuit_mouseClick(self, event): 
        self.refresh()
        try:
            self.serial.close()
        except:
            pass
        fp=open("pyRS485.ini","w")
        self.cfg.write(fp)
        self.Close()
        
    def refresh(self):
        if (self.components.ComboBoxPORT.GetValue()!= self.port):
           self.port=self.components.ComboBoxPORT.GetValue()
           self.cfg.set('settings','port',self.port)
           self.nport = int(self.port[3])-1
           try:
                self.serial.close()
           except:
                pass
                
           try:
               self.serial=Serial(self.nport,self.baud,EIGHTBITS,PARITY_NONE,STOPBITS_ONE,1,0,0)
           except:
               wx.MessageBox('Port %s already opened or not exist!' %(self.port),'Error', wx.OK)
               return
    
    def display(self, str, color):
        text=""
        for i in range (0,len(str)):
            if (ord (str[i]) < 128):
               if str[i]!='\r':
                  text=text+str[i]
            else:
               text=text+ "[%X]" %(ord (str[i]) )
                  
        text=text+"[\\r]\r\n"
        self.components.TextArea1.SetStyle(self.number, self.number+len(text), wx.TextAttr(color, "WHITE"))
        self.components.TextArea1.AppendText(text)
        self.number=self.number+len(text)

    def pdisplay(self, str,):
        text=""
        for i in range (0,len(str)):
            if (ord (str[i]) < 128):
               if str[i]!='\r':
                  text=text+str[i]
            else:
               text=text+ "[%X]" %(ord (str[i]) )
                  
        text=text+"\r\n"
        print text
        
    def on_btnCLEAR_mouseClick(self, event): 
        self.components.TextArea1.SetValue("")
        self.number=0

    def on_btnSEND_mouseClick(self, event): 
        self.refresh()
        #open TXT file
        try:
           file = open(self.file, 'rb')
        except:
           wx.MessageBox('File %s cannot opened !' %(self.file),'Error', wx.OK)
           return
           
        #test port COMx
        try:
           self.serial.setRTS(0)
        except:
            wx.MessageBox('Port %s not opened!' %(self.port),'Error', wx.OK)
            return  
            
        str=file.read(os.path.getsize(self.file))
        file.close()
        self.display(str,'BLUE')

        self.serial.flushInput()
        self.serial.setRTS(0)
        self.serial.write(str) 
        self.serial.write('\r') #send CR 
        # 20ms necessary : after write instruction the '\r' is always in the buffer, but not in the UART
        # print self.serial.outWaiting() ,
        time.sleep(0.01)
        # print self.serial.outWaiting()
        self.serial.setRTS(1)

        self.serial.setTimeout(1)
        programmed = self.serial.read(1)
        #self.display(programmed,'RED')
        
        
        #if not programmed:
        #    wx.MessageBox('%s: Serial Port Timeout!' %(self.port),'Error', wx.OK)
        #    #self.pdisplay(programmed)
        #    return
        
        self.pdisplay(str[0])
        self.pdisplay(programmed)
        
        if (programmed==str[0]):
           str=programmed
           while (str.find('\r')==-1):                       #loop while this flag is true
               str = str+ self.serial.read(1)           #read one, with timout
           self.display(str,'RED')
        else:
           if not programmed: 
               print '[NULL]'
           else:
               print programmed
           self.display("No Response",'RED')
           #self.pdisplay(programmed)
    
if __name__ == '__main__':
    import sys
    app = model.Application(MyBackground) 
    app.MainLoop()