#ifndef __JDB__JSUPPORT__
#define __JDB__JSUPPORT__

#include <string>
#include <vector>

#include "JLang/JType.hh"
#include "JLang/JTypeList.hh"
#include "JROOT/JTreeParameters.hh"
#include "JDB/JDBTypes.hh"


/**
 * \file
 *
 * ROOT TTree parameter settings.\n
 * Type lists for various collections of data types.
 * \author mdejong
 */

namespace JDATABASE {

  using JLANG::JType;
  using JROOT::JTreeParameters;

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JDetectors>& type)
  {
    return JTreeParameters("DB_DETECTORS", "db_detectors", "", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JRuns>& type)
  {
    return JTreeParameters("DB_RUNS", "db_runs", "", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JDatalogNumbers>& type)
  {
    return JTreeParameters("DATALOGNUMBERS", "", "datalognumbers", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JDatalog>& type)
  {
    return JTreeParameters("DATALOG", "", "datalog", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JVendorHV>& type)
  {
    return JTreeParameters("VENDOR_HV", "vendor_hv", "", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JAHRS>& type)
  {
    return JTreeParameters("AHRS", "ahrs", "", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JAHRSCalibration>& type)
  {
    return JTreeParameters("AHRSCALIB", "ahrscalib", "", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JAllParams>& type)
  {
    return JTreeParameters("DB_ALLPARAMS", "db_allparams", "", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JPMTHVSettings>& type)
  {
    return JTreeParameters("HV_SETTINGS", "hv_settings", "", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JPMTHVRunSettings>& type)
  {
    return JTreeParameters("HV_RUN_SETTINGS", "hv_run_settings", "", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JPMTBestHVSettings>& type)
  {
    return JTreeParameters("BEST_HV_SETTINGS", "best_hv_settings", "", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JProductIntegration>& type)
  {
    return JTreeParameters("INTEGRATION", "integration", "", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JCLBMap>& type)
  {
    return JTreeParameters("CLBMAP", "clbmap", "", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JPersons>& type)
  {
    return JTreeParameters("PERSONS", "persons", "", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JToAshort>& type)
  {
    return JTreeParameters("DB_TOASHORT", "db_toashort", "", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JRunSummaryNumbers>& type)
  {
    return JTreeParameters("DB_RUNSUMMARYNUMBERS", "db_runsummarynumbers", "", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JRunQuality>& type)
  {
    return JTreeParameters("DB_RUNQUALITY", "db_runquality", "", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JRunsetupParams>& type)
  {
    return JTreeParameters("DB_RUNSETUPPARAMS", "db_runsetupparams", "", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JCLBID>& type)
  {
    return JTreeParameters("DB_CLBID", "db_clbid", "", 2);
  }

  /**
   * \param  type   data type
   * \return        TTree parameters
   */
  inline JTreeParameters getTreeParameters(const JType<JUPI>& type)
  {
    return JTreeParameters("DB_UPI", "db_upi", "", 2);
  }


  /**
   * Auxiliary method to get list of table names.
   */
  template<class JTypelist_t>
  struct JQueries :
    public std::vector<std::string>
  {
    /**
     * Default constructor.
     *
     * This constructor builds the list of queries from the given type list.
     */
    JQueries()
    {
      JLANG::for_each(*this, JType<JTypelist_t>());
    }


    /**
     * Add data type.
     *
     * \param  type        data type
     */
    template<class T>
    void operator()(const JType<T>& type)
    {
      this->push_back(T::getName());
    }
  };


  /**
   * Get list of possible queries.
   *
   * \return             list of possible queries
   */
  template<class JTypelist_t>
  inline const std::vector<std::string>& getQueries()
  { 
    static const JQueries<JTypelist_t> buffer;

    return buffer;
  }
}

/**
 * Type list of database data types for I/O.
 */
typedef JLANG::JTYPELIST<JDATABASE::JDetectors,
			 JDATABASE::JRuns,
			 JDATABASE::JDatalogNumbers,
			 JDATABASE::JVendorHV,
			 JDATABASE::JAHRS,
			 JDATABASE::JAHRSCalibration,
			 JDATABASE::JAHRSDetectorCalibration,
			 JDATABASE::JAllParams,
			 JDATABASE::JPMTHVSettings,
			 JDATABASE::JPMTHVRunSettings,
			 JDATABASE::JPMTBestHVSettings,
			 JDATABASE::JProductIntegration,
			 JDATABASE::JCLBMap,
			 JDATABASE::JDetectorIntegration,
			 JDATABASE::JPersons,
			 JDATABASE::JToAshort,
			 JDATABASE::JRunSummaryNumbers,
			 //JDATABASE::JRunQuality,
			 JDATABASE::JRunsetupParams,
			 JDATABASE::JUPI,
			 JDATABASE::JCLBID>::typelist                          JDBTypes_t;

#endif