/*
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_notebook.h"


/**
 * \brief Create a new notebook
 * fun [Chn] ObjGtkWidget
 */
int SCOL_gtkNotebookNew (mmachine m)
{
    int mchannel;
    GtkWidget *widget;

    g_message ("SCOL_gtkNotebookNew : entering");

    mchannel = MMget (m, 0);
    if (mchannel == NIL)
    {
        g_warning ("SCOL_gtkNotebookNew error : channel is nil");
        MMpull (m);
        MMpush (m, NIL);
        return 0;
    }

    widget = gtk_notebook_new ();
    gtk_notebook_set_scrollable (GTK_NOTEBOOK (widget), TRUE);
    return SCOL_gtk_memory_createObjectTAB (m, widget, ObjGtkWidgetType, OBJ2DGTK_WIDGET_HANDLE);
}

/**
 * \brief Add / insert a tab in a notebook
 *
 * fun [ObjGtkWidget ObjGtkWidget S I] [ObjGtkWidget ObjGtkWidget ObjGtkWidget I]
 *
 * Args :
 * 3 : I : a position where the tab will be inserted (can be negative or positive, if nil, it will be added to the end)
 * 2 : S : the title of the new tab
 * 1 : ObjGtkWidget : a widget included to the new tab. If nil, a text (GtkTextView) will be included
 * 0 : ObjGtkWidget : a notebook already created
 *
 * Returns :
 * 0 : ObjGtkWidget : the same notebook
 * 1 : ObjGtkWidget : the label (the title of the tab)
 * 2 : ObjGtkWidget : the same child
 * 3 : the index of the inserted tab
 */
int SCOL_gtkNotebookAddPage (mmachine m)
{
    int mnotebook, mchild, mtitle, mpos;
    int pos = 0, id;
    GtkWidget *notebook, *label, *child;
    gchar *title;

    g_message ("SCOL_gtkNotebookAddPage : entering");

    mpos = MTOI (MMpull (m));
    mtitle = MMpull (m);
    mchild = MTOP (MMpull (m));
    mnotebook = MMpull (m);

    if (mnotebook == NIL)
    {
        g_warning ("SCOL_gtkNotebookAddPage error : notebook is nil");
        MMpush (m, NIL);
        return 0;
    }

    notebook = (GtkWidget*) MMfetch (m, MTOP (mnotebook), OBJ2DGTK_WIDGET_HANDLE);

    if (mtitle == NIL)
        title = DEFAULT_STRING;
    else
        title = g_strconcat (SCOLUTF8 (MMstartstr (m, MTOP (mtitle))), NULL);
    label = gtk_label_new (title);
    gtk_label_set_selectable (GTK_LABEL (label), TRUE);
    g_free (title);

    if (mchild == NIL)
        child = gtk_text_view_new ();
    else
        child = (GtkWidget *) MMfetch (m, mchild, OBJ2DGTK_WIDGET_HANDLE);

    if (mpos == NIL)
        id = gtk_notebook_append_page (GTK_NOTEBOOK (notebook), child, label);
    else if (mpos < 0)
    {
        pos = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) + mpos;
        if (pos < 0)
            pos = 0;
        id = gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), child, label, pos);
    }
    else
    {
        if (mpos > gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)))
            pos = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook));
        id = gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), child, label, pos);
    }

    MMpush (m, mnotebook);
    MMpush (m, MMgetglobal (m, OFFSCCUR));  /* get the current channel */
    SCOL_gtk_memory_createObjectTAB (m, label, ObjGtkWidgetType, OBJ2DGTK_WIDGET_HANDLE);
    MMpush (m, MMgetglobal (m, OFFSCCUR));  /* get the current channel */
    SCOL_gtk_memory_createObjectTAB (m, child, ObjGtkWidgetType, OBJ2DGTK_WIDGET_HANDLE);
    MMpush (m, ITOM (id));
    MMpush (m, ITOM (4));
    MBdeftab (m);
    gtk_widget_show_all (notebook);

    return 0;
}

/**
 * \brief Remove a tab from a notebook
 */
