(*********************************************************************************)

(*                Cameleon                                                       *)
(*                                                                               *)
(*    Copyright (C) 2004-2010 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 Library 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 Library General Public License for more details.                       *)
(*                                                                               *)
(*    You should have received a copy of the GNU Library 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                                          *)
(*                                                                               *)
(*********************************************************************************)


(* $Id: cam_main.ml 749 2010-06-17 06:52:00Z zoggy $ *)

let com ?(args=[| |]) name f =
  {
    Cam_commands.com_name = name ;
    Cam_commands.com_args = args ;
    Cam_commands.com_more_args = None ;
    Cam_commands.com_f = f
  }

let ask_quit () =
  match GToolbox.question_box ~title: Cam_messages.quit
      ~buttons: [Cam_messages.yes ; Cam_messages.no]
      Cam_messages.really_quit
  with
    1 -> GMain.Main.quit ()
  | _ -> ()

let about_dialog = ref (fun () -> raise Not_found)
let show_about_dialog () =
  try !about_dialog ()
  with Not_found ->
      let dialog = GWindow.about_dialog
        ~authors:
          [(Printf.sprintf "%s <%s>"
             Cam_messages.software_author
               Cam_messages.software_author_mail)]
          ~name: Cam_installation.software
          ~version: Cam_installation.software_version
          ~website: "http://www.gna.org/projects/cameleon"
          ~website_label: "The Cameleon website"
          ~position: `CENTER
          ~copyright: Cam_messages.software_copyright
          ~modal: true
          ()
      in
      about_dialog := dialog#present ;
      ignore(dialog#connect#response (fun _ -> dialog#misc#hide()));
      dialog#show ()
;;

let default_commands =
  [
    com Cam_constant.com_quit (fun args -> ask_quit ()) ;
    com Cam_constant.com_about_box (fun args -> show_about_dialog ());
  ]

let init_iconize_commands w =
  let coms =
    [
      com Cam_constant.com_iconify (fun (_ : string array) -> w#iconify (); Cam_misc.treat_gtk_events ()) ;
      com Cam_constant.com_deiconify (fun (_ : string array) -> w#deiconify (); Cam_misc.treat_gtk_events ()) ;
    ]
  in
  List.iter Cam_commands.register coms

let main () =
  Cam_args.parse ();
  if Sys.file_exists Cam_server.socket_file && !Cam_args.commands <> [] then
    (
     List.iter Cam_server.send_to_server !Cam_args.commands;
     exit 0
    );

  Cam_rc.load_core ();
  Cam_com_history.init ();
  Cam_rc.load_gui ();
  Cam_doc.init_keymaps ();
  Cam_keymaps.init_common_keymaps ();
  let w = new Cam_gui.main () in
  ignore (w#window#connect#destroy GMain.Main.quit);
  Cam_keymaps.set_window_common_keymaps w#window;
  List.iter Cam_commands.register default_commands ;
  Cam_menus.update_menus ~load_doc: true w#menubar;
  Cam_bbar.update w#hbox_buttons;
  Cam_rc.save_core ();
  Cam_rc.save_gui ();
  Cam_rc.handle_window w#window "main";
  let log_window = Cam_log.get_log_window () in
  Cam_rc.handle_window log_window "log";
  Cam_log.hide_log_window ();

  Cam_commands.register
    { Cam_commands.com_name = Cam_constant.com_configure_doc_sources ;
      Cam_commands.com_args = [| |] ;
      Cam_commands.com_more_args = None ;
      Cam_commands.com_f =
        (fun _ ->
          Cam_doc.config_doc_sources
            ~f_update_menu: (fun () -> Cam_menus.update_doc_menu true)
        );
    } ;

  Cam_commands.register
    { Cam_commands.com_name = Cam_constant.com_display_doc_box ;
      Cam_commands.com_args = [| |] ;
      Cam_commands.com_more_args = None ;
      Cam_commands.com_f =
        (fun _ -> Cam_doc_gui.create_or_update_list_window
            Cam_doc.default_doc_modules) ;
    } ;

  init_iconize_commands w#window;
  List.iter Cam_commands.eval_command (!Cam_args.init_commands @ !Cam_args.commands);
  GMain.Main.main ()

let _ = main ()