;implements a crude lookuptable breed. 
;a turtle of this breed contains a list of row names, a list of column names and a table
;a procedure is provided to initialise a turtle with a filename where it can read a table from
;a procedure is provided to read the table into the turtle (extracting the lists of rownames and columnnames)
;a procedure is provided to report the cell content as string based on row and column names (as strings)
;
; #### this implementation does not check for the correctness of the table 
;  ####in case of repeated row or columnames, only the first can be found, no warnings given
;  ####this does not hanlde missing values in the table
;
; ### the table is stored as a list of lists (each row is a list, for simplicity in reading the file)
; ### the current implenetation sees the rownames as part of the lookuptable, the columnames are not
;  
; ### the input file should be a comma-seperated fulle matrix
; e.g. 
; names,eyes,hair,shirt
; pete,blue,brown,black
; dan,brown,blond,white
; 
; in this example the reporter would need the inputs  "shirt" and "pete" to report "black"
; 
; If it does not work, blame me Geerten.Hengeveld@wur.nl


breed [t_lookuptables t_lookuptable]
t_lookuptables-own [lutt_table  lutt_collist lutt_rowlist]

to-report luto_rp_setuplookuptable [filename] ; observer procedure from the lookuptable 
  let whostore 0
  create-t_lookuptables 1 [
                             lutt_p_readtable filename 
                             set hidden? true ; this also makes it difficult to visually inspect the lookuptable
                             set whostore who
                           ]
  report whostore ; use this to be able to extract information from this lookuptable!
end

to-report luto_rp_ShowFromLookuptable [whostore colname rowname] ; observer procedure from the lookuptable 
  report [lutt_rp_lookup colname rowname] of t_lookuptable whostore 
end

to-report luto_rp_ShowValueFromLookuptable [whostore colname rowname] ; observer procedure from the lookuptable 
  let tablestring [lutt_rp_lookup colname rowname] of t_lookuptable whostore 
  ifelse (tablestring != false)
  [  report read-from-string [lutt_rp_lookup colname rowname] of t_lookuptable whostore ]
  [report false]
end


to-report luto_rp_ColumnsInLookuptable [whostore]
 report [lutt_collist] of t_lookuptable whostore
end

to-report luto_rp_RowsInLookuptable [whostore]
 report [lutt_rowlist] of t_lookuptable whostore
end

to-report luto_rp_ShowColumnFromLookuptable [whostore columnname]
  report [lutt_rp_column columnname] of t_lookuptable whostore
end

to-report luto_rp_ShowColumnValuesFromLookuptable [whostore columnname]
  report [lutt_rp_columnvalues columnname] of t_lookuptable whostore
end



;--------------lookup table internals-------------
to lutt_p_readtable [filename]                               ; turtle procedure from the lookuptable
  ;should actually be a reporter procedure reporting true if initalisation worked...
  
  let temp_list (list 0) ; initialise the lists use but-first lateron to remove the 0
  set lutt_collist (list 0)
  set lutt_rowlist (list 0)
  set lutt_table (list 0)
  
  file-open filename ;should be a csv - no check currently on whether the file opens correctly!
    let p file-read-line ;the header line, should be put into the list lutt_collist
    while [position "," p != false]
    [
       set lutt_collist lput (substring p 0 (position "," p)) lutt_collist 
       set p substring p (position "," p + 1) length p
    ]
    set lutt_collist lput p lutt_collist ;add the last element
    set lutt_collist but-first lutt_collist ;remove the initial 0
  
  ;initialise the table: each row will be a list in the table
  while [not file-at-end?]
     [
       set p file-read-line
       set temp_list (list 0)

        while [position "," p != false]
       [
       set temp_list lput ( substring p 0 (position "," p)) temp_list 
       set p substring p (position "," p + 1) length p
       ;store elements in the right order!
       ]
       set temp_list lput p temp_list
       set temp_list but-first temp_list ;remove 0 from start
       set lutt_table lput temp_list lutt_table 
     ]
     set lutt_table but-first lutt_table

     foreach lutt_table  ; initialise a list of all rownames: the first items of the rows in the table
     [
       set lutt_rowlist lput item 0 ? lutt_rowlist  
     ]
     set lutt_rowlist but-first lutt_rowlist
     file-close
end


;this reporter will report a string! use read-from-string to interpret output as value
to-report lutt_rp_lookup [colname rowname]                   ; turtle procedure from the lookuptable
  let colnr position colname lutt_collist
  let rownr position rowname lutt_rowlist
  
  ifelse (colnr != false and rownr != false)
  [
  
    let targetrow item rownr lutt_table
    report item colnr targetrow 
  ]
  [
    report false
  ]
end

;report a whole column
to-report lutt_rp_column [colname]                   ; turtle procedure from the lookuptable
  let colnr position colname lutt_collist
  
  let templist (list 0)
  let targetrow 0
  
  ifelse (colnr != false)
  [
    let i 0
    repeat length lutt_rowlist
    [
       set targetrow item i lutt_table
       set templist lput item colnr targetrow templist
       set i i + 1
    ]
    
    set templist but-first templist
    report templist
  ]
  [
    report false
  ]
end


to-report lutt_rp_columnvalues [colname]                   ; turtle procedure from the lookuptable
  let colnr position colname lutt_collist
  
  let templist (list 0)
  let targetrow 0
  
  ifelse (colnr != false)
  [
    let i 0
    repeat length lutt_rowlist
    [
       set targetrow item i lutt_table
       set templist lput read-from-string item colnr targetrow templist
       set i i + 1
    ]
    
    set templist but-first templist
    report templist
  ]
  [
    report false
  ]
end
