/*
** (c) 1996-2000 The Regents of the University of California (through
** E.O. Lawrence Berkeley National Laboratory), subject to approval by
** the U.S. Department of Energy.  Your use of this software is under
** license -- the license agreement is attached and included in the
** directory as license.txt or you may contact Berkeley Lab's Technology
** Transfer Department at TTD@lbl.gov.  NOTICE OF U.S. GOVERNMENT RIGHTS.
** The Software was developed under funding from the U.S. Government
** which consequently retains certain rights as follows: the
** U.S. Government has been granted for itself and others acting on its
** behalf a paid-up, nonexclusive, irrevocable, worldwide license in the
** Software to reproduce, prepare derivative works, and perform publicly
** and display publicly.  Beginning five (5) years after the date
** permission to assert copyright is obtained from the U.S. Department of
** Energy, and subject to any subsequent five (5) year renewals, the
** U.S. Government is granted for itself and others acting on its behalf
** a paid-up, nonexclusive, irrevocable, worldwide license in the
** Software to reproduce, prepare derivative works, distribute copies to
** the public, perform publicly and display publicly, and to permit
** others to do so.
*/

// -------------------------------------------------------------------
// XYPlotDataList.H
// -------------------------------------------------------------------
#ifndef XYPLOTDATALIST_H
#define XYPLOTDATALIST_H

#include <ListIterator.H>
#include <Array.H>
#include <BLassert.H>
#include <REAL.H>
#include <IntVect.H>
#include <FArrayBox.H>

#include <string>
using std::string;


class XYPlotDataListLink {
  friend class XYPlotDataListIterator;
  friend class XYPlotDataList;

  public:

    XYPlotDataListLink(Real *d, int sX, int len)
      : data(d), length(len), startXi(sX)
    { 
      BL_ASSERT(len != 0);
    };

  protected:
    Real *data;
    int length, startXi, endXi;
    XYPlotDataListLink *down;
    int nDown;
};


class XYPlotDataList {
  friend class XYPlotWin;
  friend class XYPlotDataListLink;
  friend class XYPlotDataListIterator;

  public:
    XYPlotDataList(const string &_derived, int max_level,
		   int _gridline,
		   const Array<int> &ratio_list,
		   const Array<Real> &d_x,
		   const Array<char *> &intersect_point,
		   Real start_x = 0.0);
    XYPlotDataList(XYPlotDataList *src);

    ~XYPlotDataList();

    char IsEmpty(void) { return emptyQ; }
    void AddFArrayBox(FArrayBox &fab, int direction, int level);

    void UpdateStats(void);
    void SetLevel(int new_level) {
      curLevel = (new_level < maxLevel) ? new_level : maxLevel;
    }

  protected:
    Array <List <XYPlotDataListLink *> *> dataSets; 
    Array <List <int> *> upXi;      // Used for data set iteration [level]
    Array <int> ratios;             // Used for insertion of data sets beginning
                                    // in the middle of a single cell [level]
    Array <Real> dX;                // dX in the proper direction [level]
    Array <char *> intersectPoint;  // Intersected value (in problem space)
                                    // for labelling plots [level]
    Array <double> lloY;            // min Y [level]
    Array <double> hhiY;            // max Y [level]

    int numPoints, maxLevel, curLevel, gridline;
    char updatedQ, emptyQ;
    double startX, endX, offsetX;
    string derived;
    XYPlotDataList *copied_from;

  private:
    void addLink(XYPlotDataListLink *l, int level);
};


class XYPlotDataListIterator {
  public:
    explicit XYPlotDataListIterator (XYPlotDataList *aList);
    ~XYPlotDataListIterator();
    XYPlotDataListIterator& operator++ ();
    bool operator! () const { return (curLink == NULL) ? true : false; }
    operator void* () { return (curLink != NULL) ? this : NULL; }

    double xval, yval;
  
  private:
    XYPlotDataList *list;
    Array <ListIterator <int> *> XiLI;
    Array <ListIterator <XYPlotDataListLink *> *> linkLI;
    XYPlotDataListLink *curLink, *nextLink;
    int curXi, nextXi, curLevel, maxLevel;
    Real *data;
};
 
#endif
