// chemdata.h --  the class that manages all of XDrawChem's data.

#ifndef CHEMDATA_H
#define CHEMDATA_H

#include <qobject.h>
#include <qlist.h>
#include <qstringlist.h>

#include "drawable.h"
#include "bond.h"
#include "text.h"
#include "cml.h"
#include "xdc_event.h"
#include "custom_rings.h"


class Render2D;
class Clipboard;

class ChemData : public QObject {
  Q_OBJECT
 public:
  void setRender2D(Render2D *r1) { r = r1; }
  void setCustomRings(CustomRings* rings) { m_rings=rings; }
  Render2D *getRender2D() { return r; }
  bool edited() { return false; }
  // defined in chemdata.cpp
  ChemData(QObject *parent = 0, const char *name = 0);
  void drawAll();
  Molecule *firstMolecule();
  void addMolecule(Molecule *);
  void drawBonds(QPainter* painter,float scale);
  void addBond(DPoint *, DPoint *, int, int, QColor, bool hl = false);
  void addArrow(DPoint *, DPoint *, QColor, int, bool hl = false);
  void addCurveArrow(DPoint *, DPoint *, QColor, QString, bool hl = false);
  void addBracket(DPoint *, DPoint *, QColor, int, bool hl = false);
  void addText(Text *);
  void addSymbol(DPoint *, QString, bool hl = false);
  void Erase(Drawable *);
  void EraseSelected();
  void DetectSplit();
  DPoint *FindNearestPoint(DPoint *, double &);
  Drawable *FindNearestObject(DPoint *, double &);
  void NewSelectRect(QRect, bool);
  void SelectAll(void);
  void DeselectAll(void);
  void Move(double, double);
  void Resize(DPoint *, double);
  void Rotate(DPoint *, double);
  void Flip(DPoint *, int);
  void SetColorIfHighlighted(QColor);
  void FinishMove();
  QRect selectionBox();
  QList<DPoint> UniquePoints();
  QList<Drawable> UniqueObjects();
  void SetTopLeft(QPoint p) { RenderTopLeft = p; }
  Molecule *insideMolecule(DPoint *);
  // defined in chemdata_edit.cpp
  void Cut();
  void Copy();
  bool Paste();
  void StartUndo(int fn = 0, DPoint *s1 = 0);
  bool Undo();
  void ScaleAll(double bond_length = -1.0);
  // defined in chemdata_rw.cpp
  bool load(QString);
  bool save(QString);
  bool load_legacy(QString);
  // defined in chemdata_xdc.cpp
  bool load_native(QString);
  bool save_native(QString);
  // defined in chemdata_cdx.cpp
  bool save_cdx(QString);
  bool save_cdxml(QString);
  // defined in chemdata_mdl.cpp
  bool load_mdl(QString);
  bool ProcessMDL(QString);
  bool save_mdl(QString);
  // defined in chemdata_xml.cpp
  bool load_xml(QString);
  bool ProcessXML(QString);
  bool LoadCDXMLFile(QString, QString);
  bool SelfContainedTag(QString);
  QString ReadTag(QString, int &);
  QString ReadData(QString, int &);
  QStringList ReadAttr(QString);
  QStringList Tokenize(QString);
  void ParseBoundingBox(QString, double &, double &, double &, double &);
  // defined in chemdata_cml.cpp
  bool NewLoadCMLFile(QString);
  bool LoadCMLFile(QString, QString);
  bool save_cml(QString);
  void Convert_CML_Lists_To_Native();
  // defined in chemdata_tools.cpp
  void clearAllGroups();
  void Tool(DPoint *, int);
  void AutoLayout();
  void fromSMILES(QString);
  void SmartPlace(QString, DPoint *);
  void SmartPlaceToo(QString, DPoint *);
  void SmartPlaceThree(QString, DPoint *);
  double CalculateRingAttachAngle(DPoint *);
  // defined in cdx2cdxml.cpp
  QString ParseProperty(QByteArray);
  QString CDXToCDXML(QString);
  // defined in chemdata_rxn.cpp
  void ReactionAnalysis(int);
  // defined here
  Clipboard *getClipboard() { return clip; }
  void setClipboard(Clipboard *clip1) {
    if (clip1 == 0)
      clip = new Clipboard;
    else
      clip = clip1;
  }
  public slots:
    void XDCEventHandler(XDC_Event *);

 signals:
  void SignalSetStatusBar(QString);
  void SignalHelpTopic(QString);

  // private:
  protected:
  CustomRings* m_rings;
  // the Render2D widget this ChemData is linked to
  Render2D *r;
  // Top left corner of visible part of r
  QPoint RenderTopLeft;
  // Application clipboard
  Clipboard *clip;
  // temporary/current Drawable (temporary DPoint *tmp_pt defined below)
  Drawable *tmp_draw;
  // list of Drawable objects we are tracking
  QList<Drawable> drawlist;
  // Variables for reading CML/CDXML/XML files
  QString MoleculeTitle;
  QString MoleculeId;
  QList<CML_Atom> CML_Atoms;
  QList<CML_Atom> CML_Atoms_Sub;
  QList<CML_Bond> CML_Bonds;
  QList<CML_Bond> CML_Bonds_Sub;
  QList<int> TagStack;
  QList<Drawable> CDXML_Objects;
  DPoint *tmp_pt;
  CML_Atom *tmp_atom;
  CML_Bond *tmp_bond;
  // variables for Undo
  int undo_last;
  DPoint *undo_start, *undo_end;
  double undo_dx, undo_dy;
  QStringList last_states;
  QString current_undo_file;
};

#endif
