open Html
open Htmlfmt

(* 
HTML Tables are defined by RFC1942, e.g.
  <URL:ftp://ds.internic.net/rfc/rfc1942.txt>

This code *assumes* that minimisation rules are used for
cells (td and th) and for rows.
 *)




module Make (G : GfxHTML)( TableDisplay : TableDisplay) =
struct
open G
open TableDisplay

let init mach =

  (* Tables may be nested, so we need to remember *)
  let table_stack = ref ([] : TableDisplay.t list) in

  (* Access to the stack *)
  let tm () = match !table_stack with
      tm::_ -> tm
    | [] -> raise (Invalid_Html "Table element outside <TABLE></TABLE>")
  and pop_table () = match !table_stack with
      tm::l -> table_stack := l
    | [] -> raise (Invalid_Html "Unmatched </TABLE>")
  and push_table tm = table_stack := tm :: !table_stack
  in

  (* <TABLE> starts a table *)
  let open_table fo t =
    fo.new_paragraph();
    (* Create the widget for embedding this table *)
    let fr = fo.create_embedded "" None None in
    (* And the table manager *)
    let tm = TableDisplay.create fr t in 
    (* push the table on the stack *)
	push_table tm

  and close_table fo = 
    (tm()).close_table(); (* close the table *)
    pop_table();
    fo.close_paragraph () 
     (* NOTE: this is the correct fo only if minimisation were applied
        and the correct current formatter is passed to close table
      *)
  in

  mach#add_tag "table" open_table close_table;
  mach#add_tag "col" (fun fo t -> (tm()).add_col t) (fun _ -> ());

  (* <TR> : starts a row *)
  let open_tr fo t = (tm()).open_row t
  and close_tr fo = ()
  in  
  mach#add_tag "tr" open_tr close_tr;

  (* A new cell *)
  let open_cell kind fo t =
    let rspan = try int_of_string (get_attribute t "rowspan") with _ -> 1
    and cspan = try int_of_string (get_attribute t "colspan") with _ -> 1
    in
    let cell = (tm()).new_cell kind t rspan cspan in
      mach#push_formatter (fo.cell_formatter cell)
  and close_cell fo =
    (* fo is the formatter that was open for *this* cell *)
    fo.flush();
    mach#pop_formatter
  in
  mach#add_tag "th" (open_cell HeaderCell) close_cell;
  mach#add_tag "td" (open_cell DataCell) close_cell

end
