# =============================================================================
"""CSV : display a csv file content in a tclTk window, allow modifications and
         saving"""
# ==============================================================================
__author__  = "Philippe Blasi"
__version__ = "1.0"
__date__    = "2023-05-02"
# ==============================================================================
from ezTK import *
from ezCLI import *
# ------------------------------------------------------------------------------
def main():
  """create the main window and pack the widgets"""
  global win
  win = Win(title='CSV FILE', grow=False, click=on_click)
  win.row, win.col = 0,0
  frame=Frame(win,fold=2)
  Button(frame, text='OPEN FILE', width=12, command=on_open)
  Button(frame, text='SAVE FILE', width=12, command=on_save)
  win.label = Label(frame, text=f"Cell({win.row},{win.col})",width=10)
  win.entry = Entry(frame,width=10, command=on_entry)
  # ----------------------------------------------------------------------------
  Frame(win) # create an empty frame to store the size and name of the file
  Frame(win) # create an empty frame to store the grid
  # ----------------------------------------------------------------------------
  win.matrix = None
  win.grid = None
  win.loop()
# ------------------------------------------------------------------------------
def on_open() -> None:
  """callback for the "OPEN FILE" button"""
  name = Dialog('open',title='OPEN FILE')
  grid_tcl(name)
# ------------------------------------------------------------------------------
def on_save() -> None:
  """callback for the "SAVE FILE" button"""
  name = Dialog('save',title='SAVE FILE')

  if win.matrix != None:
    for row in range(win.rows):   # loop over grid cells and copy each
      for col in range(win.cols): # value into the matrix cell in row and col
        win.matrix[row][col] = parse(win.grid[row][col]['text'])
        
  write_csv(name,win.matrix)
# ------------------------------------------------------------------------------
def on_click(widget:object, code:str, mods:str) -> None:
  """callback function for all mouse click events"""
  if widget.master != win.grid or win.matrix == None: return # wrong click (= not on a board cell)
  win.row, win.col = widget.index
  win.label['text'] = f"Cell({win.row},{win.col})"
  win.entry.state = win.grid[win.row][win.col]['text']
# ------------------------------------------------------------------------------
def on_entry() -> None:
  """callback function for the cell entry"""
  if win.grid[win.row][win.col]['text'] != win.entry.state:
    win.grid[win.row][win.col]['fg'] = '#FFF'
    win.grid[win.row][win.col]['bg'] = '#F00'
    win.grid[win.row][win.col]['text'] = win.entry.state
# ------------------------------------------------------------------------------
def grid_tcl(name:str) -> None:
  """create the grid within the main window and pack the widgets"""
  matrix = read_csv(name) # read content of data file name
  rows, cols = len(matrix), len(matrix[0]) # get matrix size from data file
  widths = [len(str(matrix[row][col])) for col in range(cols) for row in range(rows)]
  width = max(widths)+2 # get the maximum width for the cells of matrix
  # ----------------------------------------------------------------------------
  del win[2] # delete the frame containing the current grid
  del win[1] # delete the frame storing the size and name of the file
  # ----------------------------------------------------------------------------
  frame = Frame(win,op=3) # create a new frame to store the size and name
  short_name=name.split('/')[-1] # create the local name without the full path
  Label(frame, text=f'File name : {short_name}', grow=False)
  Label(frame, text=f'Number of rows : {rows}', grow=False)
  Label(frame, text=f'Number of cols : {cols}', grow=False)
  # ----------------------------------------------------------------------------
  grid = Frame(win, fold=cols) # create a new frame to store the new grid
  # ----------------------------------------------------------------------------
  for row in range(rows):   # loop over matrix cells and create a Label for each
    for col in range(cols): # value of the matrix cell in row and col
      Label(grid,text=matrix[row][col],border=1,width=width)
  # ----------------------------------------------------------------------------
  # save in win for later use
  win.matrix = matrix; win.rows=rows; win.cols=cols; win.grid=grid
# ==============================================================================
if __name__ == '__main__':
  main()
# ==============================================================================
