# -*- coding: utf-8 -*-

#
#
# ToDo
#     rename to match conventions make more sense
#            look in build help db
#     clean up gui
#     extend parms and display
#
#     driver for spi i2c
#     clean up debug prints
#     make parm lables an array
#     FIX  up links in open and close
#     begin to fix colors, perhaps thru parms
#
#
#     add blue tooth
#     add some wifi or rpc connect
#     add save to file, perhaps with processing options
#     probe ports
#     probe speeds
#
#
#



from   Tkinter import *
import logger
import parameters
import gui
import os

#import gui2
#import gui_three
#import arduinodriveremu


class MyApp:
    def __init__(self ): ### (1a)
        self.myName         = "MyApp class instance"
        self.version        = "2015 March 01.0"

        self.myParameters   = parameters.Parameters( self ) # open early may effect other

        # module and class name for the communications driver.
        self.comm_mod       = self.myParameters.comm_mod
        self.comm_class     = self.myParameters.comm_class

        self.myLogger       = logger.Logger( self )
        self.myLogger.open()  # later should get file from parameters??

        self.looping        = False   # for our looping operations
        
        self.prog_info()

        #self.myDriver       = arduinodriveremu.ArduinoDriverEmu( self )
        # actually create the communications driver.
        self.myDriver       =  self.create_comm_class( self.myParameters.comm_mod, self.myParameters.comm_class )


        self.win       = Tk()    # this is the tkinter root for the GUI

        self.win.title( "MCU Terminal  version: " + self.version )
        self.myGui     = gui.GUI( self, self.win )  # create the gui or view part of the program
        #self.myGui     = gui2.GUI2( self, self.win )  # create the gui or view part of the program
        #self.myGui     = gui_three.GUIThree( self, self.win )  # create the gui or view part of the program

        self.win.taskDelta  =   self.myParameters.poll_delta_t  # in ms 

        self.win.after( self.win.taskDelta, self.task)   # have to kick off gui task the first time

        #print "about to start mainloop"
        self.win.mainloop()

        print " and we are all over....  "
        return


    def prog_info( self ):
        """
        log info about program and its argument/enviroment
        nice to have system time and date
        """

        self.logit( "" )
        self.logit( "============================" )
        self.logit( "" )

        self.logit( "Running MCUTerminal version = " + self.version  )
        self.logit( "" )
        #  data_dir=russ_data  graph_type=graph_tot
        if len( sys.argv ) == 0:
            logit( "no command line arg " )
        else:
            ix_arg = 0
            for aArg in  sys.argv:

                self.logit( "command line arg " + str( ix_arg ) + " = " + sys.argv[ix_arg])
                ix_arg += 1

        self.logit( "current directory " +  os.getcwd() )
        return


    def create_comm_class( self, module_name, class_name):
        """
        this will load a driver from string names
        so that parameter file can specify dirver, often
        to change comm protocols.
        """

        module = __import__(module_name)
        my_class = getattr( module, class_name )
        instance = my_class( self )
        #print instance, instance.getName()
        return instance


    def task( self, ):
            """
            polling task runs continually in the GUI
            reciving data is an important task.
            polling frequency set via taskDelta, ultimately in parameters
            """

            data   = self.recieve(  )

            if self.looping:

                sdata   = self.myParameters.loop_text
                
                self.myDriver.send( sdata )
                self.myGui.printToSendArea(  sdata )
                pass

            self.win.after( self.win.taskDelta, self.task)  # reschedule event
            return


    def openDriver( self ):

        val   = self.myDriver.open()
        if val:
            status = "Open"
            #self.myLogger.log( "opened ok", "ignored" )
        else:
            status = "Open Failed"
            #self.myLogger.log( "open failed",  "ignored" )

        self.myGui.setOpen( status )

        return


    def closeDriver( self ):

        #self.myLogger.log( "controller says close", "ignored" )

        self.myDriver.close()
        self.myGui.setOpen( "Closed" )

        return


    def send( self, adata ):
         """
         is this where crlf is fixed up, think in gui now
         """

         self.myDriver.send( adata )
         return


    def recieve( self,  ):   # combine with task?
        """
        recieve only full strings ending with /n else
        accumulated in the driver /n is stripped
        """
        # for 232: breaks simulator

        data   = self.myDriver.getRecString( )
        if data == "":
             pass
        else:
             self.myGui.showRecFrame( "<<<" + data )
        return
        

    def logit( self, adata ):
        """
        for compatability with old code

        """
        self.log( adata, "logit" )
        return


    def log( self, adata, ato ):
        """
        just a call to logger
        is this needed/used, can component
        call directly?

        """
        self.myLogger.log( adata, ato )
        return


if __name__ == '__main__':


    aApp = MyApp()
    # clean up, might be nice to get up into the app
    aApp.myDriver.close()
    aApp.myLogger.close()
    aApp.logit( "mcutermainal all done" )






