import hal
import os

#speedcontrol widget color change
import gtk
#for mdi
import linuxcnc
#from gscreen import mdi

#Open speedcontrol.py in directory : /home/grotius/linuxcnc../lib/python/gladevcp/speedcontrol.py
#Change hard settings :
#        'min' : (gobject.TYPE_FLOAT, 'Min Value', 'The min allowed value to apply',
#        -10.0, 99999.0, 0.0, gobject.PARAM_READWRITE | gobject.PARAM_CONSTRUCT),
#In gmocappy they set negative value like this :   self.widgets.spc_jog_vel.set_property("min", -10)
#In custom gscreen here, the widged is called : adaptive_speed

# path to TCL for external programs eg. halshow
try:
    TCLPATH = os.environ['LINUXCNC_TCL_DIR']
except:
    pass

# This is a handler file for using Gscreen's infrastructure
# to load a completely custom glade screen.
# The only things that really matters is that it's saved as a GTK builder project,
# the toplevel window is caller window1 (The default name) and you connect a destroy
# window signal else you can't close down linuxcnc 

# standard handler call
def get_handlers(halcomp,builder,useropts,gscreen):
     return [HandlerClass(halcomp,builder,useropts,gscreen)]


            
class HandlerClass:

    # This will be pretty standard to gain access to everything
    # emc is for control and status of linuxcnc
    # data is important data from gscreen and linuxcnc
    # widgets is all the widgets from the glade files
    # gscreen is for access to gscreens methods
    def __init__(self, halcomp,builder,useropts,gscreen):
            self.emc = gscreen.emc
            self.data = gscreen.data
            self.widgets = gscreen.widgets
            self.gscreen = gscreen
            #for mdi
            self.command = linuxcnc.command()
           
            #adaptive speed, you need special linuxcnc version to do this. G-code must have extra argument's. Extend postprocessor. 
            self.h = hal.component("adaptive")
            self.h.newpin("enable", hal.HAL_BIT, hal.HAL_IN) 
            self.h.newparam("velocity", hal.HAL_FLOAT, hal.HAL_RO) 
            
            #thc function, this has to do with the linuxcnc thcud component and is connected in postgui.hal file
            self.c = hal.component("thc")
            self.c.newpin("enable", hal.HAL_BIT, hal.HAL_IN) 
            self.c.newparam("velocity", hal.HAL_FLOAT, hal.HAL_RO) 
   
   #widget negative adaptive_speed settings         
            self.widgets.adaptive_speed.set_property("min", -1)
            self.widgets.adaptive_speed.set_property("max", 1)
            self.widgets.adaptive_speed.set_value(0)
            #increment
            self.widgets.adaptive_speed.set_property("increment", 0.1)
            #inc_speed
            self.widgets.adaptive_speed.set_property("inc_speed", 100)               
   
   #widget negative thc_min settings         
            self.widgets.thc_min.set_property("min", -10)
            self.widgets.thc_min.set_property("max", 0)
            self.widgets.thc_min.set_value(-5)
            #increment
            self.widgets.thc_min.set_property("increment", 1)
            #inc_speed
            self.widgets.thc_min.set_property("inc_speed", 100)
            
   #widget negative thc_max settings         
            self.widgets.thc_max.set_property("min", 0)
            self.widgets.thc_max.set_property("max", 50)
            self.widgets.thc_max.set_value(25)
            #increment
            self.widgets.thc_max.set_property("increment", 1)
            #inc_speed
            self.widgets.thc_max.set_property("inc_speed", 100)
           

    # This connects siganals without using glade's autoconnect method
    # in this case to destroy the window
    # it calls the method in gscreen: gscreen.on_window_destroy()
    def connect_signals(self,handlers):
        signal_list = [ ["window1","destroy", "on_window1_destroy"],]
        for i in signal_list:
            if len(i) == 3:
                self.gscreen.widgets[i[0]].connect(i[1], self.gscreen[i[2]])
            elif len(i) == 4:
                self.gscreen.widgets[i[0]].connect(i[1], self.gscreen[i[2]],i[3])
 

    #adaptive_speed section
    #turn on/off the adaptive speed widget
    def on_adaptive_speed_on_pressed(self, widget, data=None):
        self.h['enable'] = 1  #adaptive_speed.enable must be coupled in custom_hal file
        #set the color of the widget to red 
        #to do : this must be updated directly on_adaptive_speed_value_changed
        self.widgets.adaptive_speed.set_property("color", gtk.gdk.Color("#FC1002")) 
       
    def on_adaptive_speed_off_pressed(self, widget, data=None):
        self.h['enable'] = 0  #adaptive_speed.enable must be coupled in custom_hal file
        #set the color to intitial grotius grey 
        #to do : this must be updated directly on_adaptive_speed_value_changed
        self.widgets.adaptive_speed.set_property("color", gtk.gdk.Color("#747474")) 
        
    ##
    # Hal example :
    # net systemlink0 adaptive.enable motion.adaptive-feed 
    # motion.adaptive-feed : http://linuxcnc.org/docs/html/man/man9/motion.9.html
    
    def on_adaptive_speed_value_changed(self, widget, data=None):
        self.h['velocity'] = self.widgets.adaptive_speed.get_value()
        
    ##
    #THC function on or off, see thcud component in postgui.hal => link method over there : thc_on.enable 
    #For more info visit : http://linuxcnc.org/docs/html/man/man9/thcud.9.html
    def on_thc_on_pressed(self, widget, data=None):
        self.c['enable'] = 1 
        #set directly the velocity value to the parameter, widgets don't update that for you unles you press them :
        self.c['velocity'] = self.widgets.thc_speed.get_value()       
    def on_thc_off_pressed(self, widget, data=None):
        self.c['enable'] = 0            
    def on_thc_speed_value_changed(self, widget, data=None):
        self.c['velocity'] = self.widgets.thc_speed.get_value()
        
    #zoom in
    def on_zoom_in_pressed(self,*args):
        self.widgets.gremlin.zoom_in()
        
    #zoom out
    def on_zoom_out_pressed(self,*args):
        self.widgets.gremlin.zoom_out()
    
    #view d3
    def on_3d_view_pressed(self, widget, data=None):
        self.widgets.gremlin.current_view = 'p'
        self.widgets.gremlin.set_current_view()
        
    #view top
    def on_top_view_pressed(self, widget, data=None):
        self.widgets.gremlin.current_view = 'z'
        self.widgets.gremlin.set_current_view()

    #view side
    def on_side_view_pressed(self, widget, data=None):
        self.widgets.gremlin.current_view = 'x'
        self.widgets.gremlin.set_current_view()
        
    #clean screen
    def on_clean_screen_pressed(self, widget, data=None):
        self.widgets.clear_live_plotter()
        self.widgets.gremlin.set_current_view()
               
    #halmeter
    def on_halmeter_pressed(self, widget, data=None):
        p = os.popen( "halmeter &" )

    #classicladder
    def on_classicladder_pressed(self, widget, data=None):
        p = os.popen( "classicladder  &", "w" )

    #halshow
    def on_halshow_pressed(self, widget, data=None):
        p = os.popen( "tclsh %s/bin/halshow.tcl &" % TCLPATH )
                
                
    def on_home_all_pressed(self, widget, data=None):
       print " home all pressed "
       self.gscreen.home_all()
       
    def on_unhome_all_pressed(self, widget, data=None):
       print " unhome all pressed "
       self.gscreen.unhome_all()
   
    def on_x_home_pressed(self, widget, data=None):
       print " x home pressed "
       self.emc.home_selected(0)
       
    def on_y_home_pressed(self, widget, data=None):
       print " y home pressed "
       self.emc.home_selected(1)

