//---------------------------------------------------------------------------
// Show qbits' states
//---------------------------------------------------------------------------
#ifndef QDrawGraphH
#define QDrawGraphH
//---------------------------------------------------------------------------
#include <vector>
#include "QBits.h"

//---------------------------------------------------------------------------
class QDrawGraph {
public:

  static const int DS_NO   = 0;
  static const int DS_UP   = 1;

  static const int DM_ALL  = 0;// DrawMode :DrawAll
  static const int DM_NONZERO  = 1;// DrawMode :Draw Onlye NonZero

  static const int FSIZE_INDEX = 12;//TODO:

  static const double EPS;

  QDrawGraph(TCanvas *_Canvas);
  ~QDrawGraph();

  void    DrawAll(const QBits *qbit, const int type=DS_NO);
  void    Paint(const QBits *qbit);

  void    SetCanvas(TCanvas *_Canvas) {mCanvas = _Canvas;}
  void    SetSizeOfArrow(const int size) {mSizeOfArrow = size;}
  void    SetFontSizeOfQbit(const int size) {mFontSizeOfQbit = size;}
  void    SetFontSizeOfValue(const int size) {mFontSizeOfValue = size;}
  void    SetPrecision(const int val) {mPrecision = val;}
  void    SetSize(const QBits *qbits);
  void    SetSizeNonZero(const QBits *qbits);
  void    SetImageSize(int w,int h) {mImageWidth=w;mImageHeight=h;};
  int     GetViewingTop(void) {return mViewingTop;};
  void    SetViewingTop(int t);
  double  GetViewingTopRatio(void) {return (double)mViewingTop/(double)(mHeight- mImageHeight);};
  void    SetViewingTopRatio(double r) {mViewingTop = int ((double)(mHeight- mImageHeight))*r;};
  void    SetDrawMode(int Mode, const QBits *qbits);
  int     GetDrawMode(void) {return mDrawMode;};

// NonZero
  void DrawNonZero(const QBits *qbits);
  int GetNonZeroCount(const QBits *qbits);


private:
  TCanvas *mCanvas;

//Draw Mode

  int     mDrawMode;

//Margin
  int     mTopWindowMargin;
  int     mTopMargin;
  int     mLeftMargin;
  int     mRowMargin;
  int     mRightMargin;
  int     mBottomMargin;
  int     mIAMargin;
  int     mAVMargin;
  int     mVQMargin;
  int     mStrOffset;

//Size of Image
  int     mImageHeight;
  int     mImageWidth;

//View Control

  int     mViewingTop;
  int     mHeight;
  int     mWidth;

//Size of elements
  int     mSizeOfArrow;
  int     mFontSizeOfValue;
  int     mFontSizeOfQbit;
  int     mPrecision;

//Below members are set automatically
  int     mWidthOfIndex;
  int     mHeightOfIndex;
  int     mWidthOfArrow;
  int     mHeightOfArrow;
  int     mWidthOfValue;
  int     mHeightOfValue;
  int     mWidthOfQbits;
  int     mHeightOfQbits;

//---------------------------------------------------------------------------
// Utility functions
//---------------------------------------------------------------------------
  int  GetRowHeight(void) const;
  void SetPageFormat(const QBits *qbits);
  void DrawNthRow(const QBits *qbits, const int nq, const int nrow) const;
  void DrawIndex(const int x, const int y, const int num) const;
  void DrawArrow(const int x, const int y, const double re, const double im) const;
  void DrawValue(const int x, const int y, double re, double im) const;
  void DrawQbit(const int x, const int y, const int ntotal, int nth) const;


};


//---------------------------------------------------------------------------
class QBitSortElement {
private:
  int index;
  double re;
  double im;

public:
  QBitSortElement(const int _index) {index = _index; re = 0.0; im = 0.0;}
  QBitSortElement(const int _index, const double _re, const double _im) {index = _index; re = _re; im = _im;}
  ~QBitSortElement() {}
  int GetIndex(void) {return index;}

//===========================================================================
// Warning, Operator < is redefined for sort (shoddy construction)
//===========================================================================
  bool operator<(const QBitSortElement &qelem) const {return re * re + im * im > qelem.re * qelem.re + qelem.im * qelem.im;}
};

typedef std::vector<QBitSortElement> QBitSortList;

//---------------------------------------------------------------------------
#endif
