. $("$libFolder\sharepoint\PageService.ps1")
. $("$libFolder\sharepoint\CommonConstants.ps1")

function ExportWebPartByUrl($sourceWebUrl, $sourcePageRelativeUrl, $webPartTitle)
{
	Write-Host "Getting source web by url ..." -ForegroundColor Gray
	$web = Get-SPWeb $sourceWebUrl
	Write-Host $("Web title: {0}" -f $web.Title)

	Write-Host $("Getting source limited web part manager by page relative url '{0}'..." -f $sourcePageRelativeUrl) -ForegroundColor Gray
	[Microsoft.SharePoint.SPFile] $sourceFile = $web.GetFile($sourcePageRelativeUrl);
	$webPartManager = $sourceFile.GetLimitedWebPartManager([System.Web.UI.WebControls.Webparts.PersonalizationScope]::Shared);
	Write-Host $("Limited web part manager web parts count: {0}" -f $webPartManager.WebParts.Count)

	$fileName = ExportWebPartByWebPartManager $web $webPartManager $webPartTitle
	
	$web.Dispose > $null
	return $fileName
}

function ExportWebPartByWebPartManager($web, $webPartManager, $webPartTitle)
{
	Write-Host $("Getting web part by title '{0}'..." -f $webPartTitle) -ForegroundColor Gray
	$webPart = GetWebPartByTitle $webPartManager $webPartTitle
	
	if (!$webPart)
	{
		Write-Host $("Can't find web part with display title: {0}" -f $webPartTitle) -ForegroundColor Red
		Write-Host $MSG_OPERATION_TERMINATED -ForegroundColor Red
		exit;
	}
	
	Write-Host $("Web part ID: {0}" -f $webPart.ID)

	return ExportWebPartByWebPartUnknownExpMode $web $webPartManager $webPart
}

function ExportWebPartByWebPartUnknownExpMode($web, $webPartManager, $webPart)
{
	$currentExpMode = $webPart.ExportMode;
	$targetExpMode = "All"
	
	if ($currentExpMode -ne $targetExpMode)
	{
		$webPart.ExportMode = $targetExpMode
		$webPartManager.SaveChanges($webPart)
		
		$fileName = ExportWebPartByWebPart $web $webPartManager $webPart
		
		$webPart.ExportMode = $currentExpMode
		$webPartManager.SaveChanges($webPart)
	}
	else
	{
		$fileName = ExportWebPartByWebPart $web $webPartManager $webPart
	}
	
	return $fileName
}

function ExportWebPartByWebPart($web, $webPartManager, $webPart)
{
	Write-Host $("Exporting web part ...") -ForegroundColor Gray
	$fileName = "$Env:temp\"+$webPartTitle+"_"+[System.Guid]::NewGuid().ToString()+".webpart"
	ExportWebPart $webPartManager $webPart $fileName
	if (Test-Path $fileName)
	{
		Write-Host $("File created: {0}" -f $fileName)
	}
	
	Write-Host $MSG_LINE
	UpdateExportedWebPart $web $fileName
	#$web.Dispose;
	
	return $fileName
}

function GetWebPartByTitle($webPartManager, $webPartTitle)
{
	$webPart = $null;
	foreach ($wp in $webPartManager.WebParts)
	{
		if ($wp.DisplayTitle -eq $webPartTitle)
		{
			$webPart = $wp;
			break;
		}
	}
	#$webPart = $webPartManager.WebParts | ? {$_.DisplayTitle -eq $webPartTitle} 
	
	if ($webPart -eq $null)
	{
		Write-Host "Available page web part list:" -ForegroundColor Gray
		foreach ($wp in $webPartManager.WebParts)
		{
			Write-Host "   " $wp.DisplayTitle
		}
	}
	
	return $webPart;
}

function ExportWebPart($webPartManager, $webPart, $destFileName)
{
	$enc = [System.Text.Encoding]::UTF8
	[System.Xml.XmlTextWriter]$writer = New-Object -TypeName "System.Xml.XmlTextWriter" -ArgumentList $fileName, $enc
	$writer.Indentation = 1
	$writer.IndentChar = " "
	$writer.Formatting = [System.Xml.Formatting]::Indented
	$webPartManager.ExportWebPart($webPart, $writer)
	$writer.Close() 
}

