/**************************************************************

cmpack_entity.h (C-Munipack project)
Auxilliary objects that are drawn on charts
Copyright (C) 2011 David Motl, dmotl@volny.cz

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU 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 General Public License for more details.

You should have received a copy of the GNU 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.

$Id: cmpack_entity.h,v 1.2 2016/05/01 16:15:04 dmotl Exp $

**************************************************************/

#ifndef CMPACK_ENTITY_H
#define CMPACK_ENTITY_H

#include <gtk/gtk.h>

#include "cmpack_widgdefs.h"

G_BEGIN_DECLS

/* Drawing context */
typedef struct _CmpackEntityDrawContext
{
	GdkDrawable *drawable;
	GdkGC *gc;
	GdkRectangle canvas_rc, clip_rc;
	const GdkColor *fg_color[CMPACK_N_COLORS], *bg_color;
	gboolean reverse_x, reverse_y;
	gdouble scale_x, scale_y;
	gdouble offset_x, offset_y;
	PangoLayout *layout;
} CmpackEntityDrawContext;

/*  ------------------------------   ENTITY BASE CLASS   --------------------------------------------- */

#define CMPACK_TYPE_ENTITY				(cmpack_entity_get_type ())
#define CMPACK_ENTITY(obj)				(G_TYPE_CHECK_INSTANCE_CAST ((obj), CMPACK_TYPE_ENTITY, CmpackEntity))
#define CMPACK_ENTITY_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST ((klass), CMPACK_TYPE_ENTITY, CmpackEntityClass))
#define CMPACK_IS_ENTITY(obj)			(G_TYPE_CHECK_INSTANCE_TYPE ((obj), CMPACK_TYPE_ENTITY))
#define CMPACK_IS_ENTITY_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), CMPACK_TYPE_ENTITY))
#define CMPACK_ENTITY_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), CMPACK_TYPE_ENTITY, CmpackEntityClass)) 

typedef struct _CmpackEntity			CmpackEntity;
typedef struct _CmpackEntityClass		CmpackEntityClass;

/* Entity */
struct _CmpackEntity 
{
	GObject			parent;

	const GdkColor	*custom_color;
};

/* Entity class */
struct _CmpackEntityClass
{
	GObjectClass parent_class;

	/* stuff */
	void (*draw_entity) (CmpackEntity *self, CmpackEntityDrawContext *context);
	void (*draw_label) (CmpackEntity *self, CmpackEntityDrawContext *context);
	void (*move) (CmpackEntity *self, gdouble x, gdouble y);
	void (*resize) (CmpackEntity *self, gdouble width, gdouble height);
};

GType cmpack_entity_get_type(void) G_GNUC_CONST;

void cmpack_entity_draw_entity(CmpackEntity *entity, CmpackEntityDrawContext *context);
void cmpack_entity_draw_label(CmpackEntity *entity, CmpackEntityDrawContext *context);
void cmpack_entity_move(CmpackEntity *entity, gdouble x, gdouble y);
void cmpack_entity_resize(CmpackEntity *entity, gdouble width, gdouble height);
const GdkColor *cmpack_entity_custom_color(CmpackEntity *entity);
void cmpack_entity_set_custom_color(CmpackEntity *entity, const GdkColor *color);

/*  ------------------------------   CIRCLE   ------------------------------------------------ */

#define CMPACK_TYPE_CIRCLE				(cmpack_circle_get_type ())
#define CMPACK_CIRCLE(obj)				(G_TYPE_CHECK_INSTANCE_CAST ((obj), CMPACK_TYPE_CIRCLE, CmpackCircle))
#define CMPACK_CIRCLE_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST ((klass), CMPACK_TYPE_CIRCLE, CmpackCircleClass))
#define CMPACK_IS_CIRCLE(obj)			(G_TYPE_CHECK_INSTANCE_TYPE ((obj), CMPACK_TYPE_CIRCLE))
#define CMPACK_IS_CIRCLE_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), CMPACK_TYPE_CIRCLE))
#define CMPACK_CIRCLE_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), CMPACK_TYPE_CIRCLE, CmpackCircleClass)) 

typedef struct _CmpackCircle			CmpackCircle;
typedef struct _CmpackCircleClass		CmpackCircleClass;

/* Circle */
struct _CmpackCircle 
{
	CmpackEntity	parent;

	gdouble			xphys, yphys;
	gdouble			width, height;
	CmpackColor		color;
	gboolean		filled;
};

/* Circle class */
struct _CmpackCircleClass
{
	CmpackEntityClass parent_class;
};

GType cmpack_circle_get_type(void) G_GNUC_CONST;

CmpackEntity *cmpack_new_circle(gdouble left, gdouble top, gdouble width, gdouble height, CmpackColor color, gboolean filled);

/*  ------------------------   QUADRATIC POLYNOMIAL CURVE  ----------------------------------- */

