#!/usr/bin/env python
import sys
import os
import io
import PySimpleGUI as sg
import matplotlib.pyplot as plt
import math
import PIL
import xlrd

VERBOS= False

if 0:
  data= [[1,2,3,4,5,6],[1,2,3,4,5,6],[1,2,3,4,5,6],[1,2,3,4,5,6],[1,2,3,4,5,6],]
  print(data)
  labels= "A B C D E F"
  header_list= labels.split()
  
  layout=[
    [sg.Table(
      key='-TABLE-',
      values=data,
      headings=header_list, 
      display_row_numbers=True,
      vertical_scroll_only=False,
      auto_size_columns=False, 
      num_rows=min(25,len(data)))
    ],
    [sg.Button('Read'),],    
  ]
  if 0:
    window= sg.Window('Table', layout, grab_anywhere=True) 
  else:
    window= sg.Window('Table', layout, location=(100,100),grab_anywhere=True) 
  # grab_anywhere True: 
  # can use mouse to click and drag to move the window
  while True:
    event, values = window.read()
    # print(event)
    # print(values)
    if event=='Read':
      print(values.get('-TABLE-'))
    if event == sg.WIN_CLOSED:
      break
    # if event == 'Double':
    #   for i in range(len(data)):
    #     data.append(data[i])
    #   window['-TABLE-'].update(values=data)
    # elif event == 'Change Colors':
    #   window['-TABLE-'].update(row_colors=((8, 'white', 'red'), (9, 'green')))

  window.close()

  sys.exit() 

def listbox_select(msg1,msg2,choices):
  layout= [
    [sg.Text(msg2)],
    [sg.Listbox(choices, size=(15, len(choices)), key='-SELEC-')],
    [sg.Button('Ok')]
  ]
  window = sg.Window(msg1, layout)
  event, values = window.read()
  window.close()
  if values['-SELEC-']:
    res= values['-SELEC-'][0]
  else:
    res= None
  return res

def xls_open(new_file,initial_path):
  initial_folder,tail= os.path.split(initial_path)

  if new_file:
    sg.SetOptions(auto_size_buttons=True)

    browser= sg.FileBrowse(
      initial_folder= initial_folder, 
      file_types = (('xls Files', '*.xls'),),)
    layout= [
      [sg.Input(key='_FILES_'), browser], 
      [sg.OK(), sg.Cancel()]
            ]
    #event, values = sg.Window('Chose Input File').Layout(layout).Read()
    window = sg.Window('Chose Input File', layout)
    event, values = window.read()
    filepath= values['_FILES_']
    window.close()
  else:
    filepath= initial_path
  #filepath= sg.PopupGetFile( 
  #            'input file', # location=[100,100],
  #            no_window=True,
  #            initial_folder= initial_folder,
  #            file_types=(("Excel Files", "*.xls"),))
  if filepath == '':
    sys.exit(69)
  if filepath is not None:
    try:
      wb= xlrd.open_workbook(filepath)
    except:
      sg.PopupError('Error reading file')
      sys.exit(69)
    
  if new_file:
    sheet_names= wb.sheet_names()
    if VERBOS: print(sheet_names)
    if len(sheet_names)>1:
      res= listbox_select("sheets","which sheet ?",sheet_names)
      isheet= sheet_names.index(res)
    else:
      isheet= 0
  else:
    isheet= 0
  sheet= wb.sheet_by_index(isheet)

  f=open("geoxdraw.files",'w')
  f.write(os.path.relpath(filepath)+'\n')
  f.write(str(isheet)+'\n')
  f.close()
  
  filename= extractFileName(filepath)
  
  return sheet,filename
  
