/*
This source file is part of Scol
For the latest info, see http://www.scolring.org

Copyright (c) 2010 Stephane Bisaro, aka Iri <iri@irizone.net>

This program 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 of the License, or (at your option) 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser 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, or go to
http://www.gnu.org/copyleft/lesser.txt

For others informations, please contact us from http://www.scolring.org/
*/






#include "../include/scol_gtk_window.h"


int scol_gtk_window_cb_destroy (GtkWidget *p_widget, gpointer user_data)
{
    int cb;
    mmachine m;

    g_message ("scol_gtk_window_cb_destroy : entering ...");

    m = (mmachine) user_data;

    /*OBJdelTM (m, ObjGtkWidgetType, MTOP (MMget (m, 0)));*/

    cb = OBJbeginreflex (m, ObjGtkWidgetType, (int) p_widget, OBJ2DGTK_WINDOW_CB_DESTROYED);
    if (cb)
    {
        g_message ("scol_gtk_window_cb_destroy error : no callback defined ! errcode = %d", cb);
        return FALSE;
    }

    if (OBJcallreflex (m, 0)) return TRUE;
    return FALSE;
}



gboolean scol_gtk_window_cb_delete_event (GtkWidget *win, GdkEvent *event, int u)
{
    if (u)
        gtk_widget_hide_on_delete (win);
    return FALSE;
}

void scol_gtk_window_new (GtkWidget **win, GtkWidget *parent,
                          gchar *title,
                          gint posx, gint posy, gint width, gint height,
                          GtkMessageType typ, GtkButtonsType btn,
                          int flag)
{
    switch (flag)
    {
        case (0) :
            *win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
            break;


        case (1) :
            *win = gtk_message_dialog_new (GTK_WINDOW (parent), GTK_DIALOG_DESTROY_WITH_PARENT, typ, btn, title);
            break;

        default :
            win = NULL;
    }
    gtk_window_set_title (GTK_WINDOW (*win), title);
    gtk_window_move (GTK_WINDOW (*win), posx, posy);
    gtk_window_set_default_size (GTK_WINDOW (*win), width, height);
    return;
}



/**
 * \brief Create a window : fun [Chn ObjGtkWidget S [I I] [I I]] ObjGtkWidget
 *
 */
int SCOL_gtkWindowNew (mmachine m)
{
    int mchannel, mparent, mtitle, mpos, msize;
    int k;
    gint mx, my, mw, mh;
    gchar *title;
    GtkWidget  *win, *parent;

    g_message ("SCOL_gtkWindowNew : entering");

    msize = MMpull (m)>>1;
    mpos = MMpull (m)>>1;
    mtitle = MTOP (MMpull (m));
    mparent = MTOP (MMpull (m));
    mchannel = MMget (m, 0);

    if (mchannel == NIL)
    {
        g_warning ("SCOL_gtkWindowNew error : channel is nil");
        MMpull (m);
        MMpush (m, NIL);
        return 0;
    }

    if (mtitle == NIL)
    {
        title = (gchar *) g_malloc (sizeof (gchar) * (strlen (DEFAULT_TITLE) + 1));
        if (title == NULL)
            g_error ("SCOL_gtkWindowNew : not enough memory");
        strcpy (title, (gchar *) DEFAULT_TITLE);
    }
    else
    {
        title = (gchar *) g_malloc (sizeof (gchar) * (MMsizestr (m, mtitle) + 1));
        if (title == NULL)
            g_error ("SCOL_gtkWindowNew : not enough memory");
        strcpy (title, (gchar *) MMstartstr (m, mtitle));
    }

    if (mpos == NIL)
        mx = my = 0;
    else
    {
        mx = (gint) MMfetch (m, mpos, 0)>>1;
        my = (gint) MMfetch (m, mpos, 1)>>1;
    }

    if (msize == NIL)
        mw = mh = 300;
    else
    {
        mw = (gint) MMfetch (m, msize, 0)>>1;
        mh = (gint) MMfetch (m, msize, 1)>>1;
    }

    if (mparent == NIL)
        parent = NULL;
    else
        parent = (GtkWidget *) MMfetch (m, mparent, OBJ2DGTK_WIDGET_HANDLE);

    scol_gtk_window_new (&win, parent, title, mx, my, mw, mh, 0, 0, 0);
    g_free (title);
    k = SCOL_gtk_memory_createObjectTAB (m, win, ObjGtkWidgetType, OBJ2DGTK_WIDGET_HANDLE);
    /*g_signal_connect (G_OBJECT(win->widget), "destroy", G_CALLBACK (scol_gtk_window_cb_destroy), GINT_TO_POINTER (m));*/
    return k;
}


