
/*
 * ===========================
 * VDK Visual Development Kit
 * Version 2.0.2
 * May 2002
 * ===========================
 *
 * Copyright (C) 1998, Mario Motta
 * Developed by Mario Motta <mmotta@guest.net>
 * Based on ISDataBox
 * Developed by Ionutz Borcoman <borco@borco-ei.eng.hokudai.ac.jp>
 * based on  GtkDatabox - An extension to the gtk+ library
 * Copyright (C) 1998-1999 Roland Bock
 * 
 * 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.
 */

#ifndef _vdkdatabox_h_
#define _vdkdatabox_h_

#include <vdk/vdk.h>
#include <vdk/gtkdatabox.h>


/*! \class VDKDataBox
 *  \brief Databox widget.
 *
 *  This is a simple (almost 1:1) wrapper of 
 *	<b><a href="http://www.eudoxos.net/gtk/gtkdatabox/index.html">
 *		GtkDatabox 0.1.11.0
 *	</a></b>
 *  widget. 
 *  Some of the functions have been modified in order to return 
 *  a value, instead to change the value sent as parameter, as
 *  I have thought this is more in the VDK spirit. Also, wherever
 *  the case, I used a VDKColor instead of GdkColor, for the same
 *  reason: VDK spirit.
 *  
 *  The data box has the following styles (but check 
 *  \e GtkDataboxDataType for other styles):
 *  \arg GTK_DATABOX_NOT_DISPLAYED
 *  \arg GTK_DATABOX_POINTS
 *  \arg GTK_DATABOX_LINES
 *  \arg GTK_DATABOX_BARS
 *  \arg GTK_DATABOX_CROSS_SIMPLE,
 *  \arg GTK_DATABOX_GRID
 *
 *  <b>Public Members</b>
 *  \arg None.
 *
 *  <b>Properties</b>
 *  \arg bool \b Rulers
 *  \arg bool \b Scrollbars
 *  \arg bool \b Zoom
 *  \arg GtkDataboxValue \b Mark \e (read-only)
 *  \arg GtkDataboxValue \b Select \e (read-only)
 *  \arg GtkDataboxCoord \b TopLeft \e (read-only)
 *  \arg GtkDataboxCoord \b BottomRight \e (read-only)
 *
 *  <b>Static Table Signals</b>
 *  \arg \b databox_zoomed_signal Emitted when databox is zoomed.
 *  \arg \b databox_marked_signal Emitted when mouse is clicked in databox.
 *  \arg \b databox_selection_started_signal Emitted when a selection is started in databox.
 *  \arg \b databox_selection_changed_signal Emitted when the selection is changed. 
 *  \arg \b databox_selection_stopped_signal Emitted when the selection is finished. 
 *  \arg \b databox_selection_canceled_signal Emitted when the selection is canceled 
 *                             (by clicking outside the selection). 
 *  
 *  <b>Dynamic Table Signals</b>
 *  \arg \b "databox_zoomed"
 *  \arg \b "databox_marked"
 *  \arg \b "databox_selection_started"
 *  \arg \b "databox_selection_changed"
 *  \arg \b "databox_selection_stopped"
 *  \arg \b "databox_selection_canceled"
 *  
 *  Dynamic table signals are different from the equivalent databox signals in 
 *  that that they do not send values of the marked point or selection, for 
 *  instance. These values can be read using the \e read-only properties.  
 *
 *  \author Ionutz Borcoman <borco@borco-ei.eng.hokudai.ac.jp>
 *  \date March 1999
 *  \author Mario Motta <mmotta@guest.net> that have done the porting to vdk 2.x
 *  \date May 2002
 */
class VDKDataBox: public VDKObject
{
public:
  //! Constructor.
  VDKDataBox(VDKForm *owner);
  //! Destructor.
  ~VDKDataBox();

  //! Shows or hides the rulers.
  VDKReadWriteValueProp<VDKDataBox, bool> Rulers;
  void SetRulers(bool);

  //! Show or hides the scrollbars.
  VDKReadWriteValueProp<VDKDataBox, bool> Scrollbars;
  void SetScrollbars(bool);

  //! Enable or disable the zoom.
  VDKReadWriteValueProp<VDKDataBox, bool> Zoom;
  void SetZoom(bool);

  //! Read the value of the top left corner of the window after a zoom.
  VDKReadOnlyValueProp<VDKDataBox, GtkDataboxValue> TopLeft;

  //! Read the value of the bottom right corner of the window after a zoom.
  VDKReadOnlyValueProp<VDKDataBox, GtkDataboxValue> BottomRight;

  //! Read the value of the marked (where you clicked down the mouse) point.
  VDKReadOnlyValueProp<VDKDataBox, GtkDataboxCoord> Mark;

  //! Read the value of the selection.
  VDKReadOnlyValueProp<VDKDataBox, GtkDataboxCoord> Select;

  //! Get the color of a dataset.
  /*! \param index dataset index
   *  \return pointer to a VDKColor identical with the one of the dataset. 
   *  \bug The returned value is a pointer to a new allocated VDKColor. Therefore, 
   *       it will not reflect furthure changes in the color of the \e index dataset.
   *       You can free memory associated with it using Destroy() method.
   */
  VDKColor* GetColor(int index);