#---------------------------------------------------------xlrd--xls-only
def xls_read(sheet):
  from pylab import zeros
  
  row= sheet.row(0)
  if VERBOS: print(row)
  # process first line for field names
  labelStr= [x.value for x in row if x.value[0]=='.']  # descriptive fields (char strings values)
  labelNum= [x.value for x in row if x.value[0]!='.']  # numeric fields
  if VERBOS: print(labelStr)
  if VERBOS: print(labelNum)
  
  nCols= sheet.ncols
  nRows= sheet.nrows
  TS= []
  TR= []
  #TT= zeros((nRows-2,len(labelNum)),'float')
  # iterate through rows and columns, starting at row 2
  for iRow in range(1,nRows):
    if sheet.cell(iRow, 0).value=='!': break
    if sheet.cell(iRow, 0).value=='': continue
    S= []
    T= zeros((len(labelNum)),'float')
    for iCol in range(0,nCols):
      x= sheet.cell(iRow, iCol).value
      if iCol<len(labelStr):
        S.append(x)
      else:
        if VERBOS: print(x)
        T[iCol-len(labelStr)]= x
    TS.append(S)
    TR.append(T)
  TT= zeros((len(TR),len(labelNum)),'float')
  for iRow in range(len(TR)):
    TT[iRow,:]= TR[iRow]
  if VERBOS:
    for S in TS: print(S)
  
  return labelStr,TS,labelNum,TT

def screensize():
  import tkinter
  root= tkinter.Tk()
  width= root.winfo_screenwidth()
  height= root.winfo_screenheight()
  root.destroy()
  del root
  return width,height

def num(s):
  try: return float(s)
  except: return 0.
    
def extractFileName(s):
  head,tail= os.path.split(s)
  if '.' in tail:
    name_= tail.split('.')[0]
  else:
    name_= tail
  return name_

#------------------------------------------for text input--NOT USED HERE
def lines2table(lines):
  from pylab import zeros
  
  lines= [x for x in lines if len(x.strip())>0] #remove empty lines
  lines= [x for x in lines if x[0] != '!'] #skip comment lines
  
  labels= lines[0].split()
  labelStr= [x for x in labels if x[0]=='.']  # descriptive fields (char strings values)
  labelNum= [x for x in labels if x[0]!='.']  # numeric fields
  if VERBOS: print(labelStr)
  if VERBOS: print(labelNum)
  TS= []
  TT= zeros((len(lines)-1,len(labelNum)),'float')
  for i,line in enumerate(lines):
    if i==0: continue #skip first line
    ww= line.split()
    S=[]
    for j in range(len(labelStr)): S.append(ww[j])
    if VERBOS: print(S)
    TS.append(S)
    for j in range(len(labelNum)): 
      TT[i-1,j]= num(ww[j+len(labelStr)])
  return labelStr,TS,labelNum,TT

#------------------------------------------for text input--NOT USED HERE
def table_read(initial_folder):
  sg.SetOptions(auto_size_buttons=True)
  filepath= sg.PopupGetFile( 
              'input file', # location=[100,100],
              no_window=True,
              initial_folder= initial_folder,
              file_types=(("tab Files", "*.tab"),("txt Files", "*.txt")))
  if filepath == '':
    sys.exit(69)
  # button= sg.PopupYesNo('Does this file have column names already?')
  if filepath is not None:
    try:
      with open(filepath,'r') as f: lines= f.readlines()
      f.close()
    except:
      sg.PopupError('Error reading file')
      sys.exit(69)
  
  f=open("geoxdraw.files",'w')
  filepath= os.path.relpath(filepath)
  f.write(filepath+'\n')
  f.close()
  
  filename= extractFileName(filepath)
  
  return lines,filename
  
#----------------------------------------------------------NOT USED HERE
def table_show(header_list,data):
  layout=[[sg.Table(
             values=data,
             headings=header_list, 
             display_row_numbers=True,
             vertical_scroll_only=False,
             auto_size_columns=False, 
             num_rows=min(25,len(data)))]]

  window= sg.Window( 
             'Table', 
             # location=(100,100),
             grab_anywhere=False) 
  # grab_anywhere True: 
  # can use mouse to click and drag to move the window
  event, values= window.Layout(layout).Read()