int SCOL_gtkWindowAddChild (mmachine m)
{
    int mwin, mchild;
    GtkWidget *win, *child;

    g_message ("SCOL_gtkWindowAddChild : entering");

    mchild = MTOP (MMpull (m));
    mwin = MTOP (MMpull (m));

    if ((mwin == NIL) || (mchild == NIL))
    {
        g_warning ("SCOL_gtkWindowAddChild error : object is nil");
        MMpush (m, NIL);
        return 0;
    }

    win = (GtkWidget*) MMfetch (m, mwin, OBJ2DGTK_WIDGET_HANDLE);
    child = (GtkWidget*) MMfetch (m, mchild, OBJ2DGTK_WIDGET_HANDLE);
    gtk_container_add (GTK_CONTAINER (win), child);

    MMpush (m, PTOM (mwin));
    return 0;
}

/**
 * \brief This function is a convenience. You can call '_gtkWidgetCB' with falg destroy
 *
 * Prototype : fun [ObjGtkWidget fun [ObjGtkWidget u0] u1 u0] ObjGtkWidget
 */
int SCOL_gtkWindowCBdestroyed (mmachine m)
{
    int mwin;
    GtkWidget *win;

    g_message ("SCOL_gtkWindowCBdestroyed : entering");

    mwin = MTOP (MMget (m, 2));
    if (mwin == NIL)
    {
        g_warning ("SCOL_gtkWindowCBdestroyed error : object is nil\n");
        MMpush (m, NIL);
        return -1;
    }

    OBJaddreflex (m, ObjGtkWidgetType, OBJ2DGTK_WINDOW_CB_DESTROYED);
    win = (GtkWidget*) MMfetch (m, mwin, OBJ2DGTK_WIDGET_HANDLE);
    g_signal_connect (G_OBJECT (win), "destroy", G_CALLBACK (scol_gtk_window_cb_destroy), (gpointer) m);

    return 0;
}

/**
 * \brief Define if the delete-event (e.g. a user press the close button) destroys the window or hide the window
 *
 * If the window is hidden, it can be shown later without rebuild it.
 *Prototype : fun [ObjGtkWidget I] ObjGtkWidget
 */
int SCOL_gtkWindowDeleteEvent (mmachine m)
{
    int mwin, mflag;
    GtkWidget *win;

    g_message ("SCOL_gtkWindowDeleteEvent : entering");

    mflag = MTOI (MMpull (m));
    mwin = MTOP (MMget (m, 0));

    if (mwin == NIL)
    {
        g_warning ("SCOL_gtkWindowDeleteEvent error : window is nil\n");
        MMpush (m, NIL);
        return -1;
    }
    if (mflag != 1)
        mflag = 0;
    win = (GtkWidget*) MMfetch (m, mwin, OBJ2DGTK_WIDGET_HANDLE);
    g_signal_connect (G_OBJECT (win), "delete-event", G_CALLBACK (scol_gtk_window_cb_delete_event), (gpointer) mflag);
    return 0;
}




/* API définitions : */

char* gtk_win_name[GTK_WIN_PKG_NB]=
{
    "_gtkWindowNew",
    "_gtkWindowAddChild",
    "_gtkWindowCBdestroyed",
    "_gtkWindowDeleteEvent"
};

int (*gtk_win_fun[GTK_WIN_PKG_NB])(mmachine m)=
{
    SCOL_gtkWindowNew,
    SCOL_gtkWindowAddChild,
    SCOL_gtkWindowCBdestroyed,
    SCOL_gtkWindowDeleteEvent
};

int gtk_win_narg[GTK_WIN_PKG_NB]=
{
    5,
    2,
    3,
    2
};

char* gtk_win_type[GTK_WIN_PKG_NB]=
{
    "fun [Chn ObjGtkWidget S [I I] [I I]] ObjGtkWidget",
    "fun [ObjGtkWidget ObjGtkWidget] ObjGtkWidget",
    "fun [ObjGtkWidget fun [ObjGtkWidget u0] u1 u0] ObjGtkWidget",
    "fun [ObjGtkWidget I] ObjGtkWidget"
};

int SCOLloadGTKwindow (mmachine m)
{
    int k;

    MMechostr (0, "SCOLloadGTKwindow : entering\n");

    k = PKhardpak (m, "GTK2DwindowEngine", GTK_WIN_PKG_NB, gtk_win_name, gtk_win_fun, gtk_win_narg, gtk_win_type);
    return k;
}