function UpdateExportedWebPart($web, $webPartFileName)
{
	$xmlDoc = [xml](gc $webPartFileName)
	$propNode = $xmlDoc.GetElementsByTagName("properties").Item(0)

	foreach ($prop in $propNode.ChildNodes)
	{
		if($prop.GetAttribute("name") -eq "WebId")
		{
			#Write-Host "WebId updating ..."
			#Write-Host "Old value:" $prop.get_InnerText() -ForegroundColor Cyan
			#Write-Host "New value:" $web.ID.ToString() -ForegroundColor Cyan
			$prop.InnerText = $web.ID.ToString()
			$xmlDoc.Save($webPartFileName)
			break
		}
	} 	
}

function ImportWebPartByUrl($destWebUrl, $destPageRelativeUrl, $fileName, $destWebPartZone)
{
	Write-Host "Getting dest web by url ..." -ForegroundColor Gray
	$web = Get-SPWeb $destWebUrl
	Write-Host $("Web title: {0}" -f $web.Title) -ForegroundColor DarkGreen

	Write-Host $("Getting dest limited web part manager by page relative url '{0}'..." -f $destPageRelativeUrl) -ForegroundColor Gray
	$webPartManager = $web.GetLimitedWebPartManager($destPageRelativeUrl, [System.Web.UI.WebControls.Webparts.PersonalizationScope]::Shared);
	Write-Host $("Limited web part manager web parts count: {0}" -f $webPartManager.WebParts.Count) -ForegroundColor DarkGreen

	Write-Host $("Importing web part from file {0}..." -f $fileName) -ForegroundColor Gray
	ImportWebPartByWebPartManager $destPageRelativeUrl $webPartManager $fileName $destWebPartZone
	$web.Dispose > $null
}

function ImportWebPartByWebPartManager($destFileRelativeUrl, $webPartManager, $sourceFileName, $destWebPartZone)
{
	[System.Xml.XmlTextReader]$reader = New-Object -TypeName "System.Xml.XmlTextReader" -ArgumentList $sourceFileName
	$errorMsg = "";
	
	$destFile = $webPartManager.Web.GetFile($destFileRelativeUrl);
	$destItem = $destFile.Item;
	if($destFile.CheckOutType -eq "None" -And $destFile.LockType -eq "None") 
	{
	   $destFile.CheckOut()
	} 
	$webPart = $webPartManager.ImportWebPart($reader, [ref]$errorMsg) -as [Microsoft.SharePoint.WebPartPages.WebPart];	
	ImportWebPartByWebPart $webPartManager $webPart $destFile $destItem $destWebPartZone
}

function ImportWebPartByWebPart($webPartManager, $webPart, $destFile, $destItem, $destWebPartZone)
{
	$WP_INDEX = 0
	
	if ($destItem -ne $null)
	{
		ImportWebPartToLibraryPage $webPartManager $webPart $destItem $destWebPartZone
		UpdateLibraryPage $destItem
	}
	else # default.aspx
	{
		$webPartManager.AddWebPart($webPart, $destWebPartZone, $WP_INDEX);
		UpdateRootDefaultPage $destFile
	}
}

function ImportWebPartToLibraryPage($webPartManager, $webPart, $destItem, $destWebPartZone)
{
	$WP_INDEX = 0

	# wiki
	if ($destItem.ContentTypeId.Parent.ToString() -eq $WIKI_CONTENT_TYPE) 
	{
		ImportWebPartToWiki $webPartManager $webPart $destItem
	}
	else # web part page or publishing page
	{
		$webPartManager.AddWebPart($webPart, $destWebPartZone, $WP_INDEX);
	}
}

function ImportWebPartToWiki($webPartManager, $webPart, $destItem)
{
	$WIKI_CONTENT = '<div class="ms-rtestate-read ms-rte-wpbox" contentEditable="false"><div class="ms-rtestate-read {0}" id="div_{0}"></div><div style="display:none" id="vid_{0}"></div></div>';
	$WIKI_WP_ZONE = "wpz"
	$WP_INDEX = 0

	$webPartManager.AddWebPart($webPart, $WIKI_WP_ZONE, $WP_INDEX);
	$webPartGuid = $webPart.ID.Replace('_', '-').Substring(2);
	$content = $WIKI_CONTENT -f $webPartGuid
	$destItem[[Microsoft.SharePoint.SPBuiltInFieldId]::WikiField]= $content+$destItem[[Microsoft.SharePoint.SPBuiltInFieldId]::WikiField];
}