# -----------------------------------------------
#  SiteInfo - данные о создаваемом сайте:
# Название шаблона, Активируемые возможности, Объединенные календари, Группы безопасности
# -----------------------------------------------
function New-SiteInfo()
{
  param ($Url, $Title, $ShouldExistXml, $TemplateName, $AddToTopNav, $ThemeSettings,
        $ArrayOfSiteTypeFeaturesXml, $ArrayOfFeaturesXml, $ArrayOfSiteTypeCalendarOverlaysXml, $ArrayOfSiteCalendarOverlaysXml,
        $ArrayOfSecurityGroupXml,
        $PropertiesSiteXml, $PropertiesSiteTypeXml)

  $siteInfo = new-object PSObject
  # Адрес узла
  $siteInfo | add-member -type NoteProperty -Name Url -Value $Url
  #---------------------------------

  # Название узла
  $siteInfo | add-member -type NoteProperty -Name Title -Value $Title
  #---------------------------------

  # Признак того, что сайт должен существовать
  $shouldExist = ($ShouldExistXml -and [System.Convert]::ToBoolean($ShouldExistXml))  
  $siteInfo | add-member -type NoteProperty -Name ShouldExist -Value $shouldExist
  #---------------------------------

  # Наименование шаблона
  $siteInfo | add-member -type NoteProperty -Name Template -Value $TemplateName
  #---------------------------------

  # Настройки цветовой темы
  $siteInfo | add-member -type NoteProperty -Name ThemeColor -Value $ThemeSettings.Color
  $siteInfo | add-member -type NoteProperty -Name ThemeFont -Value $ThemeSettings.Font
  #---------------------------------

  # Должен ли сайт добавиться в верхнее меню
  $addToTopNav = ($AddToTopNav -and [System.Convert]::ToBoolean($AddToTopNav)) 
  $siteInfo | add-member -type NoteProperty -Name AddToTopNav -Value $addToTopNav

  # Свойства для PropertyBag
  $dictProperties = @{}
  if($PropertiesSiteTypeXml)
  {
  foreach($propertyXml in  $PropertiesSiteTypeXml.Property)
  {   
    if($dictProperties.ContainsKey($propertyXml.Name))
    {
        $dictProperties[$propertyXml.Name] = $propertyXml.Value
    }
    else
    {
        $dictProperties.Add($propertyXml.Name, $propertyXml.Value)    
    }
  }
  }  
  if($PropertiesSiteXml)
  {
  foreach($propertyXml in  $PropertiesSiteXml.Property)
  {    
    if($dictProperties.ContainsKey($propertyXml.Name))
    {
        $dictProperties[$propertyXml.Name] = $propertyXml.Value
    }
    else
    {
        $dictProperties.Add($propertyXml.Name, $propertyXml.Value)    
    } 
  }
  }
  $siteInfo | add-member -type NoteProperty -Name Properties -Value $dictProperties

  #---------------------------------

  # Идентификаторы активируемых возможностей
  $webFeatureIDs = @()
  $siteFeatureIDs = @()
  if($ArrayOfSiteTypeFeaturesXml)
  {
  foreach($featuresXml in  $ArrayOfSiteTypeFeaturesXml){ 
	if ($featuresXml.Scope -eq "Site") { $siteFeatureIDs += $featuresXml.ID }
	else { $webFeatureIDs += $featuresXml.ID }
	}
  }
  if($ArrayOfFeaturesXml)
  {
  foreach($featuresXml in  $ArrayOfFeaturesXml){ 
	if ($featuresXml.Scope -eq "Site") { $siteFeatureIDs += $featuresXml.ID }
	else { $webFeatureIDs += $featuresXml.ID }
	}
  }
  $siteInfo | add-member -type NoteProperty -Name WebFeatureIDs -Value $webFeatureIDs
  $siteInfo | add-member -type NoteProperty -Name SiteFeatureIDs -Value $siteFeatureIDs
  #---------------------------------

  # Объединенные календари
  $calendarOverlayInfoCollection = @()
  if($ArrayOfSiteTypeCalendarOverlaysXml)
  {
  foreach($calendarOverlayXml in  $ArrayOfSiteTypeCalendarOverlaysXml)
  {
    $calendarOverlayInfoCollection += New-CalendarOverlayInfo -CalendarOverlayXml: $calendarOverlayXml
  }
  }  
  if($ArrayOfSiteCalendarOverlaysXml)
  {
  foreach($calendarOverlayXml in  $ArrayOfSiteCalendarOverlaysXml)
  {
    $calendarOverlayInfoCollection += New-CalendarOverlayInfo -CalendarOverlayXml: $calendarOverlayXml
  }
  }
  $siteInfo | add-member -type NoteProperty -Name CalendarOverlays -Value $calendarOverlayInfoCollection 
  #---------------------------------

  # Группы безопасности
  $groupInfoCollection = @()
  if($ArrayOfSecurityGroupXml)
  {
    foreach($securityGroupXml in  $ArrayOfSecurityGroupXml.Group)
    {
      $groupInfoCollection += New-SecurityGroupInfo -SecurityGroupInfoXml: $securityGroupXml
    }
  }  
  $siteInfo | add-member -type NoteProperty -Name SecurityGroups -Value $groupInfoCollection 

  return $siteInfo
}
# -----------------------------------------------
# -----------------------------------------------
# -----------------------------------------------

