#include "DD4hep/DetFactoryHelper.h"
#include "DD4hep/Printout.h"
#include "TMath.h"
#include "DDRec/Surface.h"
#include "DDRec/DetectorData.h"

//#include "Acts/Plugins/DD4hep/ActsExtension.hpp"

using namespace std;
using namespace dd4hep;
using namespace dd4hep::rec;

/** \addtogroup trackers Tracking Detectors
 */

/** \addtogroup GEMdisc GEM Disc Tracker
 * \brief Type: **GEMTrackerDisc**.
 * \ingroup trackers
 *
 *  A simple GEM disc tracker. 
 *
 * \code
 *   <detector>
 *   </detector>
 * \endcode
 *
 */
static Ref_t create_detector(Detector& lcdd, xml_h e, SensitiveDetector sens)
{
  typedef vector<PlacedVolume> Placements;

  xml_det_t   x_det     = e;
  Material    air       = lcdd.air();
  Material    carbon    = lcdd.material("CarbonFiber");
  Material    silicon   = lcdd.material("SiliconOxide");
  int         det_id    = x_det.id();
  string      det_name  = x_det.nameStr();
  PlacedVolume             pv;

  DetElement  sdet(det_name, det_id);
  Assembly    assembly(det_name+"_assembly");

  sens.setType("tracker");
  string module_name = "GEM";

  double thickness = 0.01*dd4hep::cm;

  int N_layers      = 0;

  for(xml_coll_t lay( x_det, _U(layer) ); lay; ++lay, ++N_layers)  {

    xml_comp_t x_layer  = lay;
    double     inner_r     = x_layer.attr<double>(  _Unicode(inner_r) ) ;
    double     outer_r     = x_layer.attr<double>(  _Unicode(outer_r) ) ;
    double     phi0_offset = x_layer.attr<double>(  _Unicode(phi0_offset) ) ;
    double     z           = x_layer.attr<double>(  _Unicode(z) ) ;
    int        layer_id    = x_layer.id();//attr<double>(  _Unicode(z) ) ;

    string  layer_name = std::string("gem_layer") + std::to_string(layer_id) ;

    Tube    gem_layer(inner_r, outer_r, thickness/2.0);
    Volume  gem_layer_vol("gem_layer_vol", gem_layer, carbon);

    gem_layer_vol.setSensitiveDetector(sens);

    DetElement layer_DE( sdet, _toString(layer_id,"layer%d"), layer_id );

    pv = assembly.placeVolume( gem_layer_vol, Transform3D(RotationZ(phi0_offset),Position(0.0,0.0,z)) );
    pv.addPhysVolID( "layer", layer_id );
    layer_DE.setPlacement(pv);

  }

  sdet.setAttributes(lcdd, assembly,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());

  pv = lcdd.pickMotherVolume(sdet).placeVolume(assembly);
  pv.addPhysVolID("system", det_id);      // Set the subdetector system ID.
  sdet.setPlacement(pv);

  assembly->GetShape()->ComputeBBox() ;
  return sdet;
}
DECLARE_DETELEMENT(my_GEMTracker, create_detector)