/* DiaCanvas -- A technical drawing canvas.
 * Copyright (C) 1999, Arjan Molenaar
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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.
 */
/* Original license:
 * Dia -- an diagram creation/manipulation program
 * Copyright (C) 1998 Alexander Larsson
 *
 * 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.
 */
#ifndef __DIA_DIAGRAM_H__
#define __DIA_DIAGRAM_H__

#include <gtk/gtk.h>

#include <diacanvas/geometry.h>
#include <diacanvas/diaobject.h>
#include <diacanvas/dialayer.h>
#include <diacanvas/diadefs.h>

DIA_OPEN

#define DIA_TYPE_DIAGRAM            (dia_diagram_get_type ())
#define DIA_DIAGRAM(obj)            (GTK_CHECK_CAST ((obj), DIA_TYPE_DIAGRAM, DiaDiagram))
#define DIA_DIAGRAM_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), DIA_TYPE_DIAGRAM, DiaDiagramClass))
#define DIA_IS_DIAGRAM(obj)         (GTK_CHECK_TYPE ((obj), DIA_TYPE_DIAGRAM))
#define DIA_IS_DIAGRAM_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), DIA_TYPE_DIAGRAM))

typedef struct _DiaDiagram DiaDiagram;
typedef struct _DiaDiagramClass DiaDiagramClass;

#include <diacanvas/diadisplay.h>

struct _DiaDiagram 
{
  GtkObject object; /* parent */
  
  gchar *name;
  gint unsaved: 1;            /* True if diagram is created but not saved.*/
  gint modified: 1;
  gint auto_resize: 1; /* can the diagram rescale itself, according to the BB's
		     * of the layers. */
  
  Rectangle extents;      /* The extents of the diagram */

  DiaColor bg_color;

  GList *layers;     /* Layers ordered by decreasing z-order */
  /* NOTE: this first was a GPtrArray!!! be careful with converstions! */

  //DiaLayer *active_layer; -> to DiaDisplay
  
  GSList *displays;       /* List of all displays showing this diagram */
};

struct _DiaDiagramClass
{
  GtkObjectClass parent_class;
  
  void (*modified)        (DiaDiagram *diagram);

  /* Fires as soon as an object is added to the canvas. If you want
   * to know when if an object is succesfully added (scaled or whatever), use
   * DiaDisplay::object_added. That event will be fired by the create tool
   * to notify that an object is added to the canvas and will stay there.
   * This event is used basically for displays to know if they have to update.
   */
  void (*add_item)        (DiaDiagram *diagram, DiaLayer *layer,
			   DiaObject *object);
  /* A create object cicle has been completed successfully. */
  void (*add_item_done)   (DiaDiagram *diagram, DiaLayer *layer,
			   DiaObject *object);
  /* If a new object was by some reson not created, this event is fired. */
  void (*add_item_fail)   (DiaDiagram *diagram, DiaLayer *layer,
			   DiaObject *object);
 /* Returning FALSE will prevent the object from being removed.
   */
  void (*remove_item)     (DiaDiagram *diagram, DiaLayer *layer,
			   DiaObject *object);
  void (*name_changed)    (DiaDiagram *diagram);
};

extern GList *open_diagrams; /* Read only! */

/* Check the diagram list if there are modified diagrams */
gboolean dia_diagram_modified_exist ();


GtkType      gme_data_get_type (void);

/* UPDATE_BOX is the part of the diagram to update. If this is NULL, the
 * entire diagram will be drawn.
 * DATA is a pointer to information that will be given to OBJ_RENDERER, if
 * it is non-NULL.
 */
void   dia_diagram_render(DiaDiagram *diagram, DiaRenderer *renderer,
			  DiaObjectRenderer obj_renderer /* Can be NULL */,
			  Rectangle *update_box, /* may be NULL */
			  gpointer data);  

DiaDiagram* dia_diagram_new (gchar *name);  /* Note: name is copied */

/* wrapper functions for adding and removing objects to/from
 * the canvas. Use these in stead of the DiaLayer counterparts.
 */
void        dia_diagram_add_object (DiaDiagram *dia, DiaLayer *layer,
				    DiaObject *obj);
void        dia_diagram_add_objects (DiaDiagram *dia, DiaLayer *layer,
				     GList *obj_list);
void        dia_diagram_add_objects_first (DiaDiagram *dia, DiaLayer *layer,
					   GList *obj_list);
void        dia_diagram_remove_object (DiaDiagram *dia, DiaLayer *layer,
				       DiaObject *obj);

void        dia_diagram_set_modified (DiaDiagram *diagram,
				      gboolean is_modified);

void   dia_diagram_set_name (DiaDiagram *dia, gchar *name);
gchar* dia_diagram_get_name (DiaDiagram *dia);

void   dia_diagram_set_auto_resize (DiaDiagram *dia, gboolean auto_resize);

void   dia_diagram_set_extents (DiaDiagram *dia, gfloat left, gfloat top,
				gfloat right, gfloat bottom);

gint dia_diagram_update_extents (DiaDiagram *data);
/* Update only one layer and the diagram: */
gint dia_diagram_update_extents_fast (DiaDiagram *data, DiaLayer *layer);

/* DiaDisplay operations
 */
void dia_diagram_add_display (DiaDiagram *diagram, DiaDisplay *display);
void dia_diagram_remove_display (DiaDiagram *dia, DiaDisplay *ddisp);

/* Wrappers for DiaDisplay functions */
void dia_diagram_add_update (DiaDiagram *dia, Rectangle *update);
void dia_diagram_add_update_all (DiaDiagram *dia);
void dia_diagram_add_update_object (DiaDiagram *dia, DiaObject *object);
void dia_diagram_add_update_list (DiaDiagram *dia, GList *list_to_update);

/* This functions forces all displays redraw theirself.
 */
void dia_diagram_flush (DiaDiagram *dia);

/* DiaLayer operations
 */
void dia_diagram_add_layer (DiaDiagram *diagram, DiaLayer *layer);
void dia_diagram_add_layer_at (DiaDiagram *diagram, DiaLayer *layer, gint pos);
//void dia_diagram_set_active_layer (DiagramData *data, DiaLayer *layer);
void dia_diagram_delete_layer (DiaDiagram *data, DiaLayer *layer);
void dia_diagram_delete_layer_at (DiaDiagram *data, gint pos);

/* returns true if changed. */

DIA_CLOSE

#endif /* __DIA_DIAGRAM_H__ */







