<?php

include_once(dirname(__FILE__).'/MapAPI.php');

class PageNetworkMap extends Page
{
  function __construct(System $System)
  {
    parent::__construct($System);
    $this->Title = 'Mapa sítě';
    $this->ParentClass = 'PagePortal';
  }
  //var $Load = 'initialize()';
  //var $Unload = 'GUnload()';

  function Show(): string
  {
    if (!ModuleUser::Cast($this->System->GetModule('User'))->User->CheckPermission('Map', 'Show'))
      return 'Nemáte oprávnění';

    if (count($this->System->PathItems) > 1)
    {
      if ($this->System->PathItems[1] == 'show-position') return $this->ShowPosition();
      else return PAGE_NOT_FOUND;
    } else return $this->ShowMain();
  }

  function ShowPosition(): string
  {
    $DbResult = $this->Database->select('MapPosition', '*', '`Id`='.$_GET['i']);
    if ($DbResult->num_rows > 0)
    {
      $DbRow = $DbResult->fetch_assoc();
      $Pos = explode(';', $DbRow['Pos']);
      $MapApi = new MapOpenStreetMaps($this->System);
      $MapApi->Position = array('Lat' => $Pos[0], 'Lng' => $Pos[1]);
      $MapApi->Zoom = 18;
      $MapApi->Key = $this->System->Config['Map']['GoogleMapsApiKey'];
      $MapApi->ShowMarker = true;
      $Marker = new MapMarker();
      $Marker->Text = $DbRow['Name'];
      $Marker->Position = $MapApi->Position;
      $MapApi->Markers[] = $Marker;
      $Output = $MapApi->ShowPage($this);
      return $Output;
    } else return 'Položka nenalezena';
  }

