// @(#)root/gdml:$Id$
// Author: Anton Pytel 15/9/2011

/*************************************************************************
 * Copyright (C) 1995-2011, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TGDMLWRITE
#define ROOT_TGDMLWRITE

#ifndef ROOT_TGeoMatrix
#include "TGeoMatrix.h"
#endif

#ifndef ROOT_TXMLEngine
#include "TXMLEngine.h"
#endif

#ifndef ROOT_TGeoVolume
#include "TGeoVolume.h"
#endif

#ifndef ROOT_TGeoParaboloid
#include "TGeoParaboloid.h"
#endif

#ifndef ROOT_TGeoSphere
#include "TGeoSphere.h"
#endif

#ifndef ROOT_TGeoArb8
#include "TGeoArb8.h"
#endif

#ifndef ROOT_TGeoCone
#include "TGeoCone.h"
#endif

#ifndef ROOT_TGeoPara
#include "TGeoPara.h"
#endif

#ifndef ROOT_TGeoTrd1
#include "TGeoTrd1.h"
#endif

#ifndef ROOT_TGeoTrd2
#include "TGeoTrd2.h"
#endif

#ifndef ROOT_TGeoTube
#include "TGeoTube.h"
#endif

#ifndef ROOT_TGeoPcon
#include "TGeoPcon.h"
#endif

#ifndef ROOT_TGeoTorus
#include "TGeoTorus.h"
#endif

#ifndef ROOT_TGeoPgon
#include "TGeoPgon.h"
#endif

#ifndef ROOT_TGeoXtru
#include "TGeoXtru.h"
#endif

#ifndef ROOT_TGeoPgon
#include "TGeoPgon.h"
#endif

#ifndef ROOT_TGeoEltu
#include "TGeoEltu.h"
#endif

#ifndef ROOT_TGeoHype
#include "TGeoHype.h"
#endif

#ifndef ROOT_TGeoBoolNode
#include "TGeoBoolNode.h"
#endif

#ifndef ROOT_TGeoCompositeShape
#include "TGeoCompositeShape.h"
#endif

#ifndef ROOT_TGeoScaledShape
#include "TGeoScaledShape.h"
#endif

#include <map>
#include <vector>
#include <iostream>

////////////////////////////////////////////////////////////////////////////
//                                                                        //
// TGDMLWrite - Class for exporting geometries From ROOT's gGeoManager    //
//    (instance of TGeoManager class) To GDML file. More about GDML       //
//    see http://gdml.web.cern.ch.                                        //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

class TGDMLWrite : public TObject {
public:
   TGDMLWrite();
   virtual ~TGDMLWrite();

   static void StartGDMLWriting(TGeoManager * geomanager, const char* filename, TString option) {
      //static function -
      //options:
      //  g - set by default - geant4 compatibility
      //  f,n - if none of this two is set then naming convention is
      //        with incremental suffix, if "f" then suffix is pointer
      //        if "n" then there is no suffix, but uniqness of names
      //        is not secured.
      TGDMLWrite *writer = new TGDMLWrite;
      writer->WriteGDMLfile(geomanager, filename, option);
      delete writer;
   }
   //wrapper of all main methods for extraction
   void WriteGDMLfile(TGeoManager * geomanager, const char* filename = "test.gdml", TString option = "");
   enum ENamingType {
      kelegantButSlow = 0,
      kwithoutSufixNotUniq = 1,
      kfastButUglySufix = 2
   };
   void SetNamingSpeed(ENamingType naming);
   void SetG4Compatibility(Bool_t G4Compatible) {
      fgG4Compatibility = G4Compatible;
   };

private:
   struct Xyz {
      Double_t x;
      Double_t y;
      Double_t z;
   };

   typedef  std::map<TString, Bool_t> NameList;
   typedef  std::map<TString, TString> NameListS;
   typedef  std::map<TString, Int_t> NameListI;
   typedef  std::map<TString, Float_t> NameListF;
   struct StructLst {
      NameList fLst;
   };     //to store pointers
   struct NameLst {
      NameListS fLst;        //to map pointers with names
      NameListI fLstIter;    //to store all the iterators for repeating names
   };

   //General lists
   StructLst *fIsotopeList;   //list of isotopes
   StructLst *fElementList;   //list of elements
   StructLst *fAccPatt;       //list of accepted patterns for division
   StructLst *fRejShape;      //list of rejected shapes

   NameLst *fNameList; //list of names (pointer mapped)

   //Data members
   static TGDMLWrite *fgGDMLWrite;                         //pointer to gdml writer
   Int_t  fgNamingSpeed;                                   //input option for volume and solid naming
   Bool_t fgG4Compatibility;                               //input option for Geant4 compatibility
   XMLDocPointer_t  fGdmlFile;                             //pointer storing xml file
   TString fTopVolumeName;                                 //name of top volume
   TXMLEngine *fGdmlE;                                     //xml engine pointer

   XMLNodePointer_t fDefineNode;                           //main <define> node...
   XMLNodePointer_t fMaterialsNode;                        //main <materials> node...
   XMLNodePointer_t fSolidsNode;                           //main <solids> node...
   XMLNodePointer_t fStructureNode;                        //main <structure> node...
   Int_t        fVolCnt;                                   //count of volumes
   Int_t        fPhysVolCnt;                               //count of physical volumes
   UInt_t       fActNameErr;                               //count of name errors
   UInt_t       fSolCnt;                                   //count of name solids

   static const UInt_t fgkProcBit    = BIT(14);    //14th bit is set when solid is processed
   static const UInt_t fgkProcBitVol = BIT(19);    //19th bit is set when volume is processed
   static const UInt_t fgkMaxNameErr = 5;          //maximum number of errors for naming

   //I. Methods processing the gGeoManager geometry object structure
   //1. Main methods to extract everything from ROOT gGeoManager
   XMLNodePointer_t ExtractMaterials(TList* materialsLst); //result <materials>...
   TString          ExtractSolid(TGeoShape* volShape);     //adds <shape> to <solids>
   void             ExtractVolumes(TGeoVolume* volume);    //result <volume> node...  + corresp. shape


   //1.1 Materials sub methods - creating Nodes
   XMLNodePointer_t CreateAtomN(Double_t atom, const char * unit = "g/mole");
   XMLNodePointer_t CreateDN(Double_t density, const char * unit = "g/cm3");
   XMLNodePointer_t CreateFractionN(Double_t percentage, const char * refName);

   XMLNodePointer_t CreateIsotopN(TGeoIsotope * isotope, const char * name);
   XMLNodePointer_t CreateElementN(TGeoElement * element, XMLNodePointer_t materials, const char * name);
   XMLNodePointer_t CreateMixtureN(TGeoMixture * mixture, XMLNodePointer_t materials, TString mname);
   XMLNodePointer_t CreateMaterialN(TGeoMaterial * material, TString mname);


   //1.2 Solids sub methods
   XMLNodePointer_t ChooseObject(TGeoShape *geoShape);
   XMLNodePointer_t CreateZplaneN(Double_t z, Double_t rmin, Double_t rmax);

   XMLNodePointer_t CreateBoxN(TGeoBBox * geoShape);
   XMLNodePointer_t CreateParaboloidN(TGeoParaboloid * geoShape);
   XMLNodePointer_t CreateSphereN(TGeoSphere * geoShape);
   XMLNodePointer_t CreateArb8N(TGeoArb8 * geoShape);
   XMLNodePointer_t CreateConeN(TGeoConeSeg * geoShape);
   XMLNodePointer_t CreateConeN(TGeoCone * geoShape);
   XMLNodePointer_t CreateParaN(TGeoPara * geoShape);
   XMLNodePointer_t CreateTrapN(TGeoTrap * geoShape);
   XMLNodePointer_t CreateTwistedTrapN(TGeoGtra * geoShape);
   XMLNodePointer_t CreateTrdN(TGeoTrd1 * geoShape);
   XMLNodePointer_t CreateTrdN(TGeoTrd2 * geoShape);
   XMLNodePointer_t CreateTubeN(TGeoTubeSeg * geoShape);
   XMLNodePointer_t CreateCutTubeN(TGeoCtub * geoShape);
   XMLNodePointer_t CreateTubeN(TGeoTube * geoShape);
   XMLNodePointer_t CreatePolyconeN(TGeoPcon * geoShape);
   XMLNodePointer_t CreateTorusN(TGeoTorus * geoShape);
   XMLNodePointer_t CreatePolyhedraN(TGeoPgon * geoShape);
   XMLNodePointer_t CreateEltubeN(TGeoEltu * geoShape);
   XMLNodePointer_t CreateHypeN(TGeoHype * geoShape);
   XMLNodePointer_t CreateXtrusionN(TGeoXtru * geoShape);
   XMLNodePointer_t CreateEllipsoidN(TGeoCompositeShape * geoShape, TString elName);
   XMLNodePointer_t CreateElConeN(TGeoScaledShape * geoShape);

   XMLNodePointer_t CreateCommonBoolN(TGeoCompositeShape *geoShape);

   //1.3 Volume sub methods
   XMLNodePointer_t CreatePhysVolN(const char * volref, const char * posref, const char * rotref, XMLNodePointer_t scaleN);
   XMLNodePointer_t CreateDivisionN(Double_t offset, Double_t width, Int_t number, const char * axis, const char * unit, const char * volref);

   XMLNodePointer_t CreateSetupN(const char * topVolName , const char * name = "default", const char * version = "1.0");
   XMLNodePointer_t StartVolumeN(const char * name, const char * solid, const char * material);
   XMLNodePointer_t StartAssemblyN(const char * name);


   //II. Utility methods
   Xyz GetXYZangles(const Double_t * rotationMatrix);
   //nodes to create position, rotation and similar types first-position/rotation...
   XMLNodePointer_t CreatePositionN(const char * name, Xyz position, const char * type = "position", const char * unit = "cm");
   XMLNodePointer_t CreateRotationN(const char * name, Xyz rotation, const char * type = "rotation", const char * unit = "deg");
   TGeoCompositeShape* CreateFakeCtub(TGeoCtub * geoShape);  //create fake cut tube as intersection

   //check name (2nd parameter) whether it is in the list (1st parameter)
   Bool_t IsInList(NameList list, TString name2check);
   TString GenName(TString oldname);
   TString GenName(TString oldname, TString objPointer);
   Bool_t CanProcess(TObject *pointer);
   TString GetPattAxis(Int_t divAxis, const char * pattName, TString& unit);
   Bool_t IsNullParam(Double_t parValue, TString parName, TString objName);
   void UnsetTemporaryBits(TGeoManager * geoMng);

   ClassDef(TGDMLWrite, 0)    //imports GDML using DOM and binds it to ROOT
};

#endif /* ROOT_TGDMLWRITE */
 TGDMLWrite.h:1
 TGDMLWrite.h:2
 TGDMLWrite.h:3
 TGDMLWrite.h:4
 TGDMLWrite.h:5
 TGDMLWrite.h:6
 TGDMLWrite.h:7
 TGDMLWrite.h:8
 TGDMLWrite.h:9
 TGDMLWrite.h:10
 TGDMLWrite.h:11
 TGDMLWrite.h:12
 TGDMLWrite.h:13
 TGDMLWrite.h:14
 TGDMLWrite.h:15
 TGDMLWrite.h:16
 TGDMLWrite.h:17
 TGDMLWrite.h:18
 TGDMLWrite.h:19
 TGDMLWrite.h:20
 TGDMLWrite.h:21
 TGDMLWrite.h:22
 TGDMLWrite.h:23
 TGDMLWrite.h:24
 TGDMLWrite.h:25
 TGDMLWrite.h:26
 TGDMLWrite.h:27
 TGDMLWrite.h:28
 TGDMLWrite.h:29
 TGDMLWrite.h:30
 TGDMLWrite.h:31
 TGDMLWrite.h:32
 TGDMLWrite.h:33
 TGDMLWrite.h:34
 TGDMLWrite.h:35
 TGDMLWrite.h:36
 TGDMLWrite.h:37
 TGDMLWrite.h:38
 TGDMLWrite.h:39
 TGDMLWrite.h:40
 TGDMLWrite.h:41
 TGDMLWrite.h:42
 TGDMLWrite.h:43
 TGDMLWrite.h:44
 TGDMLWrite.h:45
 TGDMLWrite.h:46
 TGDMLWrite.h:47
 TGDMLWrite.h:48
 TGDMLWrite.h:49
 TGDMLWrite.h:50
 TGDMLWrite.h:51
 TGDMLWrite.h:52
 TGDMLWrite.h:53
 TGDMLWrite.h:54
 TGDMLWrite.h:55
 TGDMLWrite.h:56
 TGDMLWrite.h:57
 TGDMLWrite.h:58
 TGDMLWrite.h:59
 TGDMLWrite.h:60
 TGDMLWrite.h:61
 TGDMLWrite.h:62
 TGDMLWrite.h:63
 TGDMLWrite.h:64
 TGDMLWrite.h:65
 TGDMLWrite.h:66
 TGDMLWrite.h:67
 TGDMLWrite.h:68
 TGDMLWrite.h:69
 TGDMLWrite.h:70
 TGDMLWrite.h:71
 TGDMLWrite.h:72
 TGDMLWrite.h:73
 TGDMLWrite.h:74
 TGDMLWrite.h:75
 TGDMLWrite.h:76
 TGDMLWrite.h:77
 TGDMLWrite.h:78
 TGDMLWrite.h:79
 TGDMLWrite.h:80
 TGDMLWrite.h:81
 TGDMLWrite.h:82
 TGDMLWrite.h:83
 TGDMLWrite.h:84
 TGDMLWrite.h:85
 TGDMLWrite.h:86
 TGDMLWrite.h:87
 TGDMLWrite.h:88
 TGDMLWrite.h:89
 TGDMLWrite.h:90
 TGDMLWrite.h:91
 TGDMLWrite.h:92
 TGDMLWrite.h:93
 TGDMLWrite.h:94
 TGDMLWrite.h:95
 TGDMLWrite.h:96
 TGDMLWrite.h:97
 TGDMLWrite.h:98
 TGDMLWrite.h:99
 TGDMLWrite.h:100
 TGDMLWrite.h:101
 TGDMLWrite.h:102
 TGDMLWrite.h:103
 TGDMLWrite.h:104
 TGDMLWrite.h:105
 TGDMLWrite.h:106
 TGDMLWrite.h:107
 TGDMLWrite.h:108
 TGDMLWrite.h:109
 TGDMLWrite.h:110
 TGDMLWrite.h:111
 TGDMLWrite.h:112
 TGDMLWrite.h:113
 TGDMLWrite.h:114
 TGDMLWrite.h:115
 TGDMLWrite.h:116
 TGDMLWrite.h:117
 TGDMLWrite.h:118
 TGDMLWrite.h:119
 TGDMLWrite.h:120
 TGDMLWrite.h:121
 TGDMLWrite.h:122
 TGDMLWrite.h:123
 TGDMLWrite.h:124
 TGDMLWrite.h:125
 TGDMLWrite.h:126
 TGDMLWrite.h:127
 TGDMLWrite.h:128
 TGDMLWrite.h:129
 TGDMLWrite.h:130
 TGDMLWrite.h:131
 TGDMLWrite.h:132
 TGDMLWrite.h:133
 TGDMLWrite.h:134
 TGDMLWrite.h:135
 TGDMLWrite.h:136
 TGDMLWrite.h:137
 TGDMLWrite.h:138
 TGDMLWrite.h:139
 TGDMLWrite.h:140
 TGDMLWrite.h:141
 TGDMLWrite.h:142
 TGDMLWrite.h:143
 TGDMLWrite.h:144
 TGDMLWrite.h:145
 TGDMLWrite.h:146
 TGDMLWrite.h:147
 TGDMLWrite.h:148
 TGDMLWrite.h:149
 TGDMLWrite.h:150
 TGDMLWrite.h:151
 TGDMLWrite.h:152
 TGDMLWrite.h:153
 TGDMLWrite.h:154
 TGDMLWrite.h:155
 TGDMLWrite.h:156
 TGDMLWrite.h:157
 TGDMLWrite.h:158
 TGDMLWrite.h:159
 TGDMLWrite.h:160
 TGDMLWrite.h:161
 TGDMLWrite.h:162
 TGDMLWrite.h:163
 TGDMLWrite.h:164
 TGDMLWrite.h:165
 TGDMLWrite.h:166
 TGDMLWrite.h:167
 TGDMLWrite.h:168
 TGDMLWrite.h:169
 TGDMLWrite.h:170
 TGDMLWrite.h:171
 TGDMLWrite.h:172
 TGDMLWrite.h:173
 TGDMLWrite.h:174
 TGDMLWrite.h:175
 TGDMLWrite.h:176
 TGDMLWrite.h:177
 TGDMLWrite.h:178
 TGDMLWrite.h:179
 TGDMLWrite.h:180
 TGDMLWrite.h:181
 TGDMLWrite.h:182
 TGDMLWrite.h:183
 TGDMLWrite.h:184
 TGDMLWrite.h:185
 TGDMLWrite.h:186
 TGDMLWrite.h:187
 TGDMLWrite.h:188
 TGDMLWrite.h:189
 TGDMLWrite.h:190
 TGDMLWrite.h:191
 TGDMLWrite.h:192
 TGDMLWrite.h:193
 TGDMLWrite.h:194
 TGDMLWrite.h:195
 TGDMLWrite.h:196
 TGDMLWrite.h:197
 TGDMLWrite.h:198
 TGDMLWrite.h:199
 TGDMLWrite.h:200
 TGDMLWrite.h:201
 TGDMLWrite.h:202
 TGDMLWrite.h:203
 TGDMLWrite.h:204
 TGDMLWrite.h:205
 TGDMLWrite.h:206
 TGDMLWrite.h:207
 TGDMLWrite.h:208
 TGDMLWrite.h:209
 TGDMLWrite.h:210
 TGDMLWrite.h:211
 TGDMLWrite.h:212
 TGDMLWrite.h:213
 TGDMLWrite.h:214
 TGDMLWrite.h:215
 TGDMLWrite.h:216
 TGDMLWrite.h:217
 TGDMLWrite.h:218
 TGDMLWrite.h:219
 TGDMLWrite.h:220
 TGDMLWrite.h:221
 TGDMLWrite.h:222
 TGDMLWrite.h:223
 TGDMLWrite.h:224
 TGDMLWrite.h:225
 TGDMLWrite.h:226
 TGDMLWrite.h:227
 TGDMLWrite.h:228
 TGDMLWrite.h:229
 TGDMLWrite.h:230
 TGDMLWrite.h:231
 TGDMLWrite.h:232
 TGDMLWrite.h:233
 TGDMLWrite.h:234
 TGDMLWrite.h:235
 TGDMLWrite.h:236
 TGDMLWrite.h:237
 TGDMLWrite.h:238
 TGDMLWrite.h:239
 TGDMLWrite.h:240
 TGDMLWrite.h:241
 TGDMLWrite.h:242
 TGDMLWrite.h:243
 TGDMLWrite.h:244
 TGDMLWrite.h:245
 TGDMLWrite.h:246
 TGDMLWrite.h:247
 TGDMLWrite.h:248
 TGDMLWrite.h:249
 TGDMLWrite.h:250
 TGDMLWrite.h:251
 TGDMLWrite.h:252
 TGDMLWrite.h:253
 TGDMLWrite.h:254
 TGDMLWrite.h:255
 TGDMLWrite.h:256
 TGDMLWrite.h:257
 TGDMLWrite.h:258
 TGDMLWrite.h:259
 TGDMLWrite.h:260
 TGDMLWrite.h:261
 TGDMLWrite.h:262
 TGDMLWrite.h:263