######################################## oscopegraphlibyy.py ################################
# Peter Halverson  May 25, 2015

#Multi-channel oscilloscope    (Note that its slow.  Will not work faster than 2 samples per second)
#Now has optional XGraph time axis in seconds to midnight

import turtle
import time

oscope_turtle = None
oscope_display_needs_refresh = True
XGraph_colors = ['black','white','red','blue','green','violet','orange','yellow','pink','cyan','light-gray','dark-gray','fuchsia','aqua','navy','gold']

def oscope(user_y_list,smallest_y=0.0,biggest_y=2.5,sample_period=0.1,samples_per_sweep=20,  \
           record_for_xgraph=False,use_seconds_since_midnight=False):
  global oscope_turtle
  global oscope_display_needs_refresh
  global oscope_sample_number_for_xgraph
  global oscope_sample_number_this_sweep
  global data_file
  global old_x,old_y_list
  global midnight_seconds_for_oscope
  first_call=False
  if oscope_turtle is None:
      first_call=True
      print "Starting turtle graphics"
      oscope_turtle = turtle.Pen()                # "Pen" must start with a capital P!
      oscope_turtle.speed(0)                      # 0 is fastest
      oscope_turtle.hideturtle() 
      old_y_list=user_y_list
      if record_for_xgraph:
        file_name=raw_input('''Enter a file name to make a xgraph (do not put ".dat"):  ''')
        title = raw_input("Enter the title of the graph. (Or just press Enter): ")
        numbered_file_name=file_name+"0.dat"
        print "Creating data file for channel 0, file name=",numbered_file_name
        print "XGraph number ",0," will have color ",XGraph_colors[0+2]
        data_file=[open(numbered_file_name,"w")]
        if title != "":
          data_file[0].write("Title =")
          data_file[0].write(title)
          data_file[0].write("\n")
        data_file[0].write("thickness = 2\n")
        data_file[0].write("title_x = time\n")
        data_file[0].write("title_y = V\n")
        data_file[0].write("color "+str(0+2)+"\n")
        for i in range(1,len(user_y_list)):
          numbered_file_name=file_name+str(i)+".dat"
          print "Creating data file for channel ",i,", file name=",numbered_file_name
          data_file=data_file+[open(numbered_file_name,"w")]
          print "XGraph number ",i," will have color ",XGraph_colors[i+2]
          #Set the Xgraph color of the graph
          data_file[i].write("color "+str(i+2)+"\n")
        oscope_sample_number_for_xgraph=0
        ############ Special code to record x-axis in seconds since midnight
        now_struct = time.localtime()
        now_list = list(now_struct)     #convert struct_time to a list
        midnight_list=now_list
        midnight_list[3]=0      #Set the hours to zero
        midnight_list[4]=0      #Set the minutes to zero
        midnight_list[5]=0      #Set the seconds to zero
        midnight_struct=time.struct_time(midnight_list) # convert to a struct_time 
        #print "midnight_struct=",midnight_struct
        midnight_seconds_for_oscope=time.mktime(midnight_struct)
        #print "midnight_seconds_for_oscope=",midnight_seconds_for_oscope
  smallest_x=0.0
  biggest_x=sample_period*samples_per_sweep
  window_max_x = oscope_turtle.window_width()/2.1
  window_max_y = oscope_turtle.window_height()/2.1
  #print "window_max_x",window_max_x
  #print "window_max_y",window_max_y
  if oscope_display_needs_refresh:
    oscope_turtle.clear()
    oscope_turtle.pencolor("black")
    # Draw a box
    oscope_turtle.penup()
    oscope_turtle.goto(-window_max_x,-window_max_y)
    oscope_turtle.pendown()
    oscope_turtle.goto(-window_max_x,window_max_y)
    oscope_turtle.goto(window_max_x,window_max_y)
    oscope_turtle.goto(window_max_x,-window_max_y)
    oscope_turtle.goto(-window_max_x,-window_max_y)  
    # Draw x and y axes
    # Draw the X axis
    oscope_turtle.penup()
    y=1.0*(-smallest_y+0.0)/(biggest_y-smallest_y)  #Make y between 0 and 1
    y=-window_max_y+(y*2.0*window_max_y)  #Make y have the full window width range
    oscope_turtle.goto(-window_max_x,y)
    oscope_turtle.pendown()
    oscope_turtle.goto(window_max_x,y)      #X axis
    oscope_turtle.penup()    
    oscope_turtle.goto(window_max_x*0.98,0.0)
    oscope_turtle.write(str(biggest_x)+" s",align="right",font=("Arial", 18, "normal"))
    # Draw the Y axis
    oscope_turtle.penup()
    x=1.0*(-smallest_x+0.0)/(biggest_x-smallest_x)  #Make x be tween 0 and 1
    x=-window_max_x+(x*2.0*window_max_x)  #Make x have the full window width range
    old_x=x
    oscope_turtle.goto(x,-window_max_y)
    oscope_turtle.pendown()
    oscope_turtle.goto(x,window_max_y)      #Y axis
    oscope_turtle.penup()    
    oscope_turtle.goto(x+window_max_x*0.025,0.92*window_max_y)
    oscope_turtle.write(str(biggest_y),align="left",font=("Arial", 18, "normal"))
    oscope_turtle.goto(x+window_max_x*0.025,-0.96*window_max_y)
    oscope_turtle.write(str(smallest_y),align="left",font=("Arial", 18, "normal"))   
    oscope_sample_number_this_sweep=0
    oscope_display_needs_refresh = False

  oscope_x=1.0 * sample_period * oscope_sample_number_this_sweep
  #print "oscope_x=",oscope_x,
  x=1.0*(-smallest_x+oscope_x)/(biggest_x-smallest_x)  #Make x be tween 0 and 1
  x=-window_max_x+(x*2.0*window_max_x)  #Make x have the full window width range
  #if first_call:
  #   old_x=x
  for i in range(0,len(user_y_list)):
    #print "  user_y_list[",i,"]=",user_y_list[i],
    y=1.0*(-smallest_y+user_y_list[i])/(biggest_y-smallest_y)  #Make y be tween 0 and 1
    y=-window_max_y+(y*2.0*window_max_y)  #Make y have the full window height range
    oscope_turtle.penup()
    oscope_turtle.goto(old_x,old_y_list[i])
    if i==0:
      oscope_turtle.pencolor("black")
    elif i==1:
      oscope_turtle.pencolor("brown")
    elif i==2:
      oscope_turtle.pencolor("red")
    elif i==3:
      oscope_turtle.pencolor("orange")
    elif i==4:
      oscope_turtle.pencolor("yellow")
    elif i==5:
      oscope_turtle.pencolor("green")
    elif i==6:
      oscope_turtle.pencolor("blue")
    elif i==7:
      oscope_turtle.pencolor("violet")
    else:
      oscope_turtle.pencolor("#8f8f8f")
    oscope_turtle.pendown()
    oscope_turtle.goto(x,y)
    old_y_list[i]=y
  old_x=x  
  #  if i==0:          #You want to draw after the turtle is at the first point location
  oscope_turtle.pendown()
  oscope_sample_number_this_sweep = oscope_sample_number_this_sweep + 1
  oscope_display_needs_refresh = (oscope_sample_number_this_sweep == samples_per_sweep)
  if (not first_call) and record_for_xgraph:
    #print "record for xgraph, user_y_list=",user_y_list
    if use_seconds_since_midnight:
      time_to_record = time.time() - midnight_seconds_for_oscope
    else:
      time_to_record = oscope_sample_number_for_xgraph*sample_period
    for i in range(0,len(user_y_list)):
      data_file[i].write(str(time_to_record)+" "+str(user_y_list[i])+"\n")
    oscope_sample_number_for_xgraph=oscope_sample_number_for_xgraph + 1
  return