  function ShowMain(): string
  {
    $Map = new MapOpenStreetMaps($this->System);
    $Map->Position = array('Lat' => $this->System->Config['Map']['DefaultLatitude'],
      'Lng' => $this->System->Config['Map']['DefaultLongitude']);
    $Map->Zoom = $this->System->Config['Map']['DefaultZoom'];
    $Map->Key = $this->System->Config['Map']['GoogleMapsApiKey'];
    //$Map->OnClickObject = $_GET['r'];
    //$MapApi->ShowMarker = true;

    $DbResult = $this->Database->query('SELECT GROUP_CONCAT(`NetworkDevice`.`Name` SEPARATOR ",") AS `Name`, '.
    '`MapPosition`.`Pos` AS `Pos`, `MapPosition`.`Name` AS `NodeName` '.
    'FROM `NetworkDevice` LEFT JOIN `MapPosition` ON `MapPosition`.`Id` = `NetworkDevice`.`MapPosition` '.
    'WHERE (`NetworkDevice`.`Used`=1) AND (`NetworkDevice`.`MapPosition` IS NOT NULL) '.
    'GROUP BY `NetworkDevice`.`MapPosition`');
    while ($Device = $DbResult->fetch_assoc())
    {
      $Pos = explode(';', $Device['Pos']);
      $Marker = new MapMarker();
      $Marker->Position = array('Lat' => $Pos[0], 'Lng' => $Pos[1]);
      $Marker->Text = $Device['NodeName'].': '.$Device['Name'];
      $Map->Markers[] = $Marker;
    }

    $DbResult = $this->Database->query('SELECT * FROM `NetworkLink` WHERE (`Interface1` <> 0) AND (`Interface2` <> 0)');
    while ($Link = $DbResult->fetch_assoc())
    {
      $DbResult2 = $this->Database->query('SELECT `NetworkDevice`.`Used`, `MapPosition`.`Pos` FROM `NetworkDevice` '.
        'JOIN `MapPosition` ON `MapPosition`.`Id` = `NetworkDevice`.`MapPosition` '.
        'WHERE `NetworkDevice`.`Id` = (SELECT `NetworkInterface`.`Device` FROM `NetworkInterface` WHERE `NetworkInterface`.`Id` = '.$Link['Interface1'].')');
      $DbResult3 = $this->Database->query('SELECT `NetworkDevice`.`Used`, `MapPosition`.`Pos` FROM `NetworkDevice` '.
        'JOIN `MapPosition` ON `MapPosition`.`Id` = `NetworkDevice`.`MapPosition` '.
        'WHERE `NetworkDevice`.`Id` = (SELECT `NetworkInterface`.`Device` FROM `NetworkInterface` WHERE `NetworkInterface`.`Id` = '.$Link['Interface2'].')');
      if (($DbResult2->num_rows > 0) and ($DbResult3->num_rows > 0))
      {
        $Device1 = $DbResult2->fetch_assoc();
        $Pos1 = explode(';', $Device1['Pos']);
        $Device2 = $DbResult3->fetch_assoc();
        $Pos2 = explode(';', $Device2['Pos']);
        if (($Device1['Used'] == 1) and ($Device2['Used'] == 1))
        {
          $PolyLine = new MapPolyLine();
          $PolyLine->Color = '#4F4FBF';
          $PolyLine->Points[] = array('Lat' => $Pos1[0], 'Lng' => $Pos1[1]);
          $PolyLine->Points[] = array('Lat' => $Pos2[0], 'Lng' => $Pos2[1]);
          $Map->PolyLines[] = $PolyLine;
        }
      }
    }

    $Output = $Map->ShowPage($this);


    /*
    $Output = '<script type="text/javascript" src="//maps.googleapis.com/maps/api/js?key='.
    $this->System->Config['Map']['GoogleMapsApiKey'].'"></script>';
    $Output .= '<script type="text/javascript">

    var map;
    var tinyIcon;

    function initialize()
    {

      //if (google.maps.BrowserIsCompatible())
      {
        map = new google.maps.Map(document.getElementById("map_canvas"));
        map.setMapTypeId(\'satellite\');
        map.setCenter(new google.maps.LatLng(49.260422, 18.081179), 15);
        //map.setUIToDefault();
        //map.addControl(new google.maps.OverviewMapControl(new google.maps.Size(128, 96)));


// Create our "tiny" marker icon
//var tinyIcon = new google.maps.Icon();
//tinyIcon.image = "point.gif";
//tinyIcon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
//tinyIcon.iconSize = new google.maps.Size(10, 10);
//tinyIcon.shadowSize = new google.maps.Size(10, 10);
//tinyIcon.iconAnchor = new google.maps.Point(5, 5);
//tinyIcon.infoWindowAnchor = new google.maps.Point(5, 1);

  toggleLabel(\'NetworkLinks\');
  toggleLabel(\'NetworkDevices\');';

      $Output .= '
       }
    }

function toggleLabel(id)
{
  var ele = document.getElementById(id);
  ele.checked = !ele.checked;
  ele.onclick( );
}

    function UpdateNetworkLinks()
    {
      if ((document.getElementById("NetworkLinks")).checked == true)
      {
        NetworkLinks = [';
    $DbResult = $this->Database->query('SELECT * FROM `NetworkLink` WHERE (`Interface1` <> 0) AND (`Interface2` <> 0)');
    while ($Link = $DbResult->fetch_assoc())
    {
      $DbResult2 = $this->Database->query('SELECT `NetworkDevice`.`Used`, `MapPosition`.`Pos` FROM `NetworkDevice` '.
        'JOIN `MapPosition` ON `MapPosition`.`Id` = `NetworkDevice`.`MapPosition` '.
        'WHERE `NetworkDevice`.`Id` = (SELECT `NetworkInterface`.`Device` FROM `NetworkInterface` WHERE `NetworkInterface`.`Id` = '.$Link['Interface1'].')');
      $DbResult3 = $this->Database->query('SELECT `NetworkDevice`.`Used`, `MapPosition`.`Pos` FROM `NetworkDevice` '.
        'JOIN `MapPosition` ON `MapPosition`.`Id` = `NetworkDevice`.`MapPosition` '.
        'WHERE `NetworkDevice`.`Id` = (SELECT `NetworkInterface`.`Device` FROM `NetworkInterface` WHERE `NetworkInterface`.`Id` = '.$Link['Interface2'].')');
      if (($DbResult2->num_rows > 0) and ($DbResult3->num_rows > 0))
      {
        $Device1 = $DbResult2->fetch_assoc();
        $Pos1 = explode(';', $Device1['Pos']);
        $Device2 = $DbResult3->fetch_assoc();
        $Pos2 = explode(';', $Device2['Pos']);
        if (($Device1['Used'] == 1) and ($Device2['Used'] == 1))
          $Output .= 'new google.maps.Polyline([new google.maps.LatLng('.$Pos1[0].', '.
        $Pos1[1].'),new google.maps.LatLng('.$Pos2[0].', '.$Pos2[1].')], "#4F4FBF", 3, 0.8), ';
      }
    }
    $Output .= '];
                for (var i in NetworkLinks)
                {
                        map.addOverlay(NetworkLinks[i]);
                }

   } else { //checkbox turned off
    for (var i in NetworkLinks)
    {
      map.removeOverlay(NetworkLinks[i]);
      NetworkLinks[i] = null;
    }
  }
}

function toggleLabel(id)
{
  var ele = document.getElementById(id);
  ele.checked = !ele.checked;
  ele.onclick( );
}

    function UpdateNetworkDevices()
    {
      if ((document.getElementById("NetworkDevices")).checked == true)
      {
        NetworkDevices = [';

    $DbResult = $this->Database->query('SELECT GROUP_CONCAT(`NetworkDevice`.`Name` SEPARATOR ",") AS `Name`, '.
      '`MapPosition`.`Pos` AS `Pos`, `MapPosition`.`Name` AS `NodeName` '.
      'FROM `NetworkDevice` LEFT JOIN `MapPosition` ON `MapPosition`.`Id` = `NetworkDevice`.`MapPosition` '.
      'WHERE (`NetworkDevice`.`Used`=1) AND (`NetworkDevice`.`MapPosition` IS NOT NULL) '.
      'GROUP BY `NetworkDevice`.`MapPosition`');
    while ($Device = $DbResult->fetch_assoc())
    {
      $Pos = explode(';', $Device['Pos']);
      $Output .= 'new google.maps.Marker(new google.maps.LatLng('.$Pos[0].', '.
      $Pos[1].'), {title: "'.$Device['NodeName'].': '.$Device['Name'].'", icon:\'point.gif\' }), ';
    }
    $Output .= '];
                for (var i in NetworkDevices)
                {
                        map.addOverlay(NetworkDevices[i]);
                }

   } else { //checkbox turned off
    for (var i in NetworkDevices)
    {
      map.removeOverlay(NetworkDevices[i]);
      NetworkDevices[i] = null;
    }
  }
}

    </script>';
    $Output .= '<table style="margin-left: auto; margin-right: auto; width: 100%; height: 80%;">
                  <tr>
                    <td style="width: 80%; height: 100%;">
    <div id="map_canvas" style="width: 100%; height: 100%;"></div></td>
    <td style="width: 20%">
    <form>
    <input type="checkbox" id="NetworkLinks" onClick="UpdateNetworkLinks();">
       <a href="" onClick="toggleLabel(\'NetworkLinks\');return false;">Ukázat spoje</a>
       </input><br />
    <input type="checkbox" id="NetworkDevices" onClick="UpdateNetworkDevices();">
       <a href="" onClick="toggleLabel(\'NetworkDevices\');return false;">Ukázat zařízení</a>
       </input>
    </form></td>
                  </tr>
                </table>';
    */
    return $Output;
  }
}

