/**************************************************************************/
/* svgafft --  Spectrum Analyzer                                          */
/*                                                                        */ 
/* bar class interfaces                                                   */
/**************************************************************************/

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

    Copyright (C) 1995 Andrew Veliath

    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., 675 Mass Ave, Cambridge, MA 02139, USA.


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

// $Id: bars.h,v 0.4 1995/04/15 05:43:54 drewvel Exp $             

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

#ifndef _BARS_H_INCLUDED
#define _BARS_H_INCLUDED

#include "defvals.h"
#include "barconfig.h"

/*******************************************************************/
/* Continuous Bar Graph Class */
/*******************************************************************/

/*******************************************************************/
class BarGraph {
 protected:
  int x, y, w;
  int oldvalue, value;
  int height;
  int clipvalue, clipnum;
  int medbarval, highbarval;
  char label[32];

  /* NOTE: all data for future classes
     due to the nature of array allocation.
     Otherwise a segv will occur.
     
     Derived class data: */
  int segHeight, segSpace, divider;
  int peak;

  // for fading bar graph
  unsigned char current;
  unsigned char num;
  int *vals; // previous values

 public:
  BarGraph();

  BarGraph(int X, int Y=5, int W=DEFWIDTH, int Value=1, int Height=200);

  virtual ~BarGraph() {}

  virtual void AdjustVals();

  virtual void DrawLabel();
  virtual void DrawTick(int height, int color);

  void Label(const char *);

  void Reset() { value=0; oldvalue=0; peak=0; }

  /* clipping values */
  virtual void SetClipValue(int value);
  virtual int GetClipValue(void);
  
  virtual void SetProx(int X=5, int Y=-1, int W=0);

  void SetWidth(int W) { w=W; }

#ifdef RUNTIME_BARCHANGE // use virtual methods
  virtual void SetValue(int Value);
  virtual void Update(void);
#else // don't use virtual methods (faster)
  void SetValue(int Value);
  void Update(void);
#endif
};
/*******************************************************************/



/*******************************************************************/
/* Derived Classes Follow */
/*******************************************************************/


/*******************************************************************/
/* Segmented Bar Graph (like LED display) */
/*******************************************************************/

/*******************************************************************/
class SegmentedBarGraph:public BarGraph {
 protected:
  // data in base class (segHeight, segSpace)
  void DrawSegment(int num, int color);

  inline void SegmentedBarGraph::SegmentOn(int num);
  inline void SegmentedBarGraph::SegmentOff(int num);
  inline void SegmentedBarGraph::ShowPeak(int num);
  inline void SegmentedBarGraph::ShowClip(int num);
  
 public:
  SegmentedBarGraph(int X=5, int Y=5, 
		    int W=DEFWIDTH, int Value=0, 
		    int SegHeight=0, int SegSpace=0,
		    int Height=200);
  ~SegmentedBarGraph() {}

  void DrawTick(int height, int color);
  void DrawLabel();
  void SetProx(int X=5, int Y=-1, int W=0);

  void SetClipValue(int value);
  void AdjustVals();

  void SetSegs(int height, int space) 
    { segHeight=height; segSpace=space; 
      divider=segHeight+segSpace; }

  void SetValue(int Value);
  void Update(void);
};



/*******************************************************************/
/* One Segment Bar Graph (like floating LED display) */
/*******************************************************************/

/*******************************************************************/
class SegmentBarGraph:public SegmentedBarGraph {
 public:
  SegmentBarGraph(int X=5, int Y=5, 
		  int W=DEFWIDTH, int Value=0, 
		  int SegHeight=0, int SegSpace=0,
		  int Height=200);
  ~SegmentBarGraph() {}

  void SetClipValue(int value);

  void SetValue(int Value);
  void Update(void);
};


/*******************************************************************/
/* PeakDropSegmentedBarGraph (like LED display with peak ;-)) */
/*******************************************************************/

/*******************************************************************/
class PeakDropSegmentedBarGraph:public SegmentedBarGraph {
 public:
  PeakDropSegmentedBarGraph(int X=5, int Y=5, 
			    int W=DEFWIDTH, int Value=0, 
			    int SegHeight=0, int SegSpace=0,
			    int Height=200);

  ~PeakDropSegmentedBarGraph() {}
  
  void SetValue(int Value);
  void Update(void);
};


/*******************************************************************/
/* One Segment Bar Graph with Peak Drop (like floating LED display)*/
/*******************************************************************/

/*******************************************************************/
class PeakDropSegmentBarGraph:public PeakDropSegmentedBarGraph {
 public:
  PeakDropSegmentBarGraph(int X=5, int Y=5, 
			  int W=DEFWIDTH, int Value=0, 
			  int SegHeight=0, int SegSpace=0,
			  int Height=200);
  
  ~PeakDropSegmentBarGraph() {}

  void SetClipValue(int value);
  
  void SetValue(int Value);
  void Update(void);
};



/*******************************************************************/
/* EXPERIMENTAL: fading segment bar graph                          */
/*******************************************************************/

/*******************************************************************/
class FadeSegmentBarGraph:public SegmentedBarGraph {
 public:
  FadeSegmentBarGraph(int X=5, int Y=5, 
		  int W=DEFWIDTH, int Value=0, 
		  int SegHeight=0, int SegSpace=0,
		  int Height=200);
  ~FadeSegmentBarGraph() { if (vals) delete [] vals; }

  void SetClipValue(int value);

  void SetValue(int Value);
  void Update(void);
};


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

#endif _BARS_H_INCLUDED
