(**************************************************************************)
(*                   Cameleon                                             *)
(*                                                                        *)
(*      Copyright (C) 2002 Institut National de Recherche en Informatique et   *)
(*      en Automatique. All rights reserved.                              *)
(*                                                                        *)
(*      This program is free software; you can redistribute it and/or modify  *)
(*      it under the terms of the GNU General Public License as published by  *)
(*      the Free Software Foundation; either version 2 of the License, or  *)
(*      any later version.                                                *)
(*                                                                        *)
(*      This program is distributed in the hope that it will be useful,   *)
(*      but WITHOUT ANY WARRANTY; without even the implied warranty of    *)
(*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     *)
(*      GNU General Public License for more details.                      *)
(*                                                                        *)
(*      You should have received a copy of the GNU General Public License  *)
(*      along with this program; if not, write to the Free Software       *)
(*      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA          *)
(*      02111-1307  USA                                                   *)
(*                                                                        *)
(*      Contact: Maxence.Guesdon@inria.fr                                *)
(**************************************************************************)

(** The class type of embedded applications. *)
class type embedded_app =
  object
    (** The box, to pack it in something. *)
    method box : GPack.box

    (** The method to call to close the app.*)
    method close : unit

    (** To perform some initializations with a window. *)
    method init_window : GWindow.window -> unit
  end

let embedded_apps = ref ([] : (string * (GWindow.window * embedded_app)) list)

let remove_app name =
  let (rem_apps, apps) = List.partition
      (fun (n,_) -> n = name) !embedded_apps
  in
  embedded_apps := apps;
  match rem_apps with
  | [] -> ()
  | (_, (w,app)) :: _ ->
      app#close ;
      w#destroy ()

let create name (f_app : unit -> embedded_app) () =
  try
    let (w, app) = List.assoc name !embedded_apps in
    w#misc#hide () ;
    w#show ()
  with
    Not_found ->
      let w = GWindow.window ~title: name () in
      let app = f_app () in
      ignore(w#event#connect#delete (fun _ -> remove_app name; false));
      ignore(app#box#connect#destroy (fun () -> remove_app name));
      embedded_apps := (name, (w, app)) :: !embedded_apps ;
      w#add app#box#coerce;
      app#init_window w;
      w#show ()