class TypeMapPosition extends TypeString
{
  function OnEdit(array $Item): string
  {
    $Output = parent::OnEdit($Item);
    if ($this->FormManager->ShowRelation)
      $Output .=  '<img src="'.$this->FormManager->RootURL.'/images/select.png" alf="Vybrat" language="javascript" '.
        'onclick="return popupwindow(&quot;'.$this->FormManager->RootURL.'/is/?a=mapselect&amp;r='.
        $Item['Name'].'&quot;,&quot;test&quot;);" style="cursor:hand;cursor:pointer"/>';
    return $Output;
  }
}

class ModuleMap extends Module
{
  function __construct(System $System)
  {
    parent::__construct($System);
    $this->Name = 'Map';
    $this->Version = '1.0';
    $this->Creator = 'Chronos';
    $this->License = 'GNU/GPLv3';
    $this->Description = 'Show objects on Google maps';
    $this->Dependencies = array(ModuleNetwork::GetName(), ModuleUser::GetName());
    $this->Models = array(MapPosition::GetClassName());
  }

  function DoStart(): void
  {
    $this->System->Pages['map'] = 'PageNetworkMap';
    $this->System->FormManager->Type->RegisterType('MapPosition', 'String', array());
    $this->System->FormManager->RegisterClass('MapPosition', array(
      'Title' => 'Pozice na mapě',
      'Table' => 'MapPosition',
      'Items' => array(
        'Name' => array('Type' => 'String', 'Caption' => 'Jméno', 'Default' => ''),
        'Pos' => array('Type' => 'MapPosition', 'Caption' => 'Poloha', 'Default' => '0;0'),
        'Subjects' => array('Type' => 'TSubjectListMapPosition', 'Caption' => 'Subjekty', 'Default' => ''),
        'NetworkDevices' => array('Type' => 'TNetworkDeviceListMapPosition', 'Caption' => 'Síťová zařízení', 'Default' => ''),
      ),
      'ItemActions' => array(
        array('Caption' => 'Ukázat na mapě', 'URL' => '/map/show-position?i=#RowId'),
      ),
      'Actions' => array(
        array('Caption' => 'Ukázat mapu', 'URL' => '/map/'),
      ),
    ));
    $this->System->FormManager->RegisterFormType('TMapPosition', array(
      'Type' => 'Reference',
      'Table' => 'MapPosition',
      'Id' => 'Id',
      'Name' => 'Name',
      'Filter' => '1',
    ));
    $this->System->FormManager->RegisterFormType('TSubjectListMapPosition', array(
      'Type' => 'ManyToOne',
      'Table' => 'Subject',
      'Id' => 'Id',
      'Ref' => 'MapPosition',
      'Filter' => '1',
    ));
    $this->System->FormManager->RegisterFormType('TNetworkDeviceListMapPosition', array(
      'Type' => 'ManyToOne',
      'Table' => 'NetworkDevice',
      'Id' => 'Id',
      'Ref' => 'MapPosition',
      'Filter' => '1',
    ));
  }
}

class MapPosition extends Model
{
  static function GetModelDesc(): ModelDesc
  {
    $Desc = new ModelDesc(self::GetClassName());
    $Desc->AddString('Name');
    $Desc->AddString('Pos');
    return $Desc;
  }
}