  //! Set the color of a dataset.
  /*! \param index dataset index
   *  \param color new color for the dataset
   *  \param redraw constrols if we call or not a subsequent Redraw().
   *                Set to \e false if you don't want a redraw.
   */
  void SetColor(int index, VDKColor *color, bool redraw = true);

  //! Get data value.
  /*! \param coord screen coordinates of a point.
   *  \return data value associated with the \e coord.
   */
  GtkDataboxValue GetValue(GtkDataboxCoord coord);

  //! Get the extreme values.
  /*! \param min returns the minimum x and y values of the databox.
   *  \param max returns the maximum x and y values of the databox.
   *  \param visible if true, then \e min and \e max are computed 
   *                 for the visible window; otherwise, they are
   *                 computed for the whole databox.
   */
  void GetExtrema(GtkDataboxValue& min, GtkDataboxValue& max, 
				  bool visible = true);

  //! Rescale the databox using given minimum and maximum values.
  /*! \param min the minimum x and y values.
   *  \param max the maximum x and y values.
   */
  void Rescale(GtkDataboxValue min, GtkDataboxValue max);

  /*! \brief Rescale the databox using the minimum and maximum 
   *         values from the datasets associated with the databox.
   */
  void Rescale();

  //! Redraw the databox. Use it after you change your datas.
  void Redraw();

  //! Remove a single dataset.
  /*! \param index index of dataset to be removed.
   *  \return 0 on success.
   */
  gint RemoveData(gint index);

  //! Remove all datasets.
  /*! \return 0 on success.
   */
  gint RemoveData();

  //! Remove a single dataset and destroy data associated with it.
  /*! \param index index of dataset to be destroyed.
   *  \return 0 on success.
   *  \bug this function destroys data associated using g_free().
   *       Do not use it, unless you have used g_new() to allocate 
   *       the memory for your data. 
   */
  gint DestroyData(gint index);

  //! Remove all datasets and destroy data associated with them.
  /*! \return 0 on success.
   *  \sa Destroy(gint)
   */
  gint DestroyData();

  //! Add a dataset.
  /*! Both X and Y must be supplied. Also the number of points and a color
   *  to be used for ploting the dataset.
   *  \param length number of points from the dataset.
   *  \param X pointer to x vector of data.
   *  \param Y pointer to y vector of data.
   *  \param color color for the ploting the dataset
   *  \param type type of points. 
   *  \param dotsize size of the dots used.
   *  \return index of the dataset added, on success, or -1, on error.
   */
  gint AddXY(guint length, gfloat *X, gfloat *Y, VDKColor *color, 
			 GtkDataboxDataType type = GTK_DATABOX_POINTS, guint dotSize = 1);

  //! Add a dataset.
  /*! You must supply a X vector of data and an index to an existent Y vector.
   *  Also the number of points and a color to be used for ploting the dataset.
   *  If the number of points of X and shared Y vector are different, an error
   *  is generated.
   *  \param length number of points from the dataset.
   *  \param X pointer to x vector of data.
   *  \param indexSharedY index to a shared y vector of data.
   *  \param color color for the ploting the dataset
   *  \param type type of points.
   *  \param dotsize size of the dots used.
   *  \return index of the dataset added, on success, or -1, on error.
   */
  gint AddX (guint length, gfloat *X, guint indexSharedY, VDKColor *color, 
			 GtkDataboxDataType type = GTK_DATABOX_POINTS, guint dotSize = 1);

  //! Add a dataset.
  /*! You must supply a Y vector of data and an index to an existent X vector.
   *  Also the number of points and a color to be used for ploting the dataset.
   *  If the number of points of X and shared Y vector are different, an error
   *  is generated.
   *  \param length number of points from the dataset.
   *  \param Y pointer to y vector of data.
   *  \param indexSharedX index to a shared x vector of data.
   *  \param color color for the ploting the dataset
   *  \param type type of points. 
   *  \param dotsize size of the dots used.
   *  \return index of the dataset added, on success, or -1, on error.
   */
  gint AddY (guint length, gfloat *Y, guint indexSharedX, VDKColor *color, 
			 GtkDataboxDataType type = GTK_DATABOX_POINTS, guint dotSize = 1);

virtual void SetBackground(VDKRgb color, GtkStateType state);
protected:
  // Signal handling functions 
  static gint _zoomed(GtkDatabox *box, 
					  GtkDataboxValue *top_left, 
					  GtkDataboxValue *bottom_right, 
					  gpointer);

  static gint _marked(GtkDatabox *, 
					  GtkDataboxCoord *mark, 
					  gpointer gp);

  static gint _selectionStarted(GtkDatabox *, 
								GtkDataboxCoord *mark, 
								gpointer gp);

  static gint _selectionChanged(GtkDatabox *, 
								GtkDataboxCoord *mark, 
								GtkDataboxCoord *select, 
								gpointer gp);

  static gint _selectionStoped(GtkDatabox *, 
							   GtkDataboxCoord *mark, 
							   GtkDataboxCoord *select, 
							   gpointer gp);

  static gint _selectionCanceled(GtkDatabox *, 
								 gpointer gp);

};
#endif