int SCOL_gtkNotebookRemPage (mmachine m)
{
    int mnotebook, mid;
    GtkWidget *notebook;

    g_message ("SCOL_gtkNotebookRemPage : entering");

    mid = MTOI (MMpull (m));
    mnotebook = MTOP (MMpull (m));

    if (mnotebook == NIL)
    {
        g_warning ("SCOL_gtkNotebookRemPage error : notebook is nil");
        MMpush (m, NIL);
        return 0;
    }

    notebook = (GtkWidget*) MMfetch (m, mnotebook, OBJ2DGTK_WIDGET_HANDLE);

    if (mid < -1)
    {
        mid = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) + mid;
        if (mid < 0)
            mid = 0;
    }
    gtk_notebook_remove_page (GTK_NOTEBOOK (notebook), mid);

    MMpush (m, PTOM (mnotebook));
    return 0;
}

/**
 * \brief Returns the index of a tab from the child widget
 */
int SCOL_gtkNotebookIndex (mmachine m)
{
    int mnotebook, mchild;

    g_message ("SCOL_gtkNotebookIndex : entering");

    mchild = MTOP (MMpull (m));
    mnotebook = MTOP (MMpull (m));
    if ((mnotebook == NIL) || (mchild == NIL))
    {
        g_warning ("SCOL_gtkNotebookIndex error : an object is nil");
        MMpush (m, NIL);
        return 0;
    }

    MMpush (m, ITOM (gtk_notebook_page_num (GTK_NOTEBOOK ((GtkWidget*) MMfetch (m, mnotebook, OBJ2DGTK_WIDGET_HANDLE)), (GtkWidget*) MMfetch (m, mchild, OBJ2DGTK_WIDGET_HANDLE))));
    return 0;
}

/**
 * \brief Return the index of the current tab
 */
int SCOL_gtkNotebookCurrent (mmachine m)
{
    int mnotebook;
    GtkWidget *notebook;

    g_message ("SCOL_gtkNotebookCurrent : entering");

    mnotebook = MTOP (MMpull (m));
    if (mnotebook == NIL)
    {
        g_warning ("SCOL_gtkNotebookCurrent error : object is nil");
        MMpush (m, NIL);
        return 0;
    }

    notebook = (GtkWidget*) MMfetch (m, mnotebook, OBJ2DGTK_WIDGET_HANDLE);
    MMpush (m, ITOM (gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook))));
    return 0;
}

/**
 * \brief Returns the child from the index
 *
 * If child is a GTK+ object but not a Sccol object, the Scol object is created
 */
int SCOL_gtkNotebookChild (mmachine m)
{
    int mnotebook, mindex;
    int exist;
    GtkWidget *notebook, *child;
    gint index;

    g_message ("SCOL_gtkNotebookChild : entering");

    mindex = MTOI (MMpull (m));
    mnotebook = MTOP (MMpull (m));
    if (mnotebook == NIL)
    {
        g_warning ("SCOL_gtkNotebookChild error : object is nil");
        MMpush (m, NIL);
        return 0;
    }

    notebook = (GtkWidget*) MMfetch (m, mnotebook, OBJ2DGTK_WIDGET_HANDLE);

    if (mindex < 0)
        index = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) + mindex - 1;
    else
        index = mindex;

    child = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), index);
    if (child == NULL)
    {
        MMpush (m, NIL);
        return 0;
    }

    exist = OBJfindTH (m, ObjGtkWidgetType, (int) child);
    if (exist == -1)
    {
        MMpush (m, MMgetglobal (m, OFFSCCUR));  /*  set the current channel */
        return SCOL_gtk_memory_createObjectTAB (m, child, ObjGtkWidgetType, OBJ2DGTK_WIDGET_HANDLE);
    }
    MMpush (m, MMfetch (m, exist, OFFOBJMAG));
    return 0;
}

/**
 * \brief Returns the number of tabs in a notebook
 */
int SCOL_gtkNotebookCount (mmachine m)
{
    int mnotebook;

    g_message ("SCOL_gtkNotebookCount : entering");

    mnotebook = MTOP (MMpull (m));
    if (mnotebook == NIL)
    {
        g_warning ("SCOL_gtkNotebookCount error : object is nil");
        MMpush (m, NIL);
        return 0;
    }

    MMpush (m, ITOM (gtk_notebook_get_n_pages (GTK_NOTEBOOK ((GtkWidget*) MMfetch (m, mnotebook, OBJ2DGTK_WIDGET_HANDLE)))));
    return 0;
}