#####START BUTTON MOVE ##########################################  
## IF POSSIBLE LOAD THIS TO BUTTONS.PY 
## THEN LOAD IT HERE BY COMMAND: load or import buttons.py()
    
    #X_AXIS  screen buttons positive and negative 
    #jogging plus       
    def on_x_plus_pressed(self, widget, data=None):
       print " x plus pressed "         
       self.emc.continuous_jog(0,1)  
    def on_x_plus_released(self, widget, data=None):
       print " x plus released "         
       self.emc.continuous_jog(0,0)
    #jogging min
    def on_x_min_pressed(self, widget, data=None):
       print " x min pressed "         
       self.emc.continuous_jog(0,-1) 
    def on_x_min_released(self, widget, data=None):
       print " x min released "
       self.emc.continuous_jog(0,0)

    #Y_AXIS  screen buttons positive and negative 
    #jogging plus       
    def on_y_plus_pressed(self, widget, data=None):
       print " y plus pressed "         
       self.emc.continuous_jog(1,1)  
    def on_y_plus_released(self, widget, data=None):
       print " y plus released "         
       self.emc.continuous_jog(1,0)
    #jogging min
    def on_y_min_pressed(self, widget, data=None):
       print " y min pressed "         
       self.emc.continuous_jog(1,-1) 
    def on_y_min_released(self, widget, data=None):
       print " y min released "
       self.emc.continuous_jog(1,0)
       
    #Z_AXIS  screen buttons positive and negative 
    #jogging plus       
    def on_z_plus_pressed(self, widget, data=None):
       print " z plus pressed "         
       self.emc.continuous_jog(2,1)  
    def on_z_plus_released(self, widget, data=None):
       print " z plus released "         
       self.emc.continuous_jog(2,0)
    #jogging min
    def on_z_min_pressed(self, widget, data=None):
       print " z min pressed "         
       self.emc.continuous_jog(2,-1) 
    def on_z_min_released(self, widget, data=None):
       print " z min released "
       self.emc.continuous_jog(2,0)     
       
    #A_AXIS  screen buttons positive and negative 
    #jogging plus       
    def on_a_plus_pressed(self, widget, data=None):
       print " a plus pressed "         
       self.emc.continuous_jog(3,1)  
    def on_a_plus_released(self, widget, data=None):
       print " a plus released "         
       self.emc.continuous_jog(3,0)
    #jogging min
    def on_a_min_pressed(self, widget, data=None):
       print " a min pressed "         
       self.emc.continuous_jog(3,-1) 
    def on_a_min_released(self, widget, data=None):
       print " a min released "
       self.emc.continuous_jog(3,0)     
              
    #B_AXIS screen buttons positive and negative 
    #jogging plus       
    def on_b_plus_pressed(self, widget, data=None):
       print " b plus pressed "         
       self.emc.continuous_jog(4,1)  
    def on_b_plus_released(self, widget, data=None):
       print " b plus released "     
       self.emc.continuous_jog(4,0)
    #jogging min
    def on_b_min_pressed(self, widget, data=None):
       print " b min pressed "         
       self.emc.continuous_jog(4,-1) 
    def on_b_min_released(self, widget, data=None):
       print " b min released "
       self.emc.continuous_jog(4,0)       
