
#include <iostream>
#include <fstream>

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/object-factory.h"
#include "ns3/applications-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/onoff-application.h"

#include "ns3/xgpon-helper.h"
#include "ns3/xgpon-config-db.h"
#include "ns3/xgpon-channel.h"
#include "ns3/xgpon-onu-net-device.h"
#include "ns3/xgpon-olt-net-device.h"
#include "ns3/xgpon-module.h"

#include "ns3/netanim-module.h"

#include "ns3/stats-module.h"


#define APP_START 0
#define APP_STOP 3
#define SIM_STOP 15

#define ONU_NUM 3

using namespace ns3;



NS_LOG_COMPONENT_DEFINE ("Bachelor");

//Vypis do konzole
void
DeviceStatisticsTrace (const XgponNetDeviceStatistics& stat)
{
  static uint64_t time2print = 1000000000;    //1,000,000,000 nanosekund za sekundu.

  if(stat.m_currentTime > time2print)
  {
    std::cout << (stat.m_currentTime / 1000000000L) << " seconds have been simulated.";
    std::cout << "   DS-BYTES: " << stat.m_passToXgponBytes;
    std::cout << ";   US-BYTES: " << stat.m_rxFromXgponBytes;
    std::cout << ";   FROM-CN-DS-BYTES: " << stat.m_rxFromUpperLayerBytes;
    std::cout << ";   DROPPED-DS-BYTES: " << stat.m_overallQueueDropBytes;
    std::cout << std::endl;

    time2print += 1000000000;
  }

}


