/*

  VOTable parser


  Copyright © 2010 - 2013, 17 F.Hroch (hroch@physics.muni.cz)

  This file is part of Munipack.

  Munipack 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 3 of the License, or
  (at your option) any later version.

  Munipack 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 Munipack.  If not, see <http://www.gnu.org/licenses/>.


  Reference:

  http://www.ivoa.net/Documents/VOTable/20091130/REC-VOTable-1.2.html

*/

#include <wx/wx.h>
#include <wx/xml/xml.h>
#include <wx/url.h>
#include <map>
#include <vector>


class VOInfoBasic {
public:
  VOInfoBasic(const wxXmlNode *node);

protected:

  wxString description;
  std::vector<wxString> links;
  std::map<wxString,wxString> params;

};

class VOInfo : public VOInfoBasic
{
public:
  VOInfo(const wxXmlNode *node): VOInfoBasic(node) {}
};

class VOParam : public VOInfoBasic
{
public:
  VOParam(const wxXmlNode *node): VOInfoBasic(node) {}
};

class VOField : public VOInfoBasic
{
public:
  VOField(const wxXmlNode *node): VOInfoBasic(node) {}
  wxString GetLabel() const;
  wxString GetType() const;
  wxString GetUnit() const;
  wxString GetArraySize() const;
};

class VOCooSys : public VOInfoBasic {
public:
 VOCooSys(const wxXmlNode *node): VOInfoBasic(node) {}

  wxString GetEquinox() const;
  wxString GetCooSys() const;
  double GetEpoch() const;
};



class VOGroup {
public:
  VOGroup(const wxXmlNode *node);

  //private:

  wxString description;
  std::vector<VOParam> params;
  std::vector<wxString> refs;

};


class VOTableData {
public:
  VOTableData();
  VOTableData(const wxXmlNode *node);

  //private:

  int nrows;
  std::vector<wxString> elements;
  std::vector<wxXmlNode *> rows;

};

class VOData {
public:
  VOData();
  VOData(const wxXmlNode *);

  //private:

  VOTableData table;
  wxXmlNode *tablenode;

};


class VOTableTable {
public:
  VOTableTable(const wxXmlNode *node);
  int RecordCount() const;
  std::vector<wxString> GetRecord(int) const;
  std::vector<wxString> GetColumn(int) const;


  //private:

  wxString description;
  std::vector<VOParam> params;
  std::vector<VOField> fields;
  std::vector<VOGroup> groups;
  std::vector<VOInfo> infos;
  std::vector<wxString> links;
  VOData data;

};


class VOResource {
public:
  VOResource(const wxXmlNode *node);

  //private:

  wxString description;
  std::vector<VOParam> params;
  std::vector<VOField> fields;
  std::vector<VOGroup> groups;
  std::vector<VOInfo> infos;
  std::vector<wxString> links;
  std::vector<VOCooSys> coosys;
  std::vector<VOTableTable> tables;

};


class VOTable: public wxXmlDocument
{
public:
  /*
  VOTable();
  VOTable(const wxString&);
  VOTable(const wxInputStream&);
  */
  VOTable(const wxXmlDocument&);
  VOTable(const wxURL&);

  // interface for humans
  wxString GetDescription() const;
  double GetEpoch() const;
  std::vector<wxString> GetResources() const;
  void SetResource(int);
  std::vector<wxString> GetParams() const;
  std::vector<wxString> GetGroups() const;
  std::vector<wxString> GetInfos() const;

  std::vector<wxString> GetFields() const;
  std::vector<wxString> GetUnits() const;
  std::vector<wxString> GetTypes() const;
  int RecordCount() const;
  std::vector<wxString> GetRecord(int) const;
  std::vector<wxString> GetColumn(int) const;

  // interface for programmers

  void SetProjection(const wxString&);
  void SetProjectionCenter(double,double);
  void SetCanvasSize(long,long);
  void SetScale(double);
  void SetMaglim(double);
  void SetMagkey(const wxString&);
  void SetAlphakey(const wxString&);
  void SetDeltakey(const wxString&);

  bool Sort(const wxString&);

  bool Save(const wxString&, const wxString&, const wxString&);
  bool Save(wxOutputStream&, const wxString&);


private:

  int index;
  wxString description;
  std::vector<VOParam> params;
  std::vector<VOGroup> groups;
  std::vector<VOResource> resources;
  std::vector<VOInfo> infos;

  wxString proj_type, mag_key, alpha_key, delta_key;
  double proj_alpha, proj_delta, proj_scale, mag_limit;
  long canvas_width, canvas_height;

  int timeout; // network timeout in seconds

  bool Parse();
  std::vector<wxString> TypeTrafo(const std::vector<wxString>&);
  std::vector<wxString> FitsTypes();
  char **GetArray(const std::vector<wxString>&);
  bool SaveText(wxOutputStream&);
  bool SaveCSV(wxOutputStream&);
  bool SaveSVG(wxOutputStream&);
  bool SaveFITS(const wxString&,const wxString&);

  double ToDouble(const wxString&);
};

wxString GetString(const wxString&);
double GetDouble(const wxString&);
long GetLong(const wxString&);
bool GetBool(const wxString&);
void GetOutput(const wxString&, wxString&, wxString&);
