// @(#)root/geom:$Id$
// Author: Rene Brun   26/12/02

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

////////////////////////////////////////////////////////////////////////////////
// Media are used to store properties related to tracking and which are useful
// only when using geometry with a particle transport MC package (via VMC). One
// may define several tracking media for a given material. The media ID are user
// defined values that are not used by the geometry package. In case geometry
// is used via VMC (in GEANT) these numbers are overwritten, so one can only
// rely on these values after gMC->FinishGeometry() is called.
// The media parameters are inspired from GEANT3 and the values defined make sense
// in context of GEANT (3 but also 4) or FLUKA interfaces.
////////////////////////////////////////////////////////////////////////////////

#include "Riostream.h"
#include "TGeoManager.h"
#include "TGeoMedium.h"
#include "TList.h"

ClassImp(TGeoMedium)

//-----------------------------------------------------------------------------
TGeoMedium::TGeoMedium()
{
// Default constructor
   fId      = 0;
   for (Int_t i=0; i<20; i++) fParams[i] = 0.;
   fMaterial= 0;
}

//-----------------------------------------------------------------------------
TGeoMedium::TGeoMedium(const char *name, Int_t numed, const TGeoMaterial *mat, Double_t *params)
             :TNamed(name,"")
{
// constructor
   fName = fName.Strip();
   fId    = numed;
   for (Int_t i=0; i<20; i++) fParams[i] = 0.;
   fMaterial = (TGeoMaterial*)mat;
   for (Int_t i=0;i<10;i++) {
      if (params) fParams[i] = params[i];
      else        fParams[i] = 0;
   }
   gGeoManager->GetListOfMedia()->Add(this);
}

//-----------------------------------------------------------------------------
TGeoMedium::TGeoMedium(const char *name, Int_t numed, Int_t imat, Int_t isvol, Int_t ifield,
              Double_t fieldm, Double_t tmaxfd, Double_t stemax, Double_t deemax, Double_t epsil, Double_t stmin)
             :TNamed(name,"")
{
// constructor
   fName = fName.Strip();
   fId    = numed;
   for (Int_t i=0; i<20; i++) fParams[i] = 0.;
   TIter next (gGeoManager->GetListOfMaterials());
   TGeoMaterial *mat;
   while ((mat = (TGeoMaterial*)next())) {
      if (mat->GetUniqueID() == (UInt_t)imat) break;
   }
   if (!mat || (mat->GetUniqueID() != (UInt_t)imat)) {
      fMaterial = 0;
      Error("TGeoMedium", "%s, material number %d does not exist",name,imat);
      return;
   }
   fMaterial = (TGeoMaterial*)mat;
   fParams[0] = isvol;
   fParams[1] = ifield;
   fParams[2] = fieldm;
   fParams[3] = tmaxfd;
   fParams[4] = stemax;
   fParams[5] = deemax;
   fParams[6] = epsil;
   fParams[7] = stmin;
   gGeoManager->GetListOfMedia()->Add(this);
}

//-----------------------------------------------------------------------------
TGeoMedium::TGeoMedium(const TGeoMedium& gm) :
  TNamed(gm),
  fId(gm.fId),
  fMaterial(gm.fMaterial)
{
   //copy constructor
   for(Int_t i=0; i<20; i++) fParams[i]=gm.fParams[i];
}

//-----------------------------------------------------------------------------
TGeoMedium& TGeoMedium::operator=(const TGeoMedium& gm)
{
   //assignment operator
   if(this!=&gm) {
      TNamed::operator=(gm);
      fId=gm.fId;
      for(Int_t i=0; i<20; i++) fParams[i]=gm.fParams[i];
      fMaterial=gm.fMaterial;
   }
   return *this;
}

//-----------------------------------------------------------------------------
TGeoMedium::~TGeoMedium()
{
// Destructor
}

//_____________________________________________________________________________
char *TGeoMedium::GetPointerName() const
{
// Provide a pointer name containing uid.
   static TString name;
   name = TString::Format("pMed%d", GetUniqueID());
   return (char*)name.Data();
}