/**
 * \brief Returns the label (title)
 * If the Scol object doesn't exist, it created
 */
int SCOL_gtkNotebookLabelGet (mmachine m)
{
    int mnotebook, mindex;
    int exist;
    GtkWidget *notebook, *child, *label;
    gint index;

    g_message ("SCOL_gtkNotebookLabelGet : entering");

    mindex = MTOI (MMpull (m));
    mnotebook = MTOP (MMpull (m));
    if (mnotebook == NIL)
    {
        g_warning ("SCOL_gtkNotebookLabelGet error : object is nil");
        MMpush (m, NIL);
        return 0;
    }

    notebook = (GtkWidget*) MMfetch (m, mnotebook, OBJ2DGTK_WIDGET_HANDLE);

    if (mindex < 0)
        index = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) + mindex;
    else
        index = mindex;

    child = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), index);
    if (child == NULL)
    {
        MMpush (m, NIL);
        return 0;
    }

    label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (notebook), child);
    exist = OBJfindTH (m, ObjGtkWidgetType, (int) label);
    if (exist == -1)
    {
        MMpush (m, MMgetglobal (m, OFFSCCUR));  /*  set the current channel */
        return SCOL_gtk_memory_createObjectTAB (m, label, ObjGtkWidgetType, OBJ2DGTK_WIDGET_HANDLE);
    }
    MMpush (m, MMfetch (m, exist, OFFOBJMAG));
    return 0;
}

int SCOL_gtkNotebookGoto (mmachine m)
{
    int mnotebook, mid;
    GtkWidget* notebook;

    g_message ("SCOL_gtkNotebookGoto : entering");

    mid = MTOI (MMpull (m));
    mnotebook = MMpull (m);
    if (mnotebook == NIL)
    {
        g_warning ("SCOL_gtkNotebookGoto error : notebook is nil");
        MMpush (m, NIL);
        return 0;
    }

    notebook = (GtkWidget*) MMfetch (m, MTOP (mnotebook), OBJ2DGTK_WIDGET_HANDLE);
    gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), mid);
    MMpush (m, mnotebook);
    return 0;
}






/* API définitions : */

char* gtk_nb_name[GTK_NOTEBOOK_PKG_NB]=
{
    "_gtkNotebookNew",
    "_gtkNotebookAddPage",
    "_gtkNotebookRemPage",
    "_gtkNotebookIndex",
    "_gtkNotebookCurrent",
    "_gtkNotebookChild",
    "_gtkNotebookCount",
    "_gtkNotebookLabelGet",
    "_gtkNotebookGoto"
};

int (*gtk_nb_fun[GTK_NOTEBOOK_PKG_NB])(mmachine m)=
{
    SCOL_gtkNotebookNew,
    SCOL_gtkNotebookAddPage,
    SCOL_gtkNotebookRemPage,
    SCOL_gtkNotebookIndex,
    SCOL_gtkNotebookCurrent,
    SCOL_gtkNotebookChild,
    SCOL_gtkNotebookCount,
    SCOL_gtkNotebookLabelGet,
    SCOL_gtkNotebookGoto
};

int gtk_nb_narg[GTK_NOTEBOOK_PKG_NB]=
{
    1,
    4,
    2,
    2,
    1,
    2,
    1,
    2,
    2
};

char* gtk_nb_type[GTK_NOTEBOOK_PKG_NB]=
{
    "fun [Chn] ObjGtkWidget",
    "fun [ObjGtkWidget ObjGtkWidget S I] [ObjGtkWidget ObjGtkWidget ObjGtkWidget I]",
    "fun [ObjGtkWidget I] ObjGtkWidget",
    "fun [ObjGtkWidget ObjGtkWidget] I",
    "fun [ObjGtkWidget] I",
    "fun [ObjGtkWidget I] ObjGtkWidget",
    "fun [ObjGtkWidget] I",
    "fun [ObjGtkWidget I] ObjGtkWidget",
    "fun [ObjGtkWidget I] ObjGtkWidget"
};

int SCOLloadGTKnotebook (mmachine m)
{
    int k;

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

    k = PKhardpak (m, "GTK2DnotebookEngine", GTK_NOTEBOOK_PKG_NB, gtk_nb_name, gtk_nb_fun, gtk_nb_narg, gtk_nb_type);
    return k;
}