#---------------------------------------------------MATPLOTLIB CODE HERE
def build_figure(data_lump,selec_lump,ix,iy,auto_minmax,minmax,loglog,LegLoc):
  colors = ['cyan', 'lightblue', 'lightgreen', 'tan', 'pink','red', 'blue', 'darkgreen', 'navy', 
            'cyan', 'lightblue', 'lightgreen', 'tan', 'pink','red', 'blue', 'darkgreen', 'navy']
  couleur= "grey indianred darkred red orange gold greenyellow lightgreen limegreen teal dodgerblue blue darkviolet violet deeppink"
  colors= couleur.split()
  symbols=[ 'o', 'v', 'H', 'X', 's', 'p', 'P', '*', 'D', '^',\
            'h', '>', 'd', '+', '<', 'x', '1', '2', '3', '4']
  
  fs12= 14
  
  labelStr,dataStr,labelNum,dataNum,dictStr= data_lump
  iSel1,iSel2,lisSel,iLbl, bColsym= selec_lump
  
  if bColsym:
    iColsym= labelStr.index(".COLSYM")
    Selec1= dictStr[iColsym]
    iSel1= -1
    iSel2= -1
  else:
    iColsym= -1
  if iSel1>=0:
    Selec1= dictStr[iSel1]
  if iSel2>=0:
    Selec2= dictStr[iSel2]
  len_num= len(dataNum)
  
  xmin,xmax,ymin,ymax= minmax
  xAuto,yAuto= auto_minmax
  xLog,yLog= loglog
  
  isOk= []
  if len(lisSel)>0:
    for ll in lisSel:
      w= ll.split('=')
      iSel= labelStr.index(w[0])
      isOk.append(w[1])
    if VERBOS: print("isOk=",isOk)
  else:
    iSel= iSel1
    isOk= dictStr[iSel1]
    
  fig= plt.figure(figsize=(12,8))
  ax= fig.add_subplot(111)
  
  if xLog: ax.set_xscale('log')
  if yLog: ax.set_yscale('log')
  plt.grid(True,linestyle='--')
  
  if len(iy)>1:
  #-----------------------------------------------------------multiple y
    ax.set(xlabel=labelNum[ix])
    if not xAuto: ax.set_xlim(xmin,xmax)
    if not yAuto: ax.set_ylim(ymin,ymax)
    # x=dataNum[:,ix]
    x= [ dataNum[i,ix] for i in range(len_num) if dataStr[i][iSel] in isOk ]
    if iSel1>=0:
      mk= [ dataStr[i][iSel1]  for i in range(len_num) if dataStr[i][iSel] in isOk ]
      mk= [ symbols[Selec1.index(m)] for m in mk ]      
    k=0
    for j in iy:
      color=colors[k]
      lb= labelNum[j]
      #if iSel1>=0:
      #  marker= mk
      #else:
      marker= symbols[(k)%len(symbols)]
      y= [ dataNum[i,j] for i in range(len_num) if dataStr[i][iSel] in isOk ]
      # plt.plot(x,y, '-o', c=color, label=lb,linewidth= 1) #, s=scale, marker=marker
      # plt.plot(x,y, c=color, marker=marker, label=lb) #linestyle='-', linewidth=1.0,
      ax.scatter(
        x,y, 
        c=color, marker=marker, s= 100, 
        label=lb, edgecolor='black')
      plt.legend(loc=LegLoc)
      k+=1
  else:
  #-------------------------------------------------------------single y
    colStr= ['0.5']
    labStr= []
    
    ax.set(xlabel=labelNum[ix], ylabel=labelNum[iy[0]])
    if not xAuto: ax.set_xlim(xmin,xmax)
    if not yAuto: ax.set_ylim(ymin,ymax)
    if iColsym>=0:
      for sel in Selec1:
        x= []
        y= []
        for i in range(len_num):
          if dataStr[i][iColsym]==sel and dataStr[i][iSel] in isOk:
            x.append(dataNum[i,ix])
            y.append(dataNum[i,iy[0]])
            color=  dataStr[i][iColsym][0]
            marker= dataStr[i][iColsym][1]
            label=  dataStr[i][iColsym-1]
        if len(x)>0:
          ax.scatter(
            x,y, 
            c=color, marker=marker, s= 100, 
            label=label, edgecolor='black')
      plt.legend( loc=LegLoc)
    elif iSel1<0:
      x= [ dataNum[i,ix]    
           for i in range(len_num) if dataStr[i][iSel] in isOk ]
      y= [ dataNum[i,iy[0]] 
           for i in range(len_num) if dataStr[i][iSel] in isOk ]
      color,scale,marker= '0.5',100,'s'
      ax.scatter(
         x,y, 
         c=color, marker=marker, s= 100, 
         edgecolor='black')
    else:
      for k,sel in enumerate(Selec1):
        if iSel2<0: #or iSel2==iSel1:
          color= "" #colors[k]
        else:
          color= [dataStr[i][iSel2] for i in range(len_num) if dataStr[i][iSel1]==sel and dataStr[i][iSel] in isOk]
          color= [colors[Selec2.index(c)] for c in color]
        marker= symbols[k]
        x= [dataNum[i,ix]    for i in range(len_num) if dataStr[i][iSel1]==sel and dataStr[i][iSel] in isOk]
        y= [dataNum[i,iy[0]] for i in range(len_num) if dataStr[i][iSel1]==sel and dataStr[i][iSel] in isOk]
        if len(x)>0:
          ax.scatter(
            x,y, 
            c=color, marker=marker, s= 100, 
            label=sel, edgecolor='black')
      plt.legend( loc=LegLoc)
      
    # labels on each point
    if iLbl>=0:
      vx= [ dataNum[i,ix]    for i in range(len_num) if dataStr[i][iSel] in isOk ]
      vy= [ dataNum[i,iy[0]] for i in range(len_num) if dataStr[i][iSel] in isOk ]
      vl= [ dataStr[i][iLbl] for i in range(len_num) if dataStr[i][iSel] in isOk ]
      for lb, x, y in zip(vl, vx, vy):
        plt.annotate(
          lb, 
          xy = (x, y),
          xytext = (-2,2),
          textcoords = 'offset points', 
          ha = 'right',   #horizontal adjust
          va = 'bottom')  #vertical adjust
  
  #fig= plt.gcf()
  if len(lisSel)>0:
    if VERBOS: print("isOk=",isOk)
    s= labelStr[iSel]+'='
    for t in isOk:
      s= s +t +', '
    fig.text(0.02,0.98,s,size=12,ha='left', va='top')

  #fig.set_size_inches(8.,6.,forward=True)
  #fig.set_dpi(100)
  return fig # ,figure_w, figure_h