function ConfigurationSiteBySiteInfo()
{
    param ($SiteInfo, $BaseUrl)


    if($SiteInfo.ShouldExist)
    {
         # Проверим существование сайта
		 $url = Join-Parts ($BaseUrl,$SiteInfo.Url) '/'
		 $childWeb = Get-SPWeb -Identity $url -ErrorAction: SilentlyContinue
         #$childWeb = Get-SPWeb -Identity "$($BaseUrl)/$($SiteInfo.Url)" -ErrorAction: SilentlyContinue

         if(!$childWeb.Exists)
         {
           throw "Не существует сайта:" + $SiteInfo.Title           
         }
    }
    else
    {
        # Если не задан шаблон, то будем создавать "Пустой сайт"
        if(!$SiteInfo.Template) { $SiteInfo.Template = "BlankSite" }
    
        Write-Host "Шаблон: " $SiteInfo.Template
    
        # Создаем сайт
        if($SiteInfo.Template -eq "TeamSite")
        {
            $childWeb = CreateTeamSite $BaseUrl $SiteInfo.Url $SiteInfo.Title $true $SiteInfo.AddToTopNav $true $false
        }
        elseif($SiteInfo.Template -eq "BlankSite")
        {
            $childWeb = CreateBlankSite $BaseUrl $SiteInfo.Url $SiteInfo.Title $true $SiteInfo.AddToTopNav $true $false
        }
        else
        {
            throw "Неизвестный шаблон" + $SiteInfo.Template + "для сайта " + $SiteInfo.Url
        }
    }

    # Свойства PropertyBag
    foreach ($property in $SiteInfo.Properties.GetEnumerator())
    {
        Write-Host "Свойство: " $property.Name "=" $property.Value -ForegroundColor: DarkYellow
        if (!$childWeb.Properties.ContainsKey($property.Name))
        { 
            $childWeb.Properties.Add($property.Name, $property.Value);
        }
        else
        {
            $childWeb.Properties[$property.Name] = $property.Value;
        }  
        $childWeb.Properties.Update();
        $childWeb.Update();           
    }

    # Безопасность
    foreach  ($securityGroupInfo in $SiteInfo.SecurityGroups)
    {
       Write-Host "Группа: " $securityGroupInfo.Name -ForegroundColor: DarkYellow
       ConfigurateSecurityGroupBySecurityGroupInfo -SPWeb: $childWeb -SecurityGroupInfo: $securityGroupInfo
    } 
      
    # Изменяем оформление сайта
	if($SiteInfo.ThemeColor -ne $null -or $SiteInfo.ThemeFont -ne $null)
	{
		Write-Host Recolor site started
		Start-SPAssignment -global
		Try
		{
			if ($SiteInfo.ThemeFont -ne $null -and (FileAddedToSharepoint $childWeb.Site.Url ($SiteInfo.ThemeFont + ".spfont"))) {
				$font = "/_catalogs/theme/15/" + $SiteInfo.ThemeFont + ".spfont"
			}
			else { 
				$font = ""
			}
			if ($SiteInfo.ThemeColor -ne $null -and (FileAddedToSharepoint $childWeb.Site.Url ($SiteInfo.ThemeColor + ".spcolor"))) {
				$color = "/_catalogs/theme/15/" + $SiteInfo.ThemeColor + ".spcolor"
			}
			else { 
				$color = "/_catalogs/theme/15/Palette001.spcolor"
			}
			
			$web = Get-SPWeb -Identity $childWeb.Url;
			$web.allowunsafeupdates = $true
			Write-Host "Цветовая схема сайта: " $SiteInfo.ThemeColor
			$web.ApplyTheme($color, $font, "" , $true);      
			$web.Update()
			$web.allowunsafeupdates = $false   
			Write-Host Site successfully recolored -ForegroundColor Yellow
		}
		Catch { Write-Host $_.Exception.Message -ForegroundColor: Red }
		Stop-SPAssignment -global  
	}
	
    # Активируем возможности       
    foreach  ($featureId in $SiteInfo.WebFeatureIDs)
    {
        Write-Host "Возможность: " $featureId
        ActivateWebFeatureByWebUrlAndFeatureId $childWeb.Url $featureId            
    }
    foreach  ($featureId in $SiteInfo.SiteFeatureIDs)
    {
        Write-Host "Возможность: " $featureId
        ActivateSiteFeatureBySiteUrlAndFeatureId $childWeb.Url $featureId            
    }

    # Объединенные календари
     foreach  ($calendarOverlayInfo in $SiteInfo.CalendarOverlays)
     {
        Write-Host "Объединенный календарь: " $calendarOverlayInfo.Title
        CreateCalendarOverlayByCalendarOverlayInfo -SPWeb: $childWeb -CalendarOverlayInfo: $calendarOverlayInfo
     } 
}
function FileAddedToSharepoint ($web, $fileName) {
	Try {
		$rootWeb = Get-SPWeb $web;
		$fileSP = $rootWeb.GetFile("/_catalogs/theme/15/" + $fileName)
		if ($fileSP.Exists -ne $True)
		{
			$scriptPath = Split-Path $script:MyInvocation.MyCommand.Path
			$file = Get-Item ($scriptPath + "\Theme\" + $fileName)
			$fileStream=([System.IO.FileInfo](Get-Item $file.FullName)).OpenRead()
			$folder=$rootWeb.GetFolder("/_catalogs/theme/15/")
			$spFile=$folder.Files.Add($folder.Url + "/" + $file.Name, [System.IO.Stream]$fileStream, $true)
			$fileStream.Close()
		}
		return $true
	}
	Catch {
		Write-Host $_.Exception.Message
		return $false
	}
}