int
main (int argc, char *argv[])
{

  uint32_t appStart=5;
  uint32_t appStop=5500;

  //Definice maximalni velikosti paketu
  Config::SetDefault("ns3::TcpSocket::SegmentSize", UintegerValue (1500));

  //Nastaveni vypisu do konzole Udp paketu
  LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
  LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);

  Packet::EnablePrinting ();


  //Tvorba OLT, ONU
  NodeContainer oltNode, onuNodes;
  uint16_t nOnus = ONU_NUM;  //Pocet ONU za OLT
  oltNode.Create (1);
  onuNodes.Create (nOnus);

  //Prirazeni do kontejneru xgponNodes
  NodeContainer xgponNodes;
  xgponNodes.Add(oltNode.Get(0));
  for(int i=0; i<nOnus; i++)
  {
	  xgponNodes.Add (onuNodes.Get(i));
  	  }



  //	XgponHelper
  XgponHelper xgponHelper;
  XgponConfigDb& xgponConfigDb = xgponHelper.GetConfigDb ( );

  xgponConfigDb.SetOltNetmaskLen (16);
  xgponConfigDb.SetOnuNetmaskLen (24);
  xgponConfigDb.SetIpAddressFirstByteForXgpon (10);
  xgponConfigDb.SetIpAddressFirstByteForOnus (172);

  xgponHelper.InitializeObjectFactories ( );

  //0: olt; i (>0): onu
  NetDeviceContainer xgponDevices = xgponHelper.Install (xgponNodes);

  //Vytvoreni dalsich uzlu
  NodeContainer clientNodes, serverNodes, outNode1,TorrNode;
  clientNodes.Create (nOnus);
  serverNodes.Create (nOnus);
  outNode1.Create(nOnus);
  TorrNode.Create(1);


  //Nastaveni P2P linek
  PointToPointHelper pointToPoint;
  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("100Mbps"));
  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

  //Vytvoreni dalsich kontejneru
  NetDeviceContainer p2pCDevices[nOnus];
  NetDeviceContainer p2pSDevices[nOnus];
  NetDeviceContainer p2pOutDev1[nOnus];
  NetDeviceContainer p2pTorrDev[nOnus];
  NodeContainer p2pCNodes[nOnus];
  NodeContainer p2pSNodes[nOnus];
  NodeContainer p2pOutNodes[nOnus];
  NodeContainer p2pTorrNodes[nOnus];
  Ipv4InterfaceContainer p2pCInterfaces[nOnus];
  Ipv4InterfaceContainer p2pSInterfaces[nOnus];

  //Tvorba P2P linek mezi OLT a serverovou casti, onu a klientskou casti
  for(int i=0; i<(nOnus); i++)
  {
    p2pSNodes[i].Add(serverNodes.Get(i));
    p2pSNodes[i].Add(oltNode.Get(0));
    p2pSDevices[i] = pointToPoint.Install (p2pSNodes[i]);

    p2pCNodes[i].Add(clientNodes.Get(i));
    p2pCNodes[i].Add(onuNodes.Get(i));
    p2pCDevices[i] = pointToPoint.Install (p2pCNodes[i]);
  }

  //Tvorba linek pro vnejsi cast
  for(int i=0; i<(nOnus); i++)
  {
  p2pOutNodes[i].Add(serverNodes.Get(2));
  p2pOutNodes[i].Add(outNode1.Get(i));
  p2pOutDev1[i] = pointToPoint.Install (p2pOutNodes[i]);
  }
  //Linka mezi TorrNode a R
  p2pTorrNodes[0].Add(serverNodes.Get(2));
  p2pTorrNodes[0].Add(TorrNode.Get(0));
  p2pTorrDev[0] = pointToPoint.Install (p2pTorrNodes[0]);

  //Instalace internet protokolu
  InternetStackHelper stack;
  stack.Install (xgponNodes);
  stack.Install (serverNodes);
  stack.Install (clientNodes);
  stack.Install (outNode1);
  stack.Install (TorrNode);


  //Prirazeni OLT a ONU IP adres
  Ipv4AddressHelper addressHelper;
  Ptr<XgponOltNetDevice> tmpDevice = DynamicCast<XgponOltNetDevice, NetDevice> (xgponDevices.Get(0));
  std::string xgponIpbase = xgponHelper.GetXgponIpAddressBase ( );
  std::string xgponNetmask = xgponHelper.GetOltAddressNetmask();
  addressHelper.SetBase (xgponIpbase.c_str(), xgponNetmask.c_str());

  Ipv4InterfaceContainer xgponInterfaces = addressHelper.Assign (xgponDevices);
  for(int i=0; i<(nOnus+1);i++)
  {
    Ipv4Address addr = xgponInterfaces.GetAddress(i);
    Ptr<XgponNetDevice> tmpDevice = DynamicCast<XgponNetDevice, NetDevice> (xgponDevices.Get(i));
    tmpDevice->SetAddress (addr);

    if(i==0) std::cout << "OLT IP Address: ";
    else std::cout << "ONU " << (i-1) <<" IP Address: ";
    addr.Print(std::cout);
    std::cout << std::endl;
  }

  //Vypis
  for(int i=0; i<nOnus; i++)
  {
    Ipv4Address addr;

    std::string clientIpbase = xgponHelper.GetIpAddressBase (160, i, 24);
    std::string clientNetmask = xgponHelper.GetIpAddressNetmask (24);
    addressHelper.SetBase (clientIpbase.c_str(), clientNetmask.c_str());

    p2pCInterfaces[i] = addressHelper.Assign (p2pCDevices[i]);

    addr = p2pCInterfaces[i].GetAddress(0);
    std::cout << "Client " << i <<" IP Address: ";
    addr.Print(std::cout);
    std::cout << std::endl;

    addr = p2pCInterfaces[i].GetAddress(1);
    std::cout << "Corresponding IP Address at OLT: ";
    addr.Print(std::cout);
    std::cout << std::endl;




    Ptr<XgponOnuNetDevice> tmpDevice = DynamicCast<XgponOnuNetDevice, NetDevice> (xgponDevices.Get(i+1));
    std::string onuIpbase = xgponHelper.GetOnuIpAddressBase (tmpDevice);
    std::string onuNetmask = xgponHelper.GetOnuAddressNetmask();
    addressHelper.SetBase (onuIpbase.c_str(), onuNetmask.c_str());

    p2pSInterfaces[i] = addressHelper.Assign (p2pSDevices[i]);

    addr = p2pSInterfaces[i].GetAddress(0);
    std::cout << "Server " << i <<" IP Address: ";
    addr.Print(std::cout);
    std::cout << std::endl;

    addr = p2pSInterfaces[i].GetAddress(1);
    std::cout << "IP Address at the Corresponding ONU: ";
    addr.Print(std::cout);
    std::cout << std::endl;
  }

  //Tvorba spojeni uvnitr XG-PON modulu - optika
  for(int i=0; i<nOnus; i++)
  {
    Ptr<XgponOltNetDevice> oltDevice = DynamicCast<XgponOltNetDevice, NetDevice> (xgponDevices.Get(0));
    Ptr<XgponOnuNetDevice> onuDevice = DynamicCast<XgponOnuNetDevice, NetDevice> (xgponDevices.Get(i+1));
    xgponHelper.AddOmciConnectionsForOnu (onuDevice, oltDevice);
  }


  for(int i=0; i<nOnus; i++)
  {
    Address addr = p2pSInterfaces[i].GetAddress(0);

    Ptr<XgponOltNetDevice> oltDevice = DynamicCast<XgponOltNetDevice, NetDevice> (xgponDevices.Get(0));
    Ptr<XgponOnuNetDevice> onuDevice = DynamicCast<XgponOnuNetDevice, NetDevice> (xgponDevices.Get(i+1));

    uint16_t allocId = xgponHelper.AddOneTcontForOnu (onuDevice, oltDevice);
    uint16_t upPortId = xgponHelper.AddOneUpstreamConnectionForOnu (onuDevice, oltDevice, allocId, addr);
    uint16_t downPortId = xgponHelper.AddOneDownstreamConnectionForOnu (onuDevice, oltDevice, addr);

    std::cout << "ONU-ID = "<<onuDevice->GetOnuId() << ";   ALLOC-ID = " << allocId << ";   UP-PORT-ID = " << upPortId << ";   DOWN-PORT-ID = " << downPortId << std::endl;

  }

  //Definice adres pro vnejsi cast topologie, prirazeni
  Ipv4AddressHelper outAddr1;
  outAddr1.SetBase("100.0.0.0","255.255.255.0");

  Ipv4AddressHelper outAddr2;
  outAddr2.SetBase("110.0.0.0","255.255.255.0");

  Ipv4AddressHelper outAddr3;
  outAddr3.SetBase("120.0.0.0","255.255.255.0");

  Ipv4AddressHelper TorrAddr;
  TorrAddr.SetBase("55.55.55.0","255.255.255.0");


  Ipv4InterfaceContainer outInt1[nOnus];

  outInt1[0]= outAddr1.Assign(p2pOutDev1[0]);
  outInt1[1]= outAddr2.Assign(p2pOutDev1[1]);
  outInt1[2]= outAddr3.Assign(p2pOutDev1[2]);

  Ipv4InterfaceContainer TorrInt[nOnus];
  TorrInt[0]= TorrAddr.Assign(p2pTorrDev[0]);




  //---------------------------------------http-----------------------------//

  uint16_t serverPort=80;
  uint16_t httpStart=0;
  uint16_t httpStop=3;

  //Sink na serveru pro web komunikaci

  ApplicationContainer httpSinkApp;

  PacketSinkHelper httpSink ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (p2pSInterfaces[1].GetAddress(0)),serverPort));
  std::cout << "Packet sink for http at address:"<< p2pSInterfaces[1].GetAddress(0) << ", port number : "<< serverPort <<std::endl;

  httpSinkApp.Add(httpSink.Install(serverNodes.Get(1)));

  httpSinkApp.Start (Seconds (httpStart));
  httpSinkApp.Stop (Seconds (httpStop));

  //Komunikace na web TCP

  ApplicationContainer httpApp;

  OnOffHelper httpOnOff ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (p2pSInterfaces[1].GetAddress(0)),serverPort));
  std::cout << "OnOff http to server at address" << ": "<< p2pSInterfaces[1].GetAddress(0) << "."<< std::endl;


  httpOnOff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0.02]"));
  httpOnOff.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0.15]"));
  httpOnOff.SetAttribute("DataRate", DataRateValue(DataRate("3Mb/s")));
  httpOnOff.SetAttribute("PacketSize", UintegerValue(1400));
  httpOnOff.SetAttribute("MaxBytes", UintegerValue(0));

  httpApp.Add(httpOnOff.Install(clientNodes.Get(0)));

  httpApp.Start (Seconds (httpStart));
  httpApp.Stop (Seconds (httpStop));

  //---------------------------------------http---end--------------------------//

  //---------------------------------------PPV-----------------------------//

  // TCP zdroj+sink PPV login

  ApplicationContainer PpvVodLoginSink;


    PacketSinkHelper ppvLogin ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (p2pSInterfaces[0].GetAddress(0)),serverPort));
    std::cout << "Packet sink for PPV login at address:"<< p2pSInterfaces[0].GetAddress(0) << ", port number : "<< serverPort <<std::endl;
    PpvVodLoginSink.Add(ppvLogin.Install(serverNodes.Get(0)));

    PpvVodLoginSink.Start (Seconds (4));
    PpvVodLoginSink.Stop (Seconds (7)); //Cas 7s pro platnost i v dobe VoD simulace

   ApplicationContainer PPVApp;

    OnOffHelper PPVOnOff ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (p2pSInterfaces[0].GetAddress(0)),serverPort));
    std::cout << "OnOff PPV to server at address" << ": "<< p2pSInterfaces[0].GetAddress(0) << "."<< std::endl;

    PPVOnOff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0.02]"));
    PPVOnOff.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0.05]"));
    PPVOnOff.SetAttribute("DataRate", DataRateValue(DataRate("2Mb/s")));
    PPVOnOff.SetAttribute("PacketSize", UintegerValue(1024));
    PPVOnOff.SetAttribute("MaxBytes", UintegerValue(0));

    PPVApp.Add(PPVOnOff.Install(clientNodes.Get(0)));

    PPVApp.Start (Seconds (4));
    PPVApp.Stop (Seconds (4.5));

  //PPV stream TV server -> client1

  uint16_t ppvPort=6970;
  ApplicationContainer ppvApps;
  OnOffHelper onOff ("ns3::UdpSocketFactory",InetSocketAddress(Ipv4Address (p2pCInterfaces[0].GetAddress(0)),ppvPort));
  std::cout << "OnOff on server at address" << ": "<< p2pSInterfaces[0].GetAddress(0) << "."<< std::endl;

  onOff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=1000]"));
  onOff.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
  onOff.SetAttribute("DataRate", DataRateValue(DataRate("10Mb/s")));
  onOff.SetAttribute("PacketSize", UintegerValue(1024));
  onOff.SetAttribute("MaxBytes", UintegerValue(0));

  ppvApps.Add(onOff.Install(serverNodes.Get(0)));

  ppvApps.Start (Seconds (appStart));
  ppvApps.Stop (MilliSeconds (appStop));


  //Sink na klientu  pro PPV
  ApplicationContainer sinkApp;

  PacketSinkHelper packetSink ("ns3::UdpSocketFactory",InetSocketAddress(Ipv4Address (p2pCInterfaces[0].GetAddress(0)),ppvPort));
  std::cout << "Packet sink at client at address" << ": "<< p2pCInterfaces[0].GetAddress(0) << ", port number : "<< 6970 <<std::endl;
  sinkApp.Add(packetSink.Install(clientNodes.Get(0)));

  sinkApp.Start (Seconds (appStart));
  sinkApp.Stop (Seconds (appStop-5494));
  //---------------------------------------PPV---end--------------------------//

  //---------------------------------------VoD-----------------------------//
  //	Vyber z filmoteky


   //TCP zdroj VoD login
  ApplicationContainer VoDApp;

   OnOffHelper VoDOnOff ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (p2pSInterfaces[0].GetAddress(0)),serverPort));
   std::cout << "OnOff VoD to server at address" << ": "<< p2pSInterfaces[0].GetAddress(0) << "."<< std::endl;

   VoDOnOff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0.02]"));
   VoDOnOff.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0.02]"));
   VoDOnOff.SetAttribute("DataRate", DataRateValue(DataRate("150kb/s")));
   VoDOnOff.SetAttribute("PacketSize", UintegerValue(512));
   VoDOnOff.SetAttribute("MaxBytes", UintegerValue(0));

   VoDApp.Add(VoDOnOff.Install(clientNodes.Get(1)));

   VoDApp.Start (Seconds (6));
   VoDApp.Stop (Seconds (6.2));


  //Sink na klientu pro VoD
  uint32_t VoDstart = 7;
  uint32_t VoDstop = 8;

  ApplicationContainer sinkVoD;

  PacketSinkHelper packetSinkVoD ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (p2pCInterfaces[1].GetAddress(0)),6000));
  std::cout << "Packet sink for VoD at client at address" << ": "<< p2pCInterfaces[1].GetAddress(0) << ", port number : "<< 6000 <<std::endl;
  sinkVoD.Add(packetSinkVoD.Install(clientNodes.Get(1)));

  sinkVoD.Start (Seconds (VoDstart-1));
  sinkVoD.Stop (Seconds (VoDstop+1));

  //Sink na TVserveru pro VoD - Udp


  ApplicationContainer sinkTV;

  PacketSinkHelper packetSinkVoDTV ("ns3::UdpSocketFactory",InetSocketAddress(Ipv4Address (p2pSInterfaces[0].GetAddress(0)),554));
  sinkTV.Add(packetSinkVoDTV.Install(serverNodes.Get(0)));

  sinkTV.Start (Seconds (VoDstart-1));
  sinkTV.Stop (Seconds (VoDstop+1));

  //VoD ovladani

  UdpEchoClientHelper logVoD (p2pSInterfaces[0].GetAddress(0), 554);
  logVoD.SetAttribute ("MaxPackets", UintegerValue (2));//50
  logVoD.SetAttribute ("Interval", TimeValue (Seconds (0.192)));
  logVoD.SetAttribute ("PacketSize", UintegerValue (300));

  ApplicationContainer VoDlogApp = logVoD.Install (clientNodes.Get (1));
  VoDlogApp.Start (Seconds (6.423));//VoDstart+0.1
  VoDlogApp.Stop (Seconds (7.5));//VoDstop-0.2

  UdpEchoClientHelper log2VoD (p2pSInterfaces[0].GetAddress(0), 554);
    log2VoD.SetAttribute ("MaxPackets", UintegerValue (2));//50
    log2VoD.SetAttribute ("Interval", TimeValue (Seconds (0.192)));
    log2VoD.SetAttribute ("PacketSize", UintegerValue (300));

    ApplicationContainer VoDlog2App = log2VoD.Install (clientNodes.Get (1));
    VoDlog2App.Start (Seconds (6.824));//VoDstart+0.1
    VoDlog2App.Stop (Seconds (7.5));//VoDstop-0.2

  //VoD stream

  ApplicationContainer VoDstreamApp;
  OnOffHelper onOffVoD ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (p2pCInterfaces[1].GetAddress(0)), 6000));
  std::cout << "OnOff VoD stream to address" << ": "<< p2pCInterfaces[1].GetAddress(0) << "."<< std::endl;

  onOffVoD.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0.189]"));
  onOffVoD.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0.211]"));
  onOffVoD.SetAttribute("DataRate", DataRateValue(DataRate("10Mb/s")));
  onOffVoD.SetAttribute("PacketSize", UintegerValue(512));
  onOffVoD.SetAttribute("MaxBytes", UintegerValue(0));

  VoDstreamApp.Add(onOffVoD.Install(serverNodes.Get(0)));

  VoDstreamApp.Start (Seconds (6.22));
  VoDstreamApp.Stop (Seconds (7.018));

  //---------------------------------------VoD---end--------------------------//

  //---------------------------------------BitTorrent-----------------------------//


  uint16_t torrPort=6881;

    //Zdroj a sink pro zisk .torrent
    ApplicationContainer torrSinkApp;

    uint16_t torrStart=9;
    uint16_t torrStop=10;

    PacketSinkHelper torrSink ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (TorrInt[0].GetAddress(1)),torrPort));
    std::cout << "Packet sink for torrLooking at address: "<< TorrInt[0].GetAddress(1) << ", port number : "<< torrPort <<std::endl;
    torrSinkApp.Add(torrSink.Install(TorrNode.Get(0)));

    torrSinkApp.Start (Seconds (torrStart));
    torrSinkApp.Stop (Seconds (torrStop+2));


    ApplicationContainer torrApp;

    OnOffHelper torrOnOff ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (TorrInt[0].GetAddress(1)),torrPort));
    std::cout << "OnOff torrLooking to server at address" << ": "<< TorrInt[0].GetAddress(1) << "."<< std::endl;

    torrOnOff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0.02]"));
    torrOnOff.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0.15]"));
    torrOnOff.SetAttribute("DataRate", DataRateValue(DataRate("2Mb/s")));
    torrOnOff.SetAttribute("PacketSize", UintegerValue(1400));
    torrOnOff.SetAttribute("MaxBytes", UintegerValue(0));


    torrApp.Add(torrOnOff.Install(clientNodes.Get(2)));

    torrApp.Start (Seconds (torrStart+0.1));
    torrApp.Stop (Seconds (torrStop-0.1));


  //Vytvoreni potrebnych sinku v uzlech

    uint16_t Ontorr = 10;
    uint16_t Offtorr = 12;

    ApplicationContainer trackSinkApp;
    PacketSinkHelper trackSink ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (TorrInt[0].GetAddress(1)),6969));
    std::cout << "Packet sink for tracker at address: "<< TorrInt[0].GetAddress(1) << ", port number : "<< 6969 <<std::endl;
    trackSinkApp.Add(trackSink.Install(TorrNode.Get(0)));

    trackSinkApp.Start (Seconds (Ontorr));
    trackSinkApp.Stop (Seconds (Offtorr));


    ApplicationContainer torrSinkAppA;
    PacketSinkHelper torrSinkA ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (outInt1[0].GetAddress(1)),6882));
        std::cout << "Packet sink A at address:"<< outInt1[0].GetAddress(1) << std::endl;
        torrSinkAppA.Add(torrSinkA.Install(outNode1.Get(0)));

        torrSinkAppA.Start (Seconds (Ontorr-1));
        torrSinkAppA.Stop (Seconds (Offtorr));

    ApplicationContainer torrSinkAppB;
    PacketSinkHelper torrSinkB ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (outInt1[1].GetAddress(1)),6883));
    	std::cout << "Packet sink B at address:"<< outInt1[1].GetAddress(1) << std::endl;
        torrSinkAppB.Add(torrSinkB.Install(outNode1.Get(1)));

        torrSinkAppB.Start (Seconds (Ontorr));
        torrSinkAppB.Stop (Seconds (Offtorr));

    ApplicationContainer torrSinkAppC;
    PacketSinkHelper torrSinkC ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (outInt1[2].GetAddress(1)),6884));
        std::cout << "Packet sink C at address:"<< outInt1[2].GetAddress(1) << std::endl;
        torrSinkAppC.Add(torrSinkC.Install(outNode1.Get(2)));

        torrSinkAppC.Start (Seconds (Ontorr));
        torrSinkAppC.Stop (Seconds (Offtorr));

    ApplicationContainer torrSinkAppClient;
    PacketSinkHelper torrSinkClient ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (p2pCInterfaces[2].GetAddress(0)),6885));
        std::cout << "Packet sink Client at address:"<< p2pCInterfaces[2].GetAddress(0) << std::endl;
        torrSinkAppClient.Add(torrSinkClient.Install(clientNodes.Get(2)));

        torrSinkAppClient.Start (Seconds (Ontorr));
        torrSinkAppClient.Stop (Seconds (Offtorr));



        //Tvorba vysilani z jednotlivych uzlu - ruzne cile, rychlosti a casy
        ApplicationContainer torrABApp;

            OnOffHelper torrABOnOff ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (outInt1[0].GetAddress(1)),6882));
            std::cout << "OnOff torr A to B" << ": "<< outInt1[0].GetAddress(1) << "."<< std::endl;

            torrABOnOff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=1000]"));
            torrABOnOff.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
            torrABOnOff.SetAttribute("DataRate", DataRateValue(DataRate("150kb/s")));
            torrABOnOff.SetAttribute("PacketSize", UintegerValue(1024));
            torrABOnOff.SetAttribute("MaxBytes", UintegerValue(0));

            torrABApp.Add(torrABOnOff.Install(outNode1.Get(1)));
            torrABApp.Start (Seconds (Ontorr-0.5));
            torrABApp.Stop (Seconds (Offtorr-0.5));


        ApplicationContainer torrACApp;

            OnOffHelper torrACOnOff ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (outInt1[0].GetAddress(1)),6882));
            std::cout << "OnOff torr A to C" << ": "<< outInt1[0].GetAddress(1) << "."<< std::endl;

            torrACOnOff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=1000]"));
            torrACOnOff.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
            torrACOnOff.SetAttribute("DataRate", DataRateValue(DataRate("250kb/s")));
            torrACOnOff.SetAttribute("PacketSize", UintegerValue(1024));
            torrACOnOff.SetAttribute("MaxBytes", UintegerValue(0));

            torrACApp.Add(torrACOnOff.Install(outNode1.Get(2)));
            torrACApp.Start (Seconds (Ontorr+0.43));		//Po kontaktu na torr pro zisk DHT
            torrACApp.Stop (Seconds (Offtorr));


        ApplicationContainer torrAClApp;

            OnOffHelper torrAClOnOff ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (outInt1[0].GetAddress(1)),6882));
            std::cout << "OnOff torr A to Cl" << ": "<< outInt1[0].GetAddress(1) << "."<< std::endl;

            torrAClOnOff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=1000]"));
            torrAClOnOff.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
            torrAClOnOff.SetAttribute("DataRate", DataRateValue(DataRate("250kb/s")));
            torrAClOnOff.SetAttribute("PacketSize", UintegerValue(1024));
            torrAClOnOff.SetAttribute("MaxBytes", UintegerValue(0));

            torrAClApp.Add(torrAClOnOff.Install(clientNodes.Get(2)));
            torrAClApp.Start (Seconds (Ontorr));
            torrAClApp.Stop (Seconds (Offtorr));


        ApplicationContainer torrBClApp;

            OnOffHelper torrBClOnOff ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (outInt1[1].GetAddress(1)),6883));
            std::cout << "OnOff torr B to Cl" << ": "<< outInt1[1].GetAddress(1) << "."<< std::endl;

            torrBClOnOff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=1000]"));
            torrBClOnOff.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
            torrBClOnOff.SetAttribute("DataRate", DataRateValue(DataRate("180kb/s")));
            torrBClOnOff.SetAttribute("PacketSize", UintegerValue(1024));
            torrBClOnOff.SetAttribute("MaxBytes", UintegerValue(0));

            torrBClApp.Add(torrBClOnOff.Install(clientNodes.Get(2)));
            torrBClApp.Start (Seconds (Ontorr));
            torrBClApp.Stop (Seconds (Offtorr));


        ApplicationContainer torrClBApp;

            OnOffHelper torrClBOnOff ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (p2pCInterfaces[2].GetAddress(0)),6885));
            std::cout << "OnOff torr Cl to B" << ": "<< p2pCInterfaces[2].GetAddress(0) << "."<< std::endl;

            torrClBOnOff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=1000]"));
            torrClBOnOff.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
            torrClBOnOff.SetAttribute("DataRate", DataRateValue(DataRate("40kb/s")));
            torrClBOnOff.SetAttribute("PacketSize", UintegerValue(1024));
            torrClBOnOff.SetAttribute("MaxBytes", UintegerValue(0));

            torrClBApp.Add(torrClBOnOff.Install(outNode1.Get(1)));
            torrClBApp.Start (Seconds (Ontorr+0.23));
            torrClBApp.Stop (Seconds (Offtorr-0.5));


    ApplicationContainer torrCClApp;

            OnOffHelper torrCClOnOff ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (outInt1[2].GetAddress(1)),6884));
            std::cout << "OnOff torr C to Cl" << ": "<< outInt1[2].GetAddress(1) << "."<< std::endl;

            torrCClOnOff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=1000]"));
            torrCClOnOff.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
            torrCClOnOff.SetAttribute("DataRate", DataRateValue(DataRate("100kb/s")));
            torrCClOnOff.SetAttribute("PacketSize", UintegerValue(1024));
            torrCClOnOff.SetAttribute("MaxBytes", UintegerValue(0));

            torrCClApp.Add(torrCClOnOff.Install(clientNodes.Get(2)));
            torrCClApp.Start (Seconds (Ontorr+0.46));
            torrCClApp.Stop (Seconds (Offtorr));


    ApplicationContainer torrClCApp;

            OnOffHelper torrClCOnOff ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (p2pCInterfaces[2].GetAddress(0)),6885));
            std::cout << "OnOff torr Cl to C" << ": "<< p2pCInterfaces[2].GetAddress(0) << "."<< std::endl;

            torrClCOnOff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=1000]"));
            torrClCOnOff.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
            torrClCOnOff.SetAttribute("DataRate", DataRateValue(DataRate("30kb/s")));
            torrClCOnOff.SetAttribute("PacketSize", UintegerValue(1024));
            torrClCOnOff.SetAttribute("MaxBytes", UintegerValue(0));

            torrClCApp.Add(torrClCOnOff.Install(outNode1.Get(2)));
            torrClCApp.Start (Seconds (Ontorr+0.425));
            torrClCApp.Stop (Seconds (Offtorr));


            ApplicationContainer torrBCApp;

            OnOffHelper torrBCOnOff ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (outInt1[1].GetAddress(1)),6883));
           std::cout << "OnOff torr B to C" << ": "<< outInt1[1].GetAddress(1) << "."<< std::endl;

           torrBCOnOff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=1000]"));
           torrBCOnOff.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
           torrBCOnOff.SetAttribute("DataRate", DataRateValue(DataRate("150kb/s")));
           torrBCOnOff.SetAttribute("PacketSize", UintegerValue(1024));
           torrBCOnOff.SetAttribute("MaxBytes", UintegerValue(0));

           torrBCApp.Add(torrBCOnOff.Install(outNode1.Get(2)));
           torrBCApp.Start (Seconds (Ontorr+0.43));
           torrBCApp.Stop (Seconds (Offtorr));

            //Komunikace na tracker z vnejsich uzlu Source_A a Source_B
            for(int i=0; i<2; i++)
              {

	ApplicationContainer torrTrackApp;

	            OnOffHelper torrTrackOnOff ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (TorrInt[0].GetAddress(1)),6969));
	            std::cout << "OnOff Tracker info from" << ": "<< outInt1[i].GetAddress(1) << "."<< std::endl;

	            torrTrackOnOff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=1000]"));
	            torrTrackOnOff.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
	            torrTrackOnOff.SetAttribute("DataRate", DataRateValue(DataRate("40kb/s")));
	            torrTrackOnOff.SetAttribute("PacketSize", UintegerValue(400));
	            torrTrackOnOff.SetAttribute("MaxBytes", UintegerValue(0));

	            torrTrackApp.Add(torrTrackOnOff.Install(outNode1.Get(i)));
	            torrTrackApp.Start (Seconds (Ontorr+0.2));
	            torrTrackApp.Stop (Seconds (Offtorr));

              }

            //Komunikace na tracker z vnejsiho uzlu Source_C
            ApplicationContainer torrTrackCApp;

            OnOffHelper torrTrackCOnOff ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (TorrInt[0].GetAddress(1)),6969));
            	            std::cout << "OnOff Tracker info from" << ": "<< outInt1[2].GetAddress(1) << "."<< std::endl;

            	            torrTrackCOnOff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=1000]"));
            	            torrTrackCOnOff.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
            	            torrTrackCOnOff.SetAttribute("DataRate", DataRateValue(DataRate("40kb/s")));
            	            torrTrackCOnOff.SetAttribute("PacketSize", UintegerValue(400));
            	            torrTrackCOnOff.SetAttribute("MaxBytes", UintegerValue(0));

            	            torrTrackCApp.Add(torrTrackCOnOff.Install(outNode1.Get(2)));
            	            torrTrackCApp.Start (Seconds (Ontorr+0.4));
            	            torrTrackCApp.Stop (Seconds (Offtorr));




            //Komunikace na tracker z uzlu Client_3
            ApplicationContainer torrTrackClApp;

                             OnOffHelper torrTrackClOnOff ("ns3::TcpSocketFactory",InetSocketAddress(Ipv4Address (TorrInt[0].GetAddress(1)),6969));
                             std::cout << "OnOff Tracker info from" << ": "<< p2pCInterfaces[2].GetAddress(1) << "."<< std::endl;

                             torrTrackClOnOff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=1000]"));
                             torrTrackClOnOff.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
                             torrTrackClOnOff.SetAttribute("DataRate", DataRateValue(DataRate("40kb/s")));
                             torrTrackClOnOff.SetAttribute("PacketSize", UintegerValue(400));
                             torrTrackClOnOff.SetAttribute("MaxBytes", UintegerValue(0));

                             torrTrackClApp.Add(torrTrackClOnOff.Install(clientNodes.Get(2)));
                             torrTrackClApp.Start (Seconds (Ontorr+0.2));
                             torrTrackClApp.Stop (Seconds (Offtorr));





  //---------------------------------------BitTorrent---end--------------------------//


  //---------------------------------------IPTV-------------------------------//


    //Definice skupiny, zdroje
    Ipv4Address multicastSource("172.0.0.1");
    Ipv4Address multicastGroup("225.10.10.50");

    Ipv4StaticRoutingHelper multicast;

    //Vysilani na serverove strane
    Ptr<Node> sender = serverNodes.Get(0);
    Ptr<NetDevice> direction= p2pSDevices[0].Get(0);
    multicast.SetDefaultMulticastRoute(sender, direction);


    ApplicationContainer IPTVSink;
    ApplicationContainer IPTVSource;

    //Zdroj + sink na serverove strane
    PacketSinkHelper sinkIPTV ("ns3::UdpSocketFactory",InetSocketAddress(Ipv4Address::GetAny(), 1000));
    IPTVSink.Add(sinkIPTV.Install(oltNode.Get(0)));

    IPTVSink.Start(Seconds(13.0));
    IPTVSink.Stop(Seconds(14.0));

    OnOffHelper IPTVonoff ("ns3::UdpSocketFactory",Address (InetSocketAddress ("225.10.10.50", 1000)));
    IPTVonoff.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=10]"));
    IPTVonoff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
    IPTVonoff.SetAttribute ("DataRate", DataRateValue (DataRate ("10Mb/s")));
    IPTVonoff.SetAttribute ("PacketSize", UintegerValue (1024));
    IPTVonoff.SetAttribute("MaxBytes", UintegerValue(0));

    IPTVSource.Add(IPTVonoff.Install(serverNodes.Get(0)));
    IPTVSource.Start(Seconds(13.0));
    IPTVSource.Stop(Seconds(13.2));

    //Vysilani na klientske strane
    for(int i=0; i<2; i++)
    {
    Ipv4Address multicastSource("172.0.0.1");
    Ipv4Address multicastGroup("225.10.10.50");

    Ipv4StaticRoutingHelper multicastClient;

    Ptr<Node> sender = onuNodes.Get(i);
    Ptr<NetDevice> direction= p2pCDevices[i].Get(1);
    multicastClient.SetDefaultMulticastRoute(sender, direction);


    ApplicationContainer IPTVSink;
    ApplicationContainer IPTVSource;

    PacketSinkHelper sinkIPTV ("ns3::UdpSocketFactory",InetSocketAddress(Ipv4Address::GetAny(), 1000));
    IPTVSink.Add(sinkIPTV.Install(clientNodes.Get(i)));

    IPTVSink.Start(Seconds(13.0));
    IPTVSink.Stop(Seconds(14.0));


    OnOffHelper IPTVonoff ("ns3::UdpSocketFactory",Address (InetSocketAddress ("225.10.10.50", 1000)));
    IPTVonoff.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=10]"));
    IPTVonoff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
    IPTVonoff.SetAttribute ("DataRate", DataRateValue (DataRate ("10Mb/s")));
    IPTVonoff.SetAttribute ("PacketSize", UintegerValue (1024));
    IPTVonoff.SetAttribute("MaxBytes", UintegerValue(0));

    IPTVSource.Add(IPTVonoff.Install(onuNodes.Get(i)));
    IPTVSource.Start(Seconds(13.003));
    IPTVSource.Stop(Seconds(13.203));
    }


    	//Vysilani pro uzel Client_3
    	Ipv4StaticRoutingHelper multicastClient3;

    	Ptr<Node> sender3 = onuNodes.Get(2);
        Ptr<NetDevice> direction3= p2pCDevices[2].Get(1);
        multicastClient3.SetDefaultMulticastRoute(sender3, direction3);



        ApplicationContainer IPTVSink3;
        ApplicationContainer IPTVSource3;
        ApplicationContainer IPTVSource3_2;

        PacketSinkHelper sinkIPTV3 ("ns3::UdpSocketFactory",InetSocketAddress(Ipv4Address::GetAny(), 1000));
        IPTVSink3.Add(sinkIPTV3.Install(clientNodes.Get(2)));

        IPTVSink3.Start(Seconds(13.0));
        IPTVSink3.Stop(Seconds(14));


        OnOffHelper IPTVonoff3 ("ns3::UdpSocketFactory",Address (InetSocketAddress ("225.10.10.50", 1000)));
        IPTVonoff3.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=10]"));
        IPTVonoff3.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
        IPTVonoff3.SetAttribute ("DataRate", DataRateValue (DataRate ("10Mb/s")));
        IPTVonoff3.SetAttribute ("PacketSize", UintegerValue (1024));
        IPTVonoff3.SetAttribute("MaxBytes", UintegerValue(0));

        IPTVSource3.Add(IPTVonoff3.Install(onuNodes.Get(2)));
        IPTVSource3.Start(Seconds(13.039));
        IPTVSource3.Stop(Seconds(13.063));

        OnOffHelper IPTVonoff3_2 ("ns3::UdpSocketFactory",Address (InetSocketAddress ("225.10.10.51", 1000)));
        IPTVonoff3_2.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=10]"));
        IPTVonoff3_2.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
        IPTVonoff3_2.SetAttribute ("DataRate", DataRateValue (DataRate ("10Mb/s")));
        IPTVonoff3_2.SetAttribute ("PacketSize", UintegerValue (1024));
        IPTVonoff3_2.SetAttribute("MaxBytes", UintegerValue(0));

        IPTVSource3_2.Add(IPTVonoff3_2.Install(onuNodes.Get(2)));
        IPTVSource3_2.Start(Seconds(13.065));
        IPTVSource3_2.Stop(Seconds(13.076));