#--------------------------------------- PASTE YOUR MATPLOTLIB CODE HERE
def build_boxplot(data_lump,iSel1,iSel2,lisSel,xlog):
  # import matplotlib.axes as ax
  colors = ['cyan', 'lightblue', 'lightgreen', 'tan', 'pink','red', 'blue', 'darkgreen', 'navy', 
            'cyan', 'lightblue', 'lightgreen', 'tan', 'pink','red', 'blue', 'darkgreen', 'navy']
  labelStr,dataStr,labelNum,dataNum,dictStr= data_lump
  
  isOk= []
  if len(lisSel)>0:
    for ll in lisSel:
      w= ll.split('=')
      iSel= labelStr.index(w[0])
      isOk.append(w[1])
    if VERBOS: print("isOk=",isOk)
  else:
    iSel= iSel1
    isOk= dictStr[iSel1]

  if iSel1>=0:
    Selec1= dictStr[iSel1]
  if iSel2>=0:
    Selec2= dictStr[iSel2]
    
  box_plot_data=[]
  color=[]
  vlabs=[]
  if iSel2>=0:
    for sel1 in Selec1:
      for sel2 in Selec2:
        x= [dataNum[i,ix] \
            for i in range(len(dataNum)) \
            if dataStr[i][iSel1]==sel1 and dataStr[i][iSel2]==sel2 and dataStr[i][iSel] in isOk]
        if len(x)>7:
          box_plot_data.append(x)
          vlabs.append(sel1+sel2)
  else:
    for sel1 in Selec1:
      x= [dataNum[i,ix] for i in range(len(dataNum)) \
            if dataStr[i][iSel1]==sel1 and dataStr[i][iSel] in isOk]
      if len(x)>7:
        box_plot_data.append(x)
        vlabs.append(sel1)

  # Create a figure instance
  fig= plt.figure(1, figsize=(8.,6.))
  # Create an axes instance
  ax = fig.add_subplot(111)
  # Create the boxplot
  bp = ax.boxplot(box_plot_data, vert=0)
  ## add patch_artist=True option to ax.boxplot() to get fill color
  bp = ax.boxplot(box_plot_data, vert=0, patch_artist=True)
  for patch, color in zip(bp['boxes'], colors):
    patch.set_facecolor(color)
  ## Custom y-axis labels
  ax.set_yticklabels(vlabs)
  ## semilog diagram
  ## ax.set_yscale('log')
  # Add a horizontal grid to the plot, but make it very light in color
  # so we can use it for reading data values but not be distracting
  ax.xaxis.grid(True, linestyle='-', which='major', color='grey',
                 alpha=0.5)
  # ax.set_axisbelow(True)
  ## change outline color, fill color and linewidth of the boxes
  if 0:
    for box in bp['boxes']:
      # change outline color
      box.set( color='#7570b3', linewidth=2)
      # change fill color
      box.set( facecolor = '#1b9e77' )
  ## change color and linewidth of the whiskers
  if 0:
    for whisker in bp['whiskers']:
      whisker.set(color='#7570b3', linewidth=2)
  ## change color and linewidth of the caps
  if 0:
    for cap in bp['caps']:
      cap.set(color='#7570b3', linewidth=2)
  ## change color and linewidth of the medians
  if 1:
    for median in bp['medians']:
      median.set(color='black', linewidth=3)
  ## change the style of fliers and their fill
  if 1:
    for flier in bp['fliers']:
      flier.set(marker='o', color='#e7298a', alpha=0.5)
  ## Remove top axes and right axes ticks
  ax.get_xaxis().tick_bottom()
  ax.get_yaxis().tick_left()
  if xlog: ax.set_xscale('log')
  
  fig.set_dpi(100)
  
  return fig