//_____________________________________________________________________________
void TGeoMedium::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
{
// Save a primitive as a C++ statement(s) on output stream "out".
   if (TestBit(TGeoMedium::kMedSavePrimitive)) return;
   fMaterial->SavePrimitive(out,option);
   out << "// Medium: " << GetName() << std::endl;
   out << "   numed   = " << fId << ";  // medium number" << std::endl;
   out << "   par[0]  = " << fParams[0] << "; // isvol" << std::endl;
   out << "   par[1]  = " << fParams[1] << "; // ifield" << std::endl;
   out << "   par[2]  = " << fParams[2] << "; // fieldm" << std::endl;
   out << "   par[3]  = " << fParams[3] << "; // tmaxfd" << std::endl;
   out << "   par[4]  = " << fParams[4] << "; // stemax" << std::endl;
   out << "   par[5]  = " << fParams[5] << "; // deemax" << std::endl;
   out << "   par[6]  = " << fParams[6] << "; // epsil" << std::endl;
   out << "   par[7]  = " << fParams[7] << "; // stmin" << std::endl;

   out << "   " << GetPointerName() << " = new TGeoMedium(\"" << GetName() << "\", numed," << fMaterial->GetPointerName() << ", par);" << std::endl;
   SetBit(TGeoMedium::kMedSavePrimitive);
}
 TGeoMedium.cxx:1
 TGeoMedium.cxx:2
 TGeoMedium.cxx:3
 TGeoMedium.cxx:4
 TGeoMedium.cxx:5
 TGeoMedium.cxx:6
 TGeoMedium.cxx:7
 TGeoMedium.cxx:8
 TGeoMedium.cxx:9
 TGeoMedium.cxx:10
 TGeoMedium.cxx:11
 TGeoMedium.cxx:12
 TGeoMedium.cxx:13
 TGeoMedium.cxx:14
 TGeoMedium.cxx:15
 TGeoMedium.cxx:16
 TGeoMedium.cxx:17
 TGeoMedium.cxx:18
 TGeoMedium.cxx:19
 TGeoMedium.cxx:20
 TGeoMedium.cxx:21
 TGeoMedium.cxx:22
 TGeoMedium.cxx:23
 TGeoMedium.cxx:24
 TGeoMedium.cxx:25
 TGeoMedium.cxx:26
 TGeoMedium.cxx:27
 TGeoMedium.cxx:28
 TGeoMedium.cxx:29
 TGeoMedium.cxx:30
 TGeoMedium.cxx:31
 TGeoMedium.cxx:32
 TGeoMedium.cxx:33
 TGeoMedium.cxx:34
 TGeoMedium.cxx:35
 TGeoMedium.cxx:36
 TGeoMedium.cxx:37
 TGeoMedium.cxx:38
 TGeoMedium.cxx:39
 TGeoMedium.cxx:40
 TGeoMedium.cxx:41
 TGeoMedium.cxx:42
 TGeoMedium.cxx:43
 TGeoMedium.cxx:44
 TGeoMedium.cxx:45
 TGeoMedium.cxx:46
 TGeoMedium.cxx:47
 TGeoMedium.cxx:48
 TGeoMedium.cxx:49
 TGeoMedium.cxx:50
 TGeoMedium.cxx:51
 TGeoMedium.cxx:52
 TGeoMedium.cxx:53
 TGeoMedium.cxx:54
 TGeoMedium.cxx:55
 TGeoMedium.cxx:56
 TGeoMedium.cxx:57
 TGeoMedium.cxx:58
 TGeoMedium.cxx:59
 TGeoMedium.cxx:60
 TGeoMedium.cxx:61
 TGeoMedium.cxx:62
 TGeoMedium.cxx:63
 TGeoMedium.cxx:64
 TGeoMedium.cxx:65
 TGeoMedium.cxx:66
 TGeoMedium.cxx:67
 TGeoMedium.cxx:68
 TGeoMedium.cxx:69
 TGeoMedium.cxx:70
 TGeoMedium.cxx:71
 TGeoMedium.cxx:72
 TGeoMedium.cxx:73
 TGeoMedium.cxx:74
 TGeoMedium.cxx:75
 TGeoMedium.cxx:76
 TGeoMedium.cxx:77
 TGeoMedium.cxx:78
 TGeoMedium.cxx:79
 TGeoMedium.cxx:80
 TGeoMedium.cxx:81
 TGeoMedium.cxx:82
 TGeoMedium.cxx:83
 TGeoMedium.cxx:84
 TGeoMedium.cxx:85
 TGeoMedium.cxx:86
 TGeoMedium.cxx:87
 TGeoMedium.cxx:88
 TGeoMedium.cxx:89
 TGeoMedium.cxx:90
 TGeoMedium.cxx:91
 TGeoMedium.cxx:92
 TGeoMedium.cxx:93
 TGeoMedium.cxx:94
 TGeoMedium.cxx:95
 TGeoMedium.cxx:96
 TGeoMedium.cxx:97
 TGeoMedium.cxx:98
 TGeoMedium.cxx:99
 TGeoMedium.cxx:100
 TGeoMedium.cxx:101
 TGeoMedium.cxx:102
 TGeoMedium.cxx:103
 TGeoMedium.cxx:104
 TGeoMedium.cxx:105
 TGeoMedium.cxx:106
 TGeoMedium.cxx:107
 TGeoMedium.cxx:108
 TGeoMedium.cxx:109
 TGeoMedium.cxx:110
 TGeoMedium.cxx:111
 TGeoMedium.cxx:112
 TGeoMedium.cxx:113
 TGeoMedium.cxx:114
 TGeoMedium.cxx:115
 TGeoMedium.cxx:116
 TGeoMedium.cxx:117
 TGeoMedium.cxx:118
 TGeoMedium.cxx:119
 TGeoMedium.cxx:120
 TGeoMedium.cxx:121
 TGeoMedium.cxx:122
 TGeoMedium.cxx:123
 TGeoMedium.cxx:124
 TGeoMedium.cxx:125
 TGeoMedium.cxx:126
 TGeoMedium.cxx:127
 TGeoMedium.cxx:128
 TGeoMedium.cxx:129
 TGeoMedium.cxx:130
 TGeoMedium.cxx:131
 TGeoMedium.cxx:132
 TGeoMedium.cxx:133
 TGeoMedium.cxx:134
 TGeoMedium.cxx:135
 TGeoMedium.cxx:136
 TGeoMedium.cxx:137
 TGeoMedium.cxx:138
 TGeoMedium.cxx:139
 TGeoMedium.cxx:140
 TGeoMedium.cxx:141
 TGeoMedium.cxx:142
 TGeoMedium.cxx:143