/*
    piinit.c - 22.04.2007
    pilib v0.4 - Platform Independent Library
    Copyright (c) Martin Hierholzer 2003-2007

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2.1 of the License, or (at
    your option) any later version.

    This library 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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
    USA.

    Name:     piinit
    Category: General
    Synopsis: Initialize library; call before any other routines of
              this library

    During initialisation, the following rc-files will be interpreted:
      /usr/share/<name of executable>/gtkrc                 (on UNIX)
      <directory of executable>/.<name of executable>rc     (on WIN32)
      <user home directory>/.<name of executable>rc         (always)

    The user can modify with these files the appearance of named
    widgets (see gkname).

    interface
      subroutine piinit
      end subroutine piinit
    end interface

    Meaning of arguments:
     - no arguments present -

    Note:
      >>> THIS ROUTINE CONTAINS PLATFORM DEPENDENT CODE <<<

    TODO:
      - Retrival of command line arguments is currently specific
        to Linux and Windows. Is there any POSIX compatible method?

    See also: @ref{gkname}
*/
#include <gtk/gtk.h>
#include <string.h>
#include <stdlib.h>

#define ISPIINIT
#include "pidef.h"

int  isinitialized    = 0;
int  isGUIinitialized = 0;
int  *argc = NULL;
char ***argv;

/*
   Include platform dependent headers here!
   ========================================
*/
#ifdef G_OS_WIN32
  #include <windows.h>
#endif
#ifdef G_OS_UNIX
  extern char   **environ;
#endif

void GKEXPORT piinit() {
    char    *rcfile;
    #ifdef G_OS_WIN32
      GError    *err = NULL;
      char      *c, *cmdline, *exedir;
    #endif
    #ifdef G_OS_UNIX
      int       i;
    #endif
/*
    This routine should be called only once
*/
    if(isinitialized) return;
/*
    Get command line arguments (this is platform dependent!)
    ========================================================
*/
    argc = NULL;
    argv = NULL;
/*
    Windows dependent code
    ----------------------
*/
    #ifdef G_OS_WIN32
      argc = g_malloc(4);
      argv = g_malloc(4);
      cmdline = GetCommandLine();
/*
      Convert windows style file pathes and options to unix style
*/
      c = strstr(cmdline,"/");
      while(c) {
        c[0] = '-';
        c = strstr(c,"/");
      }
      c = strstr(cmdline,"\\");
      while(c) {
        c[0] = '/';
        c = strstr(c,"\\");
      }
/*
      Convert command line to argc+argv and extract directory of executable
*/
      g_shell_parse_argv(cmdline,argc,argv,&err);
      exedir = g_path_get_dirname((*argv)[0]);
/*
      Free allocated memory
*/
      g_free(&err);
      g_free(cmdline);
    #endif
/*
    Linux dependent code
    --------------------
*/
    #ifdef G_OS_UNIX
      GIOChannel    *ihfile;
      GError        *err = NULL;
      gsize         nbr;
      char          *data;
/*
      Open /proc/self/cmdline for reading
*/
      ihfile = g_io_channel_new_file("/proc/self/cmdline", "r", &err);
      if(err == NULL) {
        argc = g_malloc(4);
        argv = g_malloc(4);
/*
        Read command line from /proc-filesystem
*/
        g_io_channel_read_to_end(ihfile,&data,&nbr, &err);
/*
        Convert command line to argc+argv and extract directory of executable
*/
        if(err == NULL) {
          for(int i=0; i<nbr-1; i++) if( data[i] == 0 ) data[i] = ' ';
          g_shell_parse_argv(data,argc,argv,&err);
        }
        g_free(data);
/*
        Free allocated memory
*/
        g_io_channel_shutdown(ihfile,FALSE,&err);
        g_io_channel_unref(ihfile);
      }
    #endif
/*
    Initialize GTK/glib
    ===================
*/
    #ifdef G_OS_UNIX
      char *display = getenv("DISPLAY");
      if(display != NULL) {
        gtk_init(argc,argv);
        isGUIinitialized = 1;
      }
      else {
        g_type_init();
      }
    #else
      gtk_init(argc,argv);
      isGUIinitialized = 1;
    #endif
/*
    Parse RC file
*/
    #ifdef G_OS_WIN32
      rcfile = g_strconcat(exedir,"/",g_get_prgname(),".rc",NULL);
      gtk_rc_parse(rcfile);
      g_free(rcfile);
      g_free(exedir);
    #endif
    #ifdef G_OS_UNIX
      rcfile = g_strconcat("/usr/share/",g_get_prgname(),"/gtkrc",NULL);
      gtk_rc_parse(rcfile);
      g_free(rcfile);
    #endif
    rcfile = g_strconcat(g_get_home_dir(),"/.",g_get_prgname(),"rc",NULL);
    gtk_rc_parse(rcfile);
    g_free(rcfile);
/*
    Remember, that we are initialized
*/
    isinitialized = 1;
    #ifdef DEBUG
      g_print(">>> pilib initialized\n");
    #endif
}