#------------------------------------------- END OF YOUR MATPLOTLIB CODE

def convert_to_bytes(file_or_bytes, resize=None):
# retrieved from demo scripts
  if isinstance(file_or_bytes, str):
    img = PIL.Image.open(file_or_bytes)
  else:
    try:
      img = PIL.Image.open(io.BytesIO(base64.b64decode(file_or_bytes)))
    except Exception as e:
      dataBytesIO = io.BytesIO(file_or_bytes)
      img = PIL.Image.open(dataBytesIO)

  cur_width, cur_height = img.size
  if resize:
    new_width, new_height = resize
    scale = min(new_height/cur_height, new_width/cur_width)
    img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL.Image.ANTIALIAS)
  with io.BytesIO() as bio:
    img.save(bio, format="PNG")
    del img
    return bio.getvalue()

initial_path= ""
if os.path.exists("geoxdraw.files"):
  with open("geoxdraw.files",'r') as f: lines= f.readlines()
  f.close()
  initial_path= lines[0].strip()
  if len(lines)>1:
    initial_sheet= int(lines[1].strip())
  try:
    wb= xlrd.open_workbook(initial_path)
  except:
    #sg.PopupError('Error reading file')
    initial_path= ""
if initial_path == "":
  new_file= True
else:
  new_file= False