//Prihlaseni a odhlaseni klienta 3

        ApplicationContainer IPTVlogin;

        OnOffHelper IPTVlog ("ns3::UdpSocketFactory",InetSocketAddress(Ipv4Address (p2pCInterfaces[2].GetAddress(1)),5555));

         IPTVlog.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=1000]"));
         IPTVlog.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
         IPTVlog.SetAttribute("DataRate", DataRateValue(DataRate("7kb/s")));
         IPTVlog.SetAttribute("PacketSize", UintegerValue(32));
         IPTVlog.SetAttribute("MaxBytes", UintegerValue(64));

         IPTVlogin.Add(IPTVlog.Install(clientNodes.Get(2)));
         IPTVlogin.Start (Seconds (13));
         IPTVlogin.Stop (Seconds (14));


        ApplicationContainer IPTVlogin2;

         OnOffHelper IPTVlog2 ("ns3::UdpSocketFactory",InetSocketAddress(Ipv4Address (p2pCInterfaces[2].GetAddress(1)),5555));

          IPTVlog2.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=1000]"));
          IPTVlog2.SetAttribute ("OffTime",  StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
          IPTVlog2.SetAttribute("DataRate", DataRateValue(DataRate("5Mb/s")));
          IPTVlog2.SetAttribute("PacketSize", UintegerValue(32));
          IPTVlog2.SetAttribute("MaxBytes", UintegerValue(64));

          IPTVlogin2.Add(IPTVlog2.Install(clientNodes.Get(2)));
          IPTVlogin2.Start (Seconds (13.06));
          IPTVlogin2.Stop (Seconds (14));

          //Sink pro login - ONU_3
          ApplicationContainer IPTVsink;

          PacketSinkHelper sinkIPTVlog ("ns3::UdpSocketFactory",InetSocketAddress(Ipv4Address::GetAny(), 5555));
          IPTVsink.Add(sinkIPTVlog.Install(onuNodes.Get(2)));

          IPTVsink.Start(Seconds(13));
          IPTVsink.Stop(Seconds(14.0));




  //---------------------------------------IPTV---end--------------------------//



  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();


  //---------------------simulation--end-----------------------------//

  //Kontejnery pro generaci vystupnich souboru
  NetDeviceContainer BTtrack;
  BTtrack.Add(p2pSDevices[2].Get(0));

  NetDeviceContainer IPTVtrack;
  IPTVtrack.Add(p2pCDevices[0].Get(0));

  NetDeviceContainer SourceBtrack;
  SourceBtrack.Add(p2pOutDev1[1].Get(0));

  NetDeviceContainer SourceAtrack;
   SourceAtrack.Add(p2pOutDev1[0].Get(0));

  NetDeviceContainer onu_3track;
  onu_3track.Add(p2pCDevices[2].Get(1));

  //Zaznam pruchodu
  xgponHelper.EnablePcapAll("Bachelor-xgpon");				//Zaznam z modulu XG-PON


  pointToPoint.EnablePcap ("BT-pcap", BTtrack); 			//Zaznam mezi OLT a R
  pointToPoint.EnablePcap ("ONU_3-pcap",onu_3track);		//Zaznam z ONU_3
  pointToPoint.EnablePcap ("SourceB-pcap", SourceBtrack); 	//Zaznam z uzlu Source_B
  pointToPoint.EnablePcap ("SourceA-pcap", SourceAtrack);	//Zaznam z uzlu Source_A

  pointToPoint.EnablePcap ("IPTV-pcap", IPTVtrack);			//Zaznam z uzlu Client_3

  //Trasovani
  Ptr<XgponOltNetDevice> oltDevice = DynamicCast<XgponOltNetDevice, NetDevice> (xgponDevices.Get(0));

  oltDevice->TraceConnectWithoutContext ("DeviceStatistics", MakeCallback(&DeviceStatisticsTrace));


  //Zobrazeni pro NetAnim
  AnimationInterface::SetConstantPosition(serverNodes.Get(0), 0, 10);
  AnimationInterface::SetConstantPosition(serverNodes.Get(1), 0, 20);
  AnimationInterface::SetConstantPosition(oltNode.Get(0), 40, 10);
  AnimationInterface::SetConstantPosition(onuNodes.Get(0), 70, 10);
  AnimationInterface::SetConstantPosition(onuNodes.Get(1), 70, 20);
  AnimationInterface::SetConstantPosition(onuNodes.Get(2), 70, 30);
  AnimationInterface::SetConstantPosition(clientNodes.Get(0), 100, 10);
  AnimationInterface::SetConstantPosition(clientNodes.Get(1), 100, 20);
  AnimationInterface::SetConstantPosition(clientNodes.Get(2), 100, 30);
  AnimationInterface::SetConstantPosition(serverNodes.Get(2),20,40);
  AnimationInterface::SetConstantPosition(outNode1.Get(0),5,55);
  AnimationInterface::SetConstantPosition(outNode1.Get(1),20,55);
  AnimationInterface::SetConstantPosition(outNode1.Get(2),35,55);
  AnimationInterface::SetConstantPosition(TorrNode.Get(0),0,40);


  //Vytvoreni souboru Bachelor.xml a popisku pro jednotlive uzly
  AnimationInterface anim ("Bachelor.xml");

  anim.UpdateNodeDescription(serverNodes.Get(0),"TvServer");
  anim.UpdateNodeDescription(serverNodes.Get(1),"WebServer");
  anim.UpdateNodeDescription(oltNode.Get(0),"OLT");
  anim.UpdateNodeDescription(onuNodes.Get(0),"ONU_1");
  anim.UpdateNodeDescription(onuNodes.Get(1),"ONU_2");
  anim.UpdateNodeDescription(onuNodes.Get(2),"ONU_3");
  anim.UpdateNodeDescription(clientNodes.Get(0),"Client_1");
  anim.UpdateNodeDescription(clientNodes.Get(1),"Client_2");
  anim.UpdateNodeDescription(clientNodes.Get(2),"Client_3");
  anim.UpdateNodeDescription(serverNodes.Get(2),"R");
  anim.UpdateNodeDescription(outNode1.Get(0),"Source_A");
  anim.UpdateNodeDescription(outNode1.Get(1),"Source_B");
  anim.UpdateNodeDescription(outNode1.Get(2),"Source_C");
  anim.UpdateNodeDescription(TorrNode.Get(0),"TorrServer");



  std::cout<<std::endl;
  Simulator::Stop(Seconds(SIM_STOP));
  Simulator::Run ();
  Simulator::Destroy ();
  std::cout<<std::endl;

  return 0;
}