#define CMPACK_TYPE_QPCURVE				(cmpack_qpcurve_get_type ())
#define CMPACK_QPCURVE(obj)				(G_TYPE_CHECK_INSTANCE_CAST ((obj), CMPACK_TYPE_QPCURVE, CmpackQPCurve))
#define CMPACK_QPCURVE_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST ((klass), CMPACK_TYPE_QPCURVE, CmpackQPCurveClass))
#define CMPACK_IS_QPCURVE(obj)			(G_TYPE_CHECK_INSTANCE_TYPE ((obj), CMPACK_TYPE_QPCURVE))
#define CMPACK_IS_QPCURVE_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), CMPACK_TYPE_QPCURVE))
#define CMPACK_QPCURVE_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), CMPACK_TYPE_QPCURVE, CmpackQPCurveClass)) 

typedef struct _CmpackQPCurve			CmpackQPCurve;
typedef struct _CmpackQPCurveClass		CmpackQPCurveClass;

/* QPCurve */
struct _CmpackQPCurve 
{
	CmpackEntity	parent;

	gdouble			coeff[6];
	gdouble			t0, t1;
	CmpackColor		color;
	gboolean		filled;

	gboolean		data_changed;
	gdouble			scale_x, scale_y;
	gboolean		reverse_x, reverse_y;
	GdkRectangle	brect;				// Bounding rectangle
	GdkPoint		origin;				// Point where the curve starts
	GList			*pts;				// List of pointers to GdkPoint (relative offsets w.r.t. origin)
	int				npoints;			// Number of line endpoints
	GdkPoint		*points;			// endpoints
};

/* QPCurve class */
struct _CmpackQPCurveClass
{
	CmpackEntityClass parent_class;
};

GType cmpack_qpcurve_get_type(void) G_GNUC_CONST;

CmpackEntity *cmpack_new_qpcurve(const gdouble *coeff, gdouble t0, gdouble t1, CmpackColor color);

/*  ------------------------   MARK  ----------------------------------- */

#define CMPACK_TYPE_MARK				(cmpack_mark_get_type ())
#define CMPACK_MARK(obj)				(G_TYPE_CHECK_INSTANCE_CAST ((obj), CMPACK_TYPE_MARK, CmpackMark))
#define CMPACK_MARK_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST ((klass), CMPACK_TYPE_MARK, CmpackMarkClass))
#define CMPACK_IS_MARK(obj)				(G_TYPE_CHECK_INSTANCE_TYPE ((obj), CMPACK_TYPE_MARK))
#define CMPACK_IS_MARK_CLASS(klass)		(G_TYPE_CHECK_CLASS_TYPE ((klass), CMPACK_TYPE_MARK))
#define CMPACK_MARK_GET_CLASS(obj)		(G_TYPE_INSTANCE_GET_CLASS ((obj), CMPACK_TYPE_MARK, CmpackMarkClass)) 

typedef struct _CmpackMark				CmpackMark;
typedef struct _CmpackMarkClass			CmpackMarkClass;

/* Mark */
struct _CmpackMark 
{
	CmpackEntity	parent;

	gdouble			x, y;
	gdouble			tilt;
	CmpackColor		color;

	gboolean		data_changed;
	gboolean		reverse_x, reverse_y;
	gint			dx, dy;
};

/* Mark class */
struct _CmpackMarkClass
{
	CmpackEntityClass parent_class;
};

GType cmpack_mark_get_type(void) G_GNUC_CONST;

CmpackEntity *cmpack_new_mark(gdouble x, gdouble y, gdouble tilt, CmpackColor color);

/*  ------------------------   OBJECT  ----------------------------------- */

#define CMPACK_TYPE_OBJECT				(cmpack_object_get_type ())
#define CMPACK_OBJECT(obj)				(G_TYPE_CHECK_INSTANCE_CAST ((obj), CMPACK_TYPE_OBJECT, CmpackObject))
#define CMPACK_OBJECT_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST ((klass), CMPACK_TYPE_OBJECT, CmpackObjectClass))
#define CMPACK_IS_OBJECT(obj)			(G_TYPE_CHECK_INSTANCE_TYPE ((obj), CMPACK_TYPE_OBJECT))
#define CMPACK_IS_OBJECT_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), CMPACK_TYPE_OBJECT))
#define CMPACK_OBJECT_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), CMPACK_TYPE_OBJECT, CmpackObjectClass)) 

typedef struct _CmpackObject				CmpackObject;
typedef struct _CmpackObjectClass			CmpackObjectClass;

/* Object */
struct _CmpackObject
{
	CmpackEntity	parent;

	gdouble			x, y;
	CmpackColor		color;
	gchar			*caption;
};

/* Object class */
struct _CmpackObjectClass
{
	CmpackEntityClass parent_class;
};

GType cmpack_object_get_type(void) G_GNUC_CONST;

CmpackEntity *cmpack_new_object(gdouble x, gdouble y, CmpackColor color, const gchar *caption);

G_END_DECLS

#endif