##### END BUTTON MOVE AXIS SECTION ##########################################         
     
    #Plasma torch on and off signals :
    def on_torch_on_pressed(self, widget, data=None):    
       print " torch on pressed "
       print " fill in code to complete "
    def on_torch_off_pressed(self, widget, data=None): 
       print " torch off pressed "
       print " fill in code to complete "
       
    def on_goto_zero_pressed(self, widget, data=None): 
       self.command.mode(linuxcnc.MODE_MDI)
       self.command.wait_complete()
       self.command.mdi("G0 X0 Y0 Z0")
       print " goto zero pressed "

       
       #gmocappy example
       #command = "M61 Q{0}".format(tool)
       #    self.command.mdi(command)
       
    # set linear jog rate at the jog_speed value.
    def on_jog_speed_value_changed(self, widget,value):
        self.emc.continuous_jog_velocity(velocity = self.widgets.jog_speed.get_value())
        
    def on_program_speed_value_changed(self,widget,value):
        self.emc.feed_override(self.widgets.program_speed.get_value())
    
    def on_reset_program_speed_pressed(self, widget, data=None):
        self.widgets.program_speed.set_value(1)
        # update program_speed widget to linuxcnc
        self.emc.feed_override(self.widgets.program_speed.get_value())
        
    
    
    # We don't want Gscreen to initialize it's regular widgets because this custom
    # screen doesn't have most of them. So we add this function call.
    # Since this custom screen uses gladeVCP magic for its interaction with linuxcnc
    # We don't add much to this function, but we do want the window to display.
    # init_show_window will do this
    def initialize_widgets(self):
        self.gscreen.init_show_windows()
        # set the initial linear jog rate at the jog_speed initial value.
        self.emc.continuous_jog_velocity(self.widgets.jog_speed.get_value())
        # set the initial program speed override.
        self.emc.feed_override(self.widgets.program_speed.get_value())
        
        self.widgets.gremlin.current_view = 'p'
        self.widgets.gremlin.set_current_view()
        # set the initial gremlin screen to mm
        self.widgets.gremlin.set_property('metric_units',True)
        
        # important, when glade value is different it wil only work if you are at zero 0.
        self.widgets.thc_speed.get_value()
 
 

 
    # If we need extra HAL pins here is where we do it.
    # Note you must import hal at the top of this script to do it.
    # For gaxis there is no extra pins but since we don't want gscreen to
    # add it's default pins we added this dunmmy function
    def initialize_pins(self):
        pass

    # every 100 milli seconds this gets called
    # add pass so gscreen doesn't try to update it's regular widgets or
    # add the individual function names that you would like to call.
    def periodic(self):
        #self.widgets.led_emergency_stop.set_active(self.data.estopped)
        self.widgets.led_machine_on.set_active(self.data.machine_on) 

      