# ------------------------------------------------------ GUI Starts Here
# fig= your figure you want to display. 
# Assumption is that 'fig' holds the  information to display

lisPosition=['best','Up-right','Up-left','Low-left','Low-right','Right',\
             'Cent-left','Cent-right','Low-cent','Up-cent','Center']
iSel1= -1
iSel2= -1
lisSel= []
ix= 0
iy= [0]

MAXSYM= 20
MAXCOL= 20

w,h= screensize()
if h<800:
  fig_w, fig_h= 640,480
else:  
  fig_w, fig_h= 800,600
if VERBOS: print(fig_w, fig_h)
  
end= False
START= True
while True:
  
  #lines,fname= table_read(initial_folder)
  #labelStr,dataStr,labelNum,dataNum= lines2table(lines)
  
  sheet,fname= xls_open(new_file,initial_path)
  labelStr,dataStr,labelNum,dataNum= xls_read(sheet)
  
  dictStr=[]
  for i,s in enumerate(labelStr):
    lis=[]
    for dd in dataStr:
      if not dd[i] in lis:
        lis.append(dd[i])
    dictStr.append(lis)
  for d in dictStr:
    if len(d)<10: 
      if VERBOS: print(d)
  listSelec=[]
  for i,lb in enumerate(labelStr):
    if len(dictStr[i])<20:
      for dic in dictStr[i]:
        if VERBOS: print(lb+"="+dic)
        listSelec.append(lb+"="+dic)

  data_lump= labelStr,dataStr,labelNum,dataNum,dictStr

  if end:
    break

  vmin= 0. #[min(dataNum[:,i]) for i in range(len(labels))]
  vmax= 1. #[max(dataNum[:,i]) for i in range(len(labels))]

  xmin,xmax=0.0,1.0
  ymin,ymax=0.0,1.0 
  minmax= xmin,xmax,ymin,ymax
  xLog= False
  yLog= False
  xAuto= True
  yAuto= True
  bBoxP= False
  #xAtom= False
  #yAtom= False
  bMute= True
  bAtom= False
  if ".COLSYM" in labelStr:
    bColsym= True
  else:
    bColsym= False
  
  #labelNum= []
  #labelStr= []
  #-------------------------------------------------x-y coord's selection
  colXsel=[
        [sg.Text('X-coord')],
        [sg.Listbox(
          values= labelNum,
          select_mode=sg.LISTBOX_SELECT_MODE_SINGLE, 
          size=(12,min(18,len(labelNum))))],
        [sg.CBox('Log',    key='_xlog_', default=xLog)],
        #[sg.CBox('atomic', key='_xatom_',default=xAtom)],
          ]
  colYsel=[
        [sg.Text('Y-coord(s)')],
        [sg.Listbox(
          values= labelNum,
          select_mode=sg.LISTBOX_SELECT_MODE_MULTIPLE,
          size=(12,min(18,len(labelNum))))],
        [sg.CBox('Log',    key='_ylog_', default=yLog)],
        #[sg.CBox('atomic', key='_yatom_',default=yAtom)],
          ]
  colSym=[[sg.Listbox(
          values= labelStr,
          select_mode=sg.LISTBOX_SELECT_MODE_SINGLE,
          size=(8,min(4,len(labelStr))))],
          [sg.Text('Symbols')]]
  colCol=[[sg.Listbox(
          values= labelStr,
          select_mode=sg.LISTBOX_SELECT_MODE_SINGLE,
          size=(8,min(4,len(labelStr))))],
          [sg.Text('Colors')]]
  colSel=[[sg.Listbox(
          values= listSelec,
          select_mode=sg.LISTBOX_SELECT_MODE_MULTIPLE,
          size=( 12,min(4,len(listSelec)) ) )],
          [sg.Text('Select')]]
  colLbl=[[sg.Listbox(
          values= labelStr,
          select_mode=sg.LISTBOX_SELECT_MODE_SINGLE,
          size=(8,min(4,len(labelStr))))],
          [sg.Text('Labels')]]
  colLeg=[[sg.Listbox(
          values= lisPosition,
          select_mode=sg.LISTBOX_SELECT_MODE_SINGLE,
          size=(8,4))],
          [sg.Text('Position')]]
  #------------------------------------------------//x-y coord's selection
  
  colX= [ 
    [sg.CBox('auto', key='_xauto_',default=xAuto)],
    [sg.T('MAX'), sg.In(default_text=str(xmax), size=(8,1), key='_xmax_')],
    [sg.T('MIN'), sg.In(default_text=str(xmin), size=(8,1), key='_xmin_')],
  ]
  colY= [ 
    [sg.CBox('auto', key='_yauto_',default=yAuto)],
    [sg.T('MAX'), sg.In(default_text=str(ymax), size=(8,1), key='_ymax_')],
    [sg.T('MIN'), sg.In(default_text=str(ymin), size=(8,1), key='_ymin_')],
  ]
  if ".COLSYM" in labelStr:
    colBools= [ 
      [sg.CBox('COLSYM',  key='_colsym_', default=bColsym)],
      [sg.CBox('MUTIC',   key='_mute_',   default=bMute)],
      [sg.CBox('ATOMIC',  key='_atom_',   default=bAtom)],
      [sg.CBox('BOXPLOT', key='_boxp_',   default=bBoxP)],
    ]
  else:
    colBools= [ 
      [sg.CBox('MUTIC',   key='_mute_', default=bMute)],
      [sg.CBox('ATOMIC',  key='_atom_', default=bAtom)],
      [sg.CBox('BOXPLOT', key='_boxp_', default=bBoxP)],
    ]

  sg.ChangeLookAndFeel('LightGreen')
  #-----------------------------------------------define the form layout
  if bBoxP:
    layout_xy_select= [
      sg.Column(colXsel,key='x-coord'),
      sg.Image(key='-IMAGE-')
    ]
  else:
    layout_xy_select= [
      sg.Column(colXsel,key='x-coord'),
      sg.Column(colYsel,key='y-coord'),
      sg.Image(key='-IMAGE-')
    ]
  layout_settings= [
    sg.Column(colX,    key='x-minmax'),
    sg.Column(colY,    key='y-minmax'),
    sg.Column(colBools,key='bools'),
    sg.Column(colSym,  key='symbols'),
    sg.Column(colCol,  key='colors'),
    sg.Column(colSel,  key='select'),
    sg.Column(colLbl,  key='labels'),
    sg.Column(colLeg,  key='position')
  ]
  if START:
    layout_choices= [
       sg.OK('Draw'),
       sg.Button('Save on File'),
       sg.Button('Save on Screen'),
       sg.Button('New file'),
       sg.Button('Exit'),
    ]
  else:
    layout_choices= [
       sg.OK('Draw'),
       sg.Button('Save on File'),
       sg.Button('Save on Screen'),
       # sg.Button('Refresh Input'),
       sg.Button('New file'),
       sg.Button('Exit'),
    ]
  layout= [
    #-[sg.Text("fname", font=('current 12'))],
    layout_choices,
    layout_xy_select,
    layout_settings,
  ]

  #-------------------------create the form and show it without the plot
  titlebar= "GeoxDraw on "+fname
  window= sg.Window(
    titlebar,
    layout,
    location=(0,0), 
    no_titlebar= False, 
    grab_anywhere=False)
  window.Finalize()
  iFig=0
  while True:
    event, values= window.Read()
    if VERBOS: print(event)
    if VERBOS: print(values)
    # show it all again and get buttons
    if event=='New file':
      window.Close()
      new_file= True
      break
    # if event=='Refresh Input':
    #   window.Close()
    #   break
    if event is None or event == 'Exit':
      end=True
      window.Close()
      break
    iy=[]
    LegLoc= 0 # code for position of legend
    iLbl=   -1
    iSel1=  -1
    iSel2=  -1
    breakk= False
    for key, val in list(values.items()):
      # print(key,val,len(val))
      if key==0: 
        if len(val)>0:
          ix=labelNum.index(val[0])
        else:
          sg.popup("No X Coord selected")
          breakk= True
      if key==1:
        # if not bBoxP:
        if len(val)>0:
          for s in val: iy.append(labelNum.index(s))
        else:
          sg.popup("No Y Coord selected")
          breakk= True
      if key==2: 
        if len(val)>0:
          iSel1= labelStr.index(val[0])
      if key==3: 
        if len(val)>0:
          iSel2= labelStr.index(val[0])
      if key==4:
        lisSel= []
        for s in val: lisSel.append(s)
      if key==5: 
        if len(val)>0:
          iLbl= labelStr.index(val[0])
      if key==6: 
        if len(val)>0: LegLoc= lisPosition.index(val[0])
      if key=='_xlog_':  xLog= val
      if key=='_ylog_':  yLog= val
      if key=='_mute_':  bMute= val
      if key=='_colsym_':  bColsym= val
      if key=='_boxp_':  bBoxP= val
      if key=='_xauto_': xAuto= val
      if key=='_yauto_': yAuto= val
      if key=='_xatom_': xAtom= val
      if key=='_yatom_': yAtom= val

    if breakk: continue
    
    xmin= 0. #math.floor(vmin[ix]*100.)/100.
    xmax= 1. #math.ceil(vmax[ix]*100.)/100.
    for key, val in list(values.items()):
      # print(key,val,len(val))
      try: x= float(val)
      except: x= 0.0 #"Not a Real !!"
      if key=='_xmax_':  xmax=x
      if key=='_xmin_':  xmin=x
      if key=='_ymax_':  ymax=x
      if key=='_ymin_':  ymin=x
    # print(("ix=",ix))
    # print(("iy=",iy))
    minmax=xmin,xmax,ymin,ymax
    # print(("minmax=",minmax))
    loglog= xLog,yLog
    auto_minmax= xAuto,yAuto
    
    if bMute: iLbl= -1
    if len(dictStr[iSel1])>MAXSYM: iSel1= -1
    if len(dictStr[iSel2])>MAXCOL: iSel2= -1
    
    # if values[0]==[] or (values[1]==[] and not bBoxP):
    if values[0]==[] or (values[1]==[] and not bBoxP):
      sg.popup("No Coordinates selected")
      continue
      
    plt.clf()
    if bBoxP:
      if iSel1>=0:
        fig= build_boxplot(data_lump,iSel1,iSel2,lisSel,xLog)
      else:
        sg.popup("No Symbols selected")
        continue
    else:
      selec_lump= iSel1,iSel2,lisSel,iLbl,bColsym
      fig= build_figure(data_lump,selec_lump,ix,iy,auto_minmax,minmax,loglog,LegLoc)
  
    fw,fh= 16., 12.
    fig.set_size_inches(fw/2.54,fh/2.54)
    picture_buf= io.BytesIO()
    plt.savefig(picture_buf,format='png')

    new_size= 800,600
    new_size= 640,480
    picture_buf.seek(0)
    byttes=convert_to_bytes(picture_buf.read(), resize=new_size)
    window['-IMAGE-'].update(data=byttes)

    # button = sg.PopupYesNo('Save this Diagram ??')
    # if button == 'Yes':
    if event=='Save on Screen':
      im = PIL.Image.open(picture_buf)
      im.show()     
    if event=='Save on File':
      iFig+=1
      fn= fname+'_'+str(iFig)
      if bBoxP:
        fn= fn +'_boxplot'
      else:
        fn= fn +'_' +labelNum[ix] +'_' +labelNum[iy[0]]
      plt.savefig(fn+'.eps')
      plt.savefig(fn+'.png')
      
  if end: break
