#include <time.h>
#include <chrono>
#include "ns3/internet-module.h"
#include "ns3/olsr-module.h"

#include "ns3/plc-module.h"
#include "ns3/ghn-plc-module.h"

#define CYKY01      1
#define NAYY150SE   2

using namespace ns3;
using namespace ghn;
using namespace std;

std::string
ConstructResFoldName (int argc, char *argv[]); //funkce pro vytvoření složky results na základě vstupních parametrů, využitá

int
main (int argc, char *argv[]) //vstup parametrů
{
  std::string resDir = ConstructResFoldName (argc, argv); //volání funkce, vytvoří složky pro výsledky na zálkadě vstupních argumentů
  RemoveDirectory (resDir); //
  CreateDirectory (resDir); //vymazání původních výsledků+vytvoření výsledků nových
  //
  // Set random seed value
  //
  typedef std::chrono::high_resolution_clock myclock; //vytvoření vlastního datového typu pro získání přesné synchronizace hodin
  myclock::time_point beginning = myclock::now (); //spuštění hodin
  myclock::duration d = myclock::now () - beginning;
  RngSeedManager::SetSeed (d.count ()); //nastaví počáteční seed pro případné generování pseudonáhodných hodnot

  //
  // Set random seed value
  //
  uint16_t maxCwSize = 50; //maximální velikost okna
  BandPlanType bandplan = GDOTHN_BANDPLAN_25MHZ; //nastavení šířky pásma
  ModulationType modulace = QAM256; //typ modulace
  GhnPlcDllMacProtocol macMode = CSMA_CA; //přístupová metoda

  std::vector<double> vals; //uložení hodnot do vektoru pro jejich logování
  vals.push_back (macMode); // přístupová metoda
  std::string logID = GetLogIdent (vals); //řetězec sloužící pro popis
  //souboru app_data_0_modem_distance_topology_macMode
  cout << "Initialized the constants.." << endl;

  GhnPlcHelper devHelper (bandplan, modulace); //vložení šířky pásma a modulace do devHelperu
  Ptr<const SpectrumModel> sm = devHelper.GetSpectrumModel (); //definice spektrálního modelu,


  Ptr<PLC_Cable> cableNAYY = CreateObject<PLC_NAYY150SE_Cable>(sm);   //PLC_AES4x120_Cable, PLC_NAYY150SE_Cable
  Ptr<PLC_Cable> cableAlfe4x50 = CreateObject<PLC_AlFe4x50_Cable>(sm);
  Ptr<PLC_Cable> cableAlfe4x35 = CreateObject<PLC_AlFe4x35_Cable>(sm);
  Ptr<PLC_Cable> cableAlfe4x25 = CreateObject<PLC_AlFe4x25_Cable>(sm);
  Ptr<PLC_Cable> cableAYKY3x120_70 = CreateObject<PLC_AYKY3x120_70_Cable>(sm);
  Ptr<PLC_Cable> cableAYKY4x50 = CreateObject<PLC_AYKY4x50_Cable>(sm);
  Ptr<PLC_Cable> cableAES4x120_Cable = CreateObject<PLC_AES4x120_Cable>(sm);

  Ptr<PLC_ConstImpedance> vysilac = Create<PLC_ConstImpedance> (sm,PLC_Value(40,0)); //dle zdroje
  Ptr<PLC_ConstImpedance> prijimac = Create<PLC_ConstImpedance> (sm,PLC_Value(100,0)); //dle zdroje
  Ptr<PLC_ConstImpedance> n2impedance = Create<PLC_ConstImpedance> (sm,PLC_Value(300)); //impedance odboček představující vyšší zatížení


Ptr<PLC_Node> n1 = CreateObject<PLC_Node> ();
  n1->SetPosition(600,0,0);
  n1->SetImpedance(vysilac);
  n1->SetName("n1");

  Ptr<PLC_Node> n2 = CreateObject<PLC_Node> ();
  n2->SetPosition(613.6,0,0);
  n2->SetName("n2");

  Ptr<PLC_Node> n3 = CreateObject<PLC_Node> ();
  n3->SetPosition(613.6,12.8,0);
  n3->SetName("n3");

  Ptr<PLC_Node> n4 = CreateObject<PLC_Node> ();
  n4->SetPosition(616.6,15.8,0);
  n4->SetName("n4");

  Ptr<PLC_Node> n5 = CreateObject<PLC_Node> ();
  n5->SetPosition(616.6,23.3,0);
  n5->SetName("n5");

  Ptr<PLC_Node> n6 = CreateObject<PLC_Node> ();
  n6->SetPosition(610.6,23.3,0);
  n6->SetName("n6");

  Ptr<PLC_Node> n7 = CreateObject<PLC_Node> ();
  n7->SetPosition(610.6,30.5,0);
  n7->SetName("n7");

  Ptr<PLC_Node> n7od = CreateObject<PLC_Node> ();
  n7od->SetPosition(616.9,30.5,0);
  n1->SetImpedance(n2impedance);
  n7od->SetName("n7od");

  Ptr<PLC_Node> n8 = CreateObject<PLC_Node> ();
  n8->SetPosition(610.6,96.8,0);
  n8->SetName("n8");

  Ptr<PLC_Node> n9 = CreateObject<PLC_Node> ();
  n9->SetPosition(560.9,96.8,0);
  n9->SetName("n9");

  Ptr<PLC_Node> n10 = CreateObject<PLC_Node> ();
  n10->SetPosition(560.9,94.8,0);
  n10->SetName("n10");

  Ptr<PLC_Node> n11 = CreateObject<PLC_Node> ();
  n11->SetPosition(540,94.8,0);
  n11->SetName("n11");

  Ptr<PLC_Node> n12 = CreateObject<PLC_Node> ();
  n12->SetPosition(538,97.6,0);
  n12->SetName("n12");

  Ptr<PLC_Node> n13 = CreateObject<PLC_Node> ();
  n13->SetPosition(538,111.6,0);
  n13->SetName("n13");

  Ptr<PLC_Node> n14 = CreateObject<PLC_Node> ();
  n14->SetPosition(543,111.6,0);
  n14->SetName("n14");

  Ptr<PLC_Node> n15 = CreateObject<PLC_Node> ();
  n15->SetPosition(543,127.6,0);
  n15->SetName("n15");

  Ptr<PLC_Node> n16 = CreateObject<PLC_Node> ();
  n16->SetPosition(538,127.6,0);
  n16->SetName("n16");

  Ptr<PLC_Node> n17 = CreateObject<PLC_Node> ();
  n17->SetPosition(538,145.2,0);
  n17->SetName("n17");

  Ptr<PLC_Node> n18 = CreateObject<PLC_Node> ();
  n18->SetPosition(538,212.2,0);
  n18->SetName("n18");

  Ptr<PLC_Node> n18od = CreateObject<PLC_Node> ();
  n18od->SetPosition(533,212.2,0);
  n18od->SetImpedance(n2impedance);
  n18od->SetName("n18od");

  Ptr<PLC_Node> n19 = CreateObject<PLC_Node> ();
  n19->SetPosition(538,235.2,0);
  n19->SetName("n19");

  Ptr<PLC_Node> n20 = CreateObject<PLC_Node> ();
  n20->SetPosition(538,255.2,0);
  n20->SetName("n20");

  Ptr<PLC_Node> n201 = CreateObject<PLC_Node> ();
  n201->SetPosition(512,255.2,0);
  n201->SetName("n201");

  Ptr<PLC_Node> n201od = CreateObject<PLC_Node> ();
  n201od->SetPosition(512,203,0);
  n201od->SetImpedance(n2impedance);
  n201od->SetName("n201od");

  Ptr<PLC_Node> n202 = CreateObject<PLC_Node> ();
  n202->SetPosition(470,235.2,0);
  n202->SetName("n202");

  Ptr<PLC_Node> n216 = CreateObject<PLC_Node> ();
  n216->SetPosition(455,235.2,0);
  n216->SetName("n216");

  Ptr<PLC_Node> n216od = CreateObject<PLC_Node> ();
  n216->SetPosition(455,225.2,0);
  n216->SetImpedance(n2impedance);
  n216->SetName("n216od");

  Ptr<PLC_Node> n217 = CreateObject<PLC_Node> ();
  n217->SetPosition(408,235.2,0);
  n217->SetName("n217");

  Ptr<PLC_Node> n217od = CreateObject<PLC_Node> ();
  n217od->SetPosition(413,220,0);
  n217od->SetImpedance(n2impedance);
  n217od->SetName("n217od");

  Ptr<PLC_Node> n218 = CreateObject<PLC_Node> ();
  n218->SetPosition(382,235.2,0);
  n218->SetName("n218");

  Ptr<PLC_Node> n218od = CreateObject<PLC_Node> ();
  n218od->SetPosition(382,234,0);
  n218od->SetImpedance(n2impedance);
  n218od->SetName("n218od");

  Ptr<PLC_Node> n219 = CreateObject<PLC_Node> ();
  n219->SetPosition(352,235.2,0);
  n219->SetName("n219");

  Ptr<PLC_Node> n219od = CreateObject<PLC_Node> ();
  n219od->SetPosition(356,220,0);
  n219od->SetImpedance(n2impedance);
  n219od->SetName("n219od");

  Ptr<PLC_Node> n219od1 = CreateObject<PLC_Node> ();
  n219od1->SetPosition(348,220,0);
  n219od1->SetImpedance(n2impedance);
  n219od1->SetName("n219od1");

  Ptr<PLC_Node> n220 = CreateObject<PLC_Node> ();
  n220->SetPosition(322,235.2,0);
  n220->SetName("n220");

  Ptr<PLC_Node> n220od = CreateObject<PLC_Node> ();
  n220od->SetPosition(318,215,0);
  n220od->SetImpedance(n2impedance);
  n220od->SetName("n220od");

  Ptr<PLC_Node> n220od1 = CreateObject<PLC_Node> ();
  n220od1->SetPosition(326,215,0);
  n220od1->SetImpedance(n2impedance);
  n220od1->SetName("n220od1");

  Ptr<PLC_Node> n221 = CreateObject<PLC_Node> ();
  n221->SetPosition(288,235.2,0);
  n221->SetName("n221");

  Ptr<PLC_Node> n221od = CreateObject<PLC_Node> ();
  n221od->SetPosition(285,225,0);
  n221od->SetImpedance(n2impedance);
  n221od->SetName("n221od");

  Ptr<PLC_Node> n221od1 = CreateObject<PLC_Node> ();
  n221od1->SetPosition(291,225,0);
  n221od1->SetImpedance(n2impedance);
  n221od1->SetName("n221od1");

  Ptr<PLC_Node> n222 = CreateObject<PLC_Node> ();
  n222->SetPosition(258,235.2,0);
  n222->SetName("n222");

  Ptr<PLC_Node> n222od = CreateObject<PLC_Node> ();
  n222od->SetPosition(258,227,0);
  n222od->SetImpedance(prijimac);
  n222od->SetName("n222od");

  Ptr<PLC_Node> n203 = CreateObject<PLC_Node> ();
  n203->SetPosition(470,223,0);
  n203->SetName("n203");

  Ptr<PLC_Node> n203od = CreateObject<PLC_Node> ();
  n203od->SetPosition(471,223,0);
  n203od->SetImpedance(n2impedance);
  n203od->SetName("n203od");

  Ptr<PLC_Node> n204 = CreateObject<PLC_Node> ();
  n204->SetPosition(470,203,0);
  n204->SetName("n204");

  Ptr<PLC_Node> n204od = CreateObject<PLC_Node> ();
  n204od->SetPosition(471,203,0);
  n204od->SetImpedance(n2impedance);
  n204od->SetName("n204od");

  Ptr<PLC_Node> n205 = CreateObject<PLC_Node> ();
  n205->SetPosition(470,192,0);
  n205->SetName("n205");

  Ptr<PLC_Node> n205od = CreateObject<PLC_Node> ();
  n205od->SetPosition(471,192,0);
  n205od->SetImpedance(n2impedance);
  n205od->SetName("n205od");

  Ptr<PLC_Node> n206 = CreateObject<PLC_Node> ();
  n206->SetPosition(470,182,0);
  n206->SetName("n206");

  Ptr<PLC_Node> n206od = CreateObject<PLC_Node> ();
  n206od->SetPosition(471,182,0);
  n206od->SetImpedance(n2impedance);
  n206od->SetName("n206od");

  Ptr<PLC_Node> n207 = CreateObject<PLC_Node> ();
  n207->SetPosition(470,170,0);
  n207->SetName("n207");

  Ptr<PLC_Node> n207od = CreateObject<PLC_Node> ();
  n207od->SetPosition(471,170,0);
  n207od->SetImpedance(n2impedance);
  n207od->SetName("n207od");

  Ptr<PLC_Node> n208 = CreateObject<PLC_Node> ();
  n208->SetPosition(470,164,0);
  n208->SetName("n208");

  Ptr<PLC_Node> n208od = CreateObject<PLC_Node> ();
  n208od->SetPosition(471,164,0);
  n208od->SetImpedance(n2impedance);
  n208od->SetName("n208od");

  Ptr<PLC_Node> n209 = CreateObject<PLC_Node> ();
  n209->SetPosition(456,203,0);
  n209->SetName("n209");

  Ptr<PLC_Node> n209od = CreateObject<PLC_Node> ();
  n209od->SetPosition(455,203,0);
  n209od->SetImpedance(n2impedance);
  n209od->SetName("n209od");

  Ptr<PLC_Node> n210 = CreateObject<PLC_Node> ();
  n210->SetPosition(456,180,0);
  n210->SetName("n210");

  Ptr<PLC_Node> n210od = CreateObject<PLC_Node> ();
  n210od->SetPosition(455,180,0);
  n210od->SetImpedance(n2impedance);
  n210od->SetName("n210od");

  Ptr<PLC_Node> n211 = CreateObject<PLC_Node> ();
  n211->SetPosition(456,164,0);
  n211->SetName("n211");

  Ptr<PLC_Node> n211od = CreateObject<PLC_Node> ();
  n211od->SetPosition(455,164,0);
  n211od->SetImpedance(n2impedance);
  n211od->SetName("n211od");

  Ptr<PLC_Node> n212 = CreateObject<PLC_Node> ();
  n212->SetPosition(456,152,0);
  n212->SetName("n212");

  Ptr<PLC_Node> n212od = CreateObject<PLC_Node> ();
  n212od->SetPosition(455,152,0);
  n212od->SetImpedance(n2impedance);
  n212od->SetName("n212od");

  Ptr<PLC_Node> n213 = CreateObject<PLC_Node> ();
  n213->SetPosition(456,137,0);
  n213->SetName("n213");

  Ptr<PLC_Node> n213od = CreateObject<PLC_Node> ();
  n213od->SetPosition(455,137,0);
  n213od->SetImpedance(n2impedance);
  n213od->SetName("n213od");

  Ptr<PLC_Node> n214 = CreateObject<PLC_Node> ();
  n214->SetPosition(456,127,0);
  n214->SetName("n214");

  Ptr<PLC_Node> n214od = CreateObject<PLC_Node> ();
  n214od->SetPosition(455,127,0);
  n214od->SetImpedance(n2impedance);
  n214od->SetName("n214od");

  Ptr<PLC_Node> n215 = CreateObject<PLC_Node> ();
  n215->SetPosition(456,110,0);
  n215->SetName("n215");

  Ptr<PLC_Node> n215od = CreateObject<PLC_Node> ();
  n215od->SetPosition(455,110,0);
  n215od->SetImpedance(n2impedance);
  n215od->SetName("n215od");

  Ptr<PLC_Node> n21 = CreateObject<PLC_Node> ();
  n21->SetPosition(696,255.2,0);
  n21->SetName("n21");

  Ptr<PLC_Node> n22 = CreateObject<PLC_Node> ();
  n22->SetPosition(696,256.2,0);
  n22->SetName("n22");

  Ptr<PLC_Node> n23 = CreateObject<PLC_Node> ();
  n23->SetPosition(704,261.2,0);
  n23->SetName("n23");

  Ptr<PLC_Node> n24 = CreateObject<PLC_Node> ();
  n24->SetPosition(731,261.2,0);
  n24->SetName("n24");

  Ptr<PLC_Node> n25 = CreateObject<PLC_Node> ();
  n25->SetPosition(739,255.2,0);
  n25->SetName("n25");

  Ptr<PLC_Node> n26 = CreateObject<PLC_Node> ();
  n26->SetPosition(872,255.2,0);
  n26->SetName("n26");

  Ptr<PLC_Node> n26od = CreateObject<PLC_Node> ();
  n26od->SetPosition(872,257.2,0);
  n26od->SetName("n26od");

  Ptr<PLC_Node> n26od1 = CreateObject<PLC_Node> ();     // 5bod
  n26od1->SetPosition(899,257.2,0);
  n26od1->SetImpedance(n2impedance);
  n26od1->SetName("n26od1");

  Ptr<PLC_Node> n27 = CreateObject<PLC_Node> ();        // 3 bod
  n27->SetPosition(946,255.2,0);
  n27->SetName("n27");

  Ptr<PLC_Node> n28 = CreateObject<PLC_Node> ();        //4 bod
  n28->SetPosition(993,255.2,0);
  n28->SetName("n28");

  Ptr<PLC_Node> n29 = CreateObject<PLC_Node> ();
  n29->SetPosition(993,271.2,0);
  n29->SetName("n29");

  Ptr<PLC_Node> n29od = CreateObject<PLC_Node> ();
  n29od->SetPosition(992,271.2,0);
  n29od->SetImpedance(n2impedance);
  n29od->SetName("n29od");

  Ptr<PLC_Node> n30 = CreateObject<PLC_Node> ();
  n30->SetPosition(993,279.2,0);
  n30->SetName("n30");

  Ptr<PLC_Node> n30od = CreateObject<PLC_Node> ();
  n30od->SetPosition(992,279.2,0);
  n30od->SetImpedance(n2impedance);
  n30od->SetName("n30od");

  Ptr<PLC_Node> n31 = CreateObject<PLC_Node> ();
  n31->SetPosition(993,287.2,0);
  n31->SetName("n31");

  Ptr<PLC_Node> n31od = CreateObject<PLC_Node> ();
  n31od->SetPosition(992,287.2,0);
  n31od->SetImpedance(n2impedance);
  n31od->SetName("n31od");

  Ptr<PLC_Node> n32 = CreateObject<PLC_Node> ();
  n32->SetPosition(993,294.2,0);
  n32->SetName("n32");

  Ptr<PLC_Node> n32od = CreateObject<PLC_Node> ();
  n32od->SetPosition(992,294.2,0);
  n31od->SetImpedance(prijimac);
  n32od->SetName("n32od");

  Ptr<PLC_Node> n300 = CreateObject<PLC_Node> ();
  n300->SetPosition(538.1,145.2,0);
  n300->SetName("n300");

  Ptr<PLC_Node> n301 = CreateObject<PLC_Node> ();
  n301->SetPosition(538.1,235.3,0);
  n301->SetName("n301");

  Ptr<PLC_Node> n302 = CreateObject<PLC_Node> ();
  n302->SetPosition(455,235.3,0);
  n302->SetName("n302");

  Ptr<PLC_Node> n303 = CreateObject<PLC_Node> ();
  n303->SetPosition(455,255,0);
  n303->SetName("n303");

  Ptr<PLC_Node> n311 = CreateObject<PLC_Node> ();
  n311->SetPosition(455,380,0);
  n311->SetName("n311");

  Ptr<PLC_Node> n311od = CreateObject<PLC_Node> ();
  n311od->SetPosition(460,380,0);
  n311od->SetImpedance(n2impedance);
  n311od->SetName("n311od");

  Ptr<PLC_Node> n312 = CreateObject<PLC_Node> ();
  n312->SetPosition(455,410,0);
  n312->SetName("n312");

  Ptr<PLC_Node> n312od = CreateObject<PLC_Node> ();
  n312od->SetPosition(465,415,0);
  n312od->SetImpedance(n2impedance);
  n312od->SetName("n312od");

  Ptr<PLC_Node> n312od1 = CreateObject<PLC_Node> ();
  n312od1->SetPosition(465,405,0);
  n312od1->SetImpedance(n2impedance);
  n312od1->SetName("n312od1");


  Ptr<PLC_Node> n313 = CreateObject<PLC_Node> ();
  n313->SetPosition(455,440,0);
  n313->SetName("n313");

  Ptr<PLC_Node> n313od = CreateObject<PLC_Node> ();
  n313od->SetPosition(460,440,0);
  n313od->SetImpedance(n2impedance);
  n313od->SetName("n313od");

  Ptr<PLC_Node> n304 = CreateObject<PLC_Node> (); //  n31od->SetImpedance(n2impedance);
  n304->SetPosition(435,255,0);
  n304->SetName("n304");

  Ptr<PLC_Node> n304od = CreateObject<PLC_Node> ();
  n304od->SetPosition(430,267,0);
  n304od->SetImpedance(n2impedance);
  n304od->SetName("n304od");

  Ptr<PLC_Node> n304od1 = CreateObject<PLC_Node> ();
  n304od1->SetPosition(440,267,0);
  n304od1->SetImpedance(n2impedance);
  n304od1->SetName("n304od1");

  Ptr<PLC_Node> n305 = CreateObject<PLC_Node> ();
  n305->SetPosition(400,255,0);
  n305->SetName("n305");

  Ptr<PLC_Node> n305od = CreateObject<PLC_Node> ();
  n305od->SetPosition(392,259,0);
  n305od->SetImpedance(n2impedance);
  n305od->SetName("n305od");

  Ptr<PLC_Node> n305od1 = CreateObject<PLC_Node> ();
  n305od1->SetPosition(395,258,0);
  n305od1->SetImpedance(n2impedance);
  n305od1->SetName("n305od1");

  Ptr<PLC_Node> n305od2 = CreateObject<PLC_Node> ();
  n305od2->SetPosition(415,260,0);
  n305od2->SetImpedance(n2impedance);
  n305od2->SetName("n305od2");

  Ptr<PLC_Node> n306 = CreateObject<PLC_Node> ();
  n306->SetPosition(378,255,0);
  n306->SetName("n306");

  Ptr<PLC_Node> n306od = CreateObject<PLC_Node> ();
  n306od->SetPosition(365,260,0);
  n306od->SetImpedance(n2impedance);
  n306od->SetName("n306od");

  Ptr<PLC_Node> n307 = CreateObject<PLC_Node> ();
  n307->SetPosition(346,255,0);
  n307->SetName("n307");

  Ptr<PLC_Node> n307od = CreateObject<PLC_Node> ();
  n307od->SetPosition(341,272,0);
  n307od->SetImpedance(n2impedance);
  n307od->SetName("n307od");

  Ptr<PLC_Node> n307od1 = CreateObject<PLC_Node> ();
  n307od1->SetPosition(358,270,0);
  n307od1->SetImpedance(n2impedance);
  n307od1->SetName("n307od1");

  Ptr<PLC_Node> n308 = CreateObject<PLC_Node> ();
  n308->SetPosition(316,255,0);
  n308->SetName("n308");

  Ptr<PLC_Node> n308od = CreateObject<PLC_Node> ();
  n308od->SetPosition(312,272,0);
  n308od->SetImpedance(n2impedance);
  n308od->SetName("n308od");

  Ptr<PLC_Node> n308od1 = CreateObject<PLC_Node> ();
  n308od1->SetPosition(320,272,0);
  n308od1->SetImpedance(n2impedance);
  n308od1->SetName("n308od1");

  Ptr<PLC_Node> n309 = CreateObject<PLC_Node> ();
  n309->SetPosition(290,255,0);
  n309->SetName("n309");

  Ptr<PLC_Node> n309od = CreateObject<PLC_Node> ();
  n309od->SetPosition(285,272,0);
  n309od->SetImpedance(n2impedance);
  n309od->SetName("n309od");

  Ptr<PLC_Node> n309od1 = CreateObject<PLC_Node> ();
  n309od1->SetPosition(295,272,0);
  n309od1->SetImpedance(n2impedance);
  n309od1->SetName("n309od1");

  Ptr<PLC_Node> n310 = CreateObject<PLC_Node> ();
  n310->SetPosition(257,255,0);
  n310->SetName("n310");

  Ptr<PLC_Node> n310od = CreateObject<PLC_Node> ();
  n310od->SetPosition(262,272,0);
  n310od->SetName("n310od");
  n310od->SetImpedance(n2impedance);

PLC_NodeList node_list;
  node_list.push_back(n1);
  node_list.push_back(n2);
  node_list.push_back(n3);
  node_list.push_back(n4);
  node_list.push_back(n5);
  node_list.push_back(n6);
  node_list.push_back(n7);
  node_list.push_back(n7od);
  node_list.push_back(n8);
  node_list.push_back(n9);
  node_list.push_back(n10);
  node_list.push_back(n11);
  node_list.push_back(n12);
  node_list.push_back(n13);
  node_list.push_back(n14);
  node_list.push_back(n15);
  node_list.push_back(n16);
  node_list.push_back(n17);
  node_list.push_back(n18);
  node_list.push_back(n19);
  node_list.push_back(n20);
  node_list.push_back(n21);
  node_list.push_back(n22);
  node_list.push_back(n23);
  node_list.push_back(n24);
  node_list.push_back(n25);
  node_list.push_back(n26);
  node_list.push_back(n26od);
  node_list.push_back(n26od1);
  node_list.push_back(n27);
  node_list.push_back(n28);
  node_list.push_back(n29);
  node_list.push_back(n29od);
  node_list.push_back(n30);
  node_list.push_back(n30od);
  node_list.push_back(n31);
  node_list.push_back(n31od);
  node_list.push_back(n32);
  node_list.push_back(n32od);
  node_list.push_back(n201);
  node_list.push_back(n201od);
  node_list.push_back(n202);
  node_list.push_back(n203);
  node_list.push_back(n203od);
  node_list.push_back(n204);
  node_list.push_back(n204od);
  node_list.push_back(n205);
  node_list.push_back(n205od);
  node_list.push_back(n206);
  node_list.push_back(n206od);
  node_list.push_back(n207);
  node_list.push_back(n207od);
  node_list.push_back(n208);
  node_list.push_back(n208od);
  node_list.push_back(n209);
  node_list.push_back(n209od);
  node_list.push_back(n210);
  node_list.push_back(n210od);
  node_list.push_back(n211);
  node_list.push_back(n211od);
  node_list.push_back(n212);
  node_list.push_back(n212od);
  node_list.push_back(n213);
  node_list.push_back(n213od);
  node_list.push_back(n214);
  node_list.push_back(n214od);
  node_list.push_back(n215);
  node_list.push_back(n215od);
  node_list.push_back(n216);
  node_list.push_back(n216od);
  node_list.push_back(n217);
  node_list.push_back(n217od);
  node_list.push_back(n218);
  node_list.push_back(n218od);
  node_list.push_back(n219);
  node_list.push_back(n219od);
  node_list.push_back(n219od1);
  node_list.push_back(n220);
  node_list.push_back(n220od);
  node_list.push_back(n220od1);
  node_list.push_back(n221);
  node_list.push_back(n221od);
  node_list.push_back(n221od1);
  node_list.push_back(n222);
  node_list.push_back(n222od);
  node_list.push_back(n300);
  node_list.push_back(n301);
  node_list.push_back(n302);
  node_list.push_back(n18od);
  node_list.push_back(n303);
  node_list.push_back(n304);
  node_list.push_back(n304od);
  node_list.push_back(n304od1);
  node_list.push_back(n305);
  node_list.push_back(n305od);
  node_list.push_back(n305od1);
  node_list.push_back(n305od2);
  node_list.push_back(n306);
  node_list.push_back(n306od);
  node_list.push_back(n307);
  node_list.push_back(n307od);
  node_list.push_back(n307od1);
  node_list.push_back(n308);
  node_list.push_back(n308od);
  node_list.push_back(n308od1);
  node_list.push_back(n309);
  node_list.push_back(n309od);
  node_list.push_back(n309od1);
  node_list.push_back(n310);
  node_list.push_back(n310od);
  node_list.push_back(n311);
  node_list.push_back(n311od);
  node_list.push_back(n312);
  node_list.push_back(n312od);
  node_list.push_back(n312od1);
  node_list.push_back(n313);
  node_list.push_back(n313od);






  CreateObject<PLC_Line> (cableNAYY, n1, n2);
  CreateObject<PLC_Line> (cableNAYY, n2, n3);
  CreateObject<PLC_Line> (cableNAYY, n3, n4);
  CreateObject<PLC_Line> (cableNAYY, n4, n5);
  CreateObject<PLC_Line> (cableNAYY, n5, n6);
  CreateObject<PLC_Line> (cableNAYY, n6, n7);
  CreateObject<PLC_Line> (cableNAYY, n7, n7od);
  CreateObject<PLC_Line> (cableNAYY, n7, n8);
  CreateObject<PLC_Line> (cableNAYY, n8, n9);
  CreateObject<PLC_Line> (cableNAYY, n9, n10);
  CreateObject<PLC_Line> (cableNAYY, n10, n11);
  CreateObject<PLC_Line> (cableNAYY, n11, n12);
  CreateObject<PLC_Line> (cableNAYY, n12, n13);
  CreateObject<PLC_Line> (cableNAYY, n13, n14);
  CreateObject<PLC_Line> (cableNAYY, n14, n15);
  CreateObject<PLC_Line> (cableNAYY, n15, n16);
  CreateObject<PLC_Line> (cableNAYY, n16, n17);
  CreateObject<PLC_Line> (cableAlfe4x50, n17, n18);
  CreateObject<PLC_Line> (cableAlfe4x50, n18, n18od);
  CreateObject<PLC_Line> (cableAlfe4x50, n18, n19);
  CreateObject<PLC_Line> (cableAYKY3x120_70, n19, n20);
  CreateObject<PLC_Line> (cableAYKY3x120_70, n20, n21);
  CreateObject<PLC_Line> (cableAlfe4x50, n19, n201);
  CreateObject<PLC_Line> (cableAlfe4x50, n201, n201od);
  CreateObject<PLC_Line> (cableAlfe4x50, n201, n202);
  CreateObject<PLC_Line> (cableAlfe4x50, n202, n203);
  CreateObject<PLC_Line> (cableAlfe4x50, n202, n216);
  CreateObject<PLC_Line> (cableAlfe4x50, n216, n216od);
  CreateObject<PLC_Line> (cableAlfe4x50, n216, n217);
  CreateObject<PLC_Line> (cableAlfe4x50, n217, n217od);
  CreateObject<PLC_Line> (cableAlfe4x50, n217, n218);
  CreateObject<PLC_Line> (cableAlfe4x50, n218, n218od);
  CreateObject<PLC_Line> (cableAlfe4x50, n218, n219);
  CreateObject<PLC_Line> (cableAlfe4x50, n219, n219od);
  CreateObject<PLC_Line> (cableAlfe4x50, n219, n219od1);
  CreateObject<PLC_Line> (cableAlfe4x50, n219, n220);
  CreateObject<PLC_Line> (cableAlfe4x50, n220, n220od);
  CreateObject<PLC_Line> (cableAlfe4x50, n220, n220od1);
  CreateObject<PLC_Line> (cableAlfe4x50, n220, n221);
  CreateObject<PLC_Line> (cableAlfe4x50, n221, n221od);
  CreateObject<PLC_Line> (cableAlfe4x50, n221, n221od1);
  CreateObject<PLC_Line> (cableAlfe4x50, n221, n222);
  CreateObject<PLC_Line> (cableAlfe4x50, n222, n222od);
  CreateObject<PLC_Line> (cableAlfe4x50, n203, n203od);
  CreateObject<PLC_Line> (cableAlfe4x50, n203, n204);
  CreateObject<PLC_Line> (cableAlfe4x50, n204, n204od);
  CreateObject<PLC_Line> (cableAlfe4x50, n204, n205);
  CreateObject<PLC_Line> (cableAlfe4x50, n205, n205od);
  CreateObject<PLC_Line> (cableAlfe4x50, n205, n206);
  CreateObject<PLC_Line> (cableAlfe4x50, n206, n206od);
  CreateObject<PLC_Line> (cableAlfe4x50, n206, n207);
  CreateObject<PLC_Line> (cableAlfe4x50, n207, n207od);
  CreateObject<PLC_Line> (cableAlfe4x50, n207, n208);
  CreateObject<PLC_Line> (cableAlfe4x50, n208, n208od);
  CreateObject<PLC_Line> (cableAlfe4x50, n203, n209);
  CreateObject<PLC_Line> (cableAlfe4x50, n209, n209od);
  CreateObject<PLC_Line> (cableAlfe4x50, n209, n210);
  CreateObject<PLC_Line> (cableAlfe4x50, n210, n210od);
  CreateObject<PLC_Line> (cableAlfe4x50, n210, n211);
  CreateObject<PLC_Line> (cableAlfe4x50, n211, n211od);
  CreateObject<PLC_Line> (cableAlfe4x50, n211, n212);
  CreateObject<PLC_Line> (cableAlfe4x50, n212, n212od);
  CreateObject<PLC_Line> (cableAlfe4x50, n212, n213);
  CreateObject<PLC_Line> (cableAlfe4x50, n213, n213od);
  CreateObject<PLC_Line> (cableAlfe4x50, n213, n214);
  CreateObject<PLC_Line> (cableAlfe4x50, n214, n214od);
  CreateObject<PLC_Line> (cableAlfe4x50, n214, n215);
  CreateObject<PLC_Line> (cableAlfe4x50, n215, n215od);
  CreateObject<PLC_Line> (cableAYKY3x120_70, n21, n22);
  CreateObject<PLC_Line> (cableNAYY, n22, n23);
  CreateObject<PLC_Line> (cableNAYY, n23, n24);
  CreateObject<PLC_Line> (cableNAYY, n24, n25);
  CreateObject<PLC_Line> (cableNAYY, n25, n26);
  CreateObject<PLC_Line> (cableNAYY, n26, n26od);
  CreateObject<PLC_Line> (cableAYKY4x50, n26od, n26od1);
  CreateObject<PLC_Line> (cableAYKY4x50, n26, n27);
  CreateObject<PLC_Line> (cableAlfe4x35, n27, n28);
  CreateObject<PLC_Line> (cableAlfe4x25, n28, n29);
  CreateObject<PLC_Line> (cableAlfe4x25, n29, n29od);
  CreateObject<PLC_Line> (cableAlfe4x25, n29, n30);
  CreateObject<PLC_Line> (cableAlfe4x25, n30, n30od);
  CreateObject<PLC_Line> (cableAlfe4x25, n30, n31);
  CreateObject<PLC_Line> (cableAlfe4x25, n31, n31od);
  CreateObject<PLC_Line> (cableAlfe4x25, n31, n32);
  CreateObject<PLC_Line> (cableAlfe4x25, n32, n32od);
  CreateObject<PLC_Line> (cableAES4x120_Cable, n17, n300);
  CreateObject<PLC_Line> (cableAES4x120_Cable, n300, n301);
  CreateObject<PLC_Line> (cableAES4x120_Cable, n301, n302);
  CreateObject<PLC_Line> (cableAES4x120_Cable, n302, n303);
  CreateObject<PLC_Line> (cableAlfe4x50, n303, n304);
  CreateObject<PLC_Line> (cableNAYY, n303, n311);
  CreateObject<PLC_Line> (cableNAYY, n311, n311od);
  CreateObject<PLC_Line> (cableNAYY, n311, n312);
  CreateObject<PLC_Line> (cableNAYY, n312, n313);
  CreateObject<PLC_Line> (cableNAYY, n312, n312od);
  CreateObject<PLC_Line> (cableNAYY, n312, n312od1);
  CreateObject<PLC_Line> (cableNAYY, n313, n313od);
  CreateObject<PLC_Line> (cableAlfe4x50, n304, n305);
  CreateObject<PLC_Line> (cableAlfe4x50, n304, n304od);
  CreateObject<PLC_Line> (cableAlfe4x50, n304, n304od1);
  CreateObject<PLC_Line> (cableAlfe4x50, n305, n306);
  CreateObject<PLC_Line> (cableAlfe4x50, n305, n305od);
  CreateObject<PLC_Line> (cableAlfe4x50, n305, n305od1);
  CreateObject<PLC_Line> (cableAlfe4x50, n305, n305od2);
  CreateObject<PLC_Line> (cableAlfe4x50, n306, n307);
  CreateObject<PLC_Line> (cableAlfe4x50, n306, n306od);
  CreateObject<PLC_Line> (cableAlfe4x50, n307, n308);
  CreateObject<PLC_Line> (cableAlfe4x50, n307, n307od);
  CreateObject<PLC_Line> (cableAlfe4x50, n307, n307od1);
  CreateObject<PLC_Line> (cableAlfe4x50, n308, n309);
  CreateObject<PLC_Line> (cableAlfe4x50, n308, n308od);
  CreateObject<PLC_Line> (cableAlfe4x50, n308, n308od1);
  CreateObject<PLC_Line> (cableAlfe4x50, n309, n310);
  CreateObject<PLC_Line> (cableAlfe4x50, n309, n309od);
  CreateObject<PLC_Line> (cableAlfe4x50, n309, n309od1);
  CreateObject<PLC_Line> (cableAlfe4x50, n310, n310od);


  cout << "Created topology.." << endl;

  //
  // Zadání šumu na pozadí=BestCase.../WorstCase... a získání jeho PSD
  //

  //Ptr<SpectrumValue> noiseFloor = CreateWorstCaseBgNoise(sm)->GetNoisePsd (); //barevny sum na pozadi, promenny s frekvenci
  PLC_ColoredNoiseHrasnica residentalNoise(-35.0,35.0,3.6,sm); //parametry residencniho ruseni
  Ptr<SpectrumValue> noiseFloor = residentalNoise.GetNoisePsd();

  std::ofstream outputrxPsd;
  outputrxPsd.open ("noise.txt");
  outputrxPsd << *noiseFloor <<endl;
  outputrxPsd.close();

  outputrxPsd.open ("frekvence.txt");
  Bands::const_iterator it;
  	for (it = sm->Begin(); it != sm->End(); it++) {
  		double f = it->fc;
  		outputrxPsd << f <<endl;
  	}
  outputrxPsd.close();

  //Ptr<SpectrumValue> noiseFloor= Create<SpectrumValue> (sm);
  //*(noiseFloor) = 1e-12; //-90 dBm/Hz
  //*(noiseFloor) = 1e-10; //-70 dBm/Hz
  //*(noiseFloor) = 1e-13; //bily sum na pozadi, konstantni s frekvenci
  //uint16_t noiseType = 3; // 0 - (-60 dBm/Hz); 1 - (-70 dBm/Hz) ; 2def - (-80 dBm/Hz) ; 3 - (-90 dBm/Hz) ; 4 - (-100 dBm/Hz);

 /* switch (noiseType){
      case 0:
    	  *(noiseFloor) = 1e-9; //-60 dBm/Hz
        break;

      case 1:
    	  *(noiseFloor) = 1e-10; //-70 dBm/Hz
        break;

      case 2:
    	  *(noiseFloor) = 1e-11; //-80 dBm/Hz
    	break;

      case 3:
    	  *(noiseFloor) = 1e-12; //-90 dBm/Hz
    	break;

      case 4:
    	  *(noiseFloor) = 1e-14; //-100 dBm/Hz
    	break;

      default:
    	  *(noiseFloor) = 1e-11; //-80 dBm/Hz
  }*/

  //
  // Vytvoření kanálu na základě SM
  //
  PLC_ChannelHelper channelHelper (sm);
  channelHelper.Install (node_list); //Urychlení nastavení pomocí instalace channelHelperu
  cout << "Created channel.." << endl;

  Ptr<GhnPlcStats> ncStats = CreateObject<GhnPlcStats> (); //objekt pro statistiky

  Ptr<PLC_Channel> channel;
  channel = channelHelper.GetChannel();

  //
  // Získání CTF z uzlu x do y, pro získání třeba odkomentoval.
  //
/*
  Ptr<PLC_TxInterface> txIfn1 = CreateObject<PLC_TxInterface> (n1, sm);
  Ptr<PLC_RxInterface> rxIfn2 = CreateObject<PLC_RxInterface> (n2, sm);

  txIfn1->SetTxIfIdx(1);
  rxIfn2->SetRxIfIdx(1);

  //přidání rozhraní do kanálu pro výpočet CTF
  channel->AddTxInterface(txIfn1);
  channel->AddRxInterface(rxIfn2);

  //inicializace a výpočet CTF
  channel->InitTransmissionChannels();
  channel->CalcTransmissionChannels();

  string nazev = node_list.at(0)->GetName() +"-to-"+ node_list.at(1)->GetName();
  PLC_OutputHelper outputHelper;

  Ptr<PLC_TransferBase>ctv=channel->GetChannelTransferData(1,1);

  nazev = node_list.at(0)->GetName() +"-to-"+ node_list.at(1)->GetName();
  outputHelper.PrintBode(nazev, ctv, sm);

*/


  //
  // Create communication devices
  //
  devHelper.SetNodeList (node_list); //Vytvoření seznamu do devhelperu
  if (macMode == CSMA_CD)
    {
      devHelper.DefinePhyType (GhnPlcPhyPmdFullD::GetTypeId ());
      devHelper.DefineMacType (GhnPlcDllMacCsmaCd::GetTypeId ());
    }
  devHelper.SetNoiseFloor (noiseFloor); //volba šumu
  devHelper.SetChannel (channelHelper.GetChannel ()); //volba kanálu
  //devHelper.SetTxImpedance (CreateObject<PLC_ConstImpedance> (sm, PLC_Value (50, 0))); //nastavení impedance vysílače, _K 50
  //devHelper.SetRxImpedance (CreateObject<PLC_ConstImpedance> (sm, PLC_Value (100, 0))); //nastavení impedance přijímače _K 200000
  devHelper.SetGhnPlcStats (ncStats); //statistiky pro GhnPLC
  devHelper.DefineLlcFlowType (GhnPlcLlcCodedFlow::GetTypeId ()); //LLC model
  devHelper.DefineBitLoadingType (NcBlVarBatMap::GetTypeId ()); //
  devHelper.SetResDirectory (resDir); //nastavení složky pro výsledky
  devHelper.SetMaxCwSize (maxCwSize); //nastavení max velikosti CW
  devHelper.Setup (); //Získáná kapacity mezi uzly capacity.txt
  cout << "Konec" << endl;


}

std::string
ConstructResFoldName (int argc, char *argv[])
{
  std::stringstream ss;
  std::string path = argv[0]; // get path from argument 0
  path = path.substr (0, path.rfind ("/") + 1);
  ss << path << "Results";

    for (uint16_t i = 1; i < argc; i++)
      {
        ss << "_" << argv[i];
      }
  ss << "/";
  return ss.str ();
}


