/* SPDX-FileCopyrightText: 2014 - Sébastien Wilmet
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

#pragma once

#include <gtk/gtk.h>
#include "gtex-types.h"

G_BEGIN_DECLS

#define GTEX_TYPE_BUILD_VIEW             (gtex_build_view_get_type ())
#define GTEX_BUILD_VIEW(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTEX_TYPE_BUILD_VIEW, GtexBuildView))
#define GTEX_BUILD_VIEW_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GTEX_TYPE_BUILD_VIEW, GtexBuildViewClass))
#define GTEX_IS_BUILD_VIEW(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTEX_TYPE_BUILD_VIEW))
#define GTEX_IS_BUILD_VIEW_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GTEX_TYPE_BUILD_VIEW))
#define GTEX_BUILD_VIEW_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GTEX_TYPE_BUILD_VIEW, GtexBuildViewClass))

typedef struct _GtexBuildMsg         GtexBuildMsg;
typedef struct _GtexBuildViewClass   GtexBuildViewClass;
typedef struct _GtexBuildViewPrivate GtexBuildViewPrivate;

/**
 * GtexBuildState:
 * @GTEX_BUILD_STATE_RUNNING: running.
 * @GTEX_BUILD_STATE_SUCCEEDED: succeeded.
 * @GTEX_BUILD_STATE_FAILED: failed.
 * @GTEX_BUILD_STATE_ABORTED: aborted.
 */
typedef enum
{
	GTEX_BUILD_STATE_RUNNING,
	GTEX_BUILD_STATE_SUCCEEDED,
	GTEX_BUILD_STATE_FAILED,
	GTEX_BUILD_STATE_ABORTED
} GtexBuildState;

/**
 * GtexBuildMsgType:
 * @GTEX_BUILD_MSG_TYPE_MAIN_TITLE: main title.
 * @GTEX_BUILD_MSG_TYPE_JOB_TITLE: build job title.
 * @GTEX_BUILD_MSG_TYPE_JOB_SUB_COMMAND: build job sub-command.
 * @GTEX_BUILD_MSG_TYPE_ERROR: error.
 * @GTEX_BUILD_MSG_TYPE_WARNING: warning.
 * @GTEX_BUILD_MSG_TYPE_BADBOX: badbox.
 * @GTEX_BUILD_MSG_TYPE_INFO: other info.
 */
typedef enum
{
	GTEX_BUILD_MSG_TYPE_MAIN_TITLE,
	GTEX_BUILD_MSG_TYPE_JOB_TITLE,
	GTEX_BUILD_MSG_TYPE_JOB_SUB_COMMAND,
	GTEX_BUILD_MSG_TYPE_ERROR,
	GTEX_BUILD_MSG_TYPE_WARNING,
	GTEX_BUILD_MSG_TYPE_BADBOX,
	GTEX_BUILD_MSG_TYPE_INFO
} GtexBuildMsgType;

/**
 * GtexBuildMsg:
 * @type: the message type.
 * @text: the text.
 * @filename: reference to a certain file.
 * @start_line: reference to a line in the file, counting from 1. -1 to unset.
 * @end_line: reference to a line in the file, counting from 1. -1 to unset.
 * @children: list of children of type #GtexBuildMsg.
 * @expand: if the message has children, whether to initially show them.
 *
 * A build message, one line in the #GtkTreeView. If a @filename is provided,
 * the file will be opened when the user clicks on the message. If @start_line
 * and @end_line are provided, the lines between the two positions will be
 * selected (the selection stops at the end of @end_line).
 */
struct _GtexBuildMsg
{
	GtexBuildMsgType type;
	gchar *text;
	gchar *filename;
	gint start_line;
	gint end_line;

	/* There are several reasons to use a GQueue:
	* 1. A GQueue is convenient for appending at the end of the list.
	* 2. An external GNode containing the build messages is not convenient for
	* running sub-post-processors, for example the latex post-processor inside
	* latexmk. A GNode has a reference to its parent, so it's more difficult to
	* embed the messages of a sub-post-processor. Moreover, we don't need to know
	* the parent, a GNode uses useless memory. A GSList would use even less
	* memory, but it's less convenient to use.
	*/
	GQueue *children;

	guint expand : 1;
};

struct _GtexBuildView
{
	GtkTreeView parent;

	GtexBuildViewPrivate *priv;
};

struct _GtexBuildViewClass
{
	GtkTreeViewClass parent_class;
};

GtexBuildMsg *	gtex_build_msg_new			(void);

void		gtex_build_msg_reinit			(GtexBuildMsg *build_msg);

void		gtex_build_msg_free			(GtexBuildMsg *build_msg);

void		gtex_build_msg_print			(GtexBuildMsg *build_msg);

GType		gtex_build_view_get_type		(void);

GtexBuildView *	gtex_build_view_new			(void);

void		gtex_build_view_clear			(GtexBuildView *build_view);

GtkTreeIter	gtex_build_view_add_main_title		(GtexBuildView  *build_view,
							 const gchar    *main_title,
							 GtexBuildState  state);

GtkTreeIter	gtex_build_view_add_job_title		(GtexBuildView  *build_view,
							 const gchar    *job_title,
							 GtexBuildState  state);

void		gtex_build_view_set_title_state		(GtexBuildView  *build_view,
							 GtkTreeIter    *title_id,
							 GtexBuildState  state);

GtkTreeIter	gtex_build_view_append_single_message	(GtexBuildView *build_view,
							 GtkTreeIter   *parent,
							 GtexBuildMsg  *message);

void		gtex_build_view_append_messages		(GtexBuildView *build_view,
							 GtkTreeIter   *parent,
							 const GList   *messages,
							 gboolean       expand);

void		gtex_build_view_remove_children		(GtexBuildView *build_view,
							 GtkTreeIter   *parent);

G_END_DECLS
