<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY nbsp   "&#160;">
<!ENTITY lsaquo   "&#8249;">
<!ENTITY rsaquo   "&#8250;">
<!ENTITY laquo  "&#171;">
<!ENTITY raquo  "&#187;">
<!ENTITY copy   "&#169;">
]>
<xsl:stylesheet version="3.0"
				xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
				xmlns:xs="http://www.w3.org/2001/XMLSchema"
				xmlns:ou="http://omniupdate.com/XSL/Variables"
				xmlns:ouc="http://omniupdate.com/XSL/Variables"
				exclude-result-prefixes="xs ou ouc"
				expand-text="yes">
	
	<xsl:import href="variables.xsl"/> <!-- dmc variables -->
	<xsl:import href="snippets.xsl"/> <!-- dmc snippets -->
	
	<xsl:param name="root" select="concat($ou:root, $ou:site)" />
	
	<!-- Used to add additional data in the item node generated by the get-item function if need be. -->
	<xsl:template name="dmc-item-data" />
	
	<!-- get a single item XML -->
	<!-- has option to add custom xsl attribute to exclude it from the xml output of the file -->
	<xsl:function name="ou:get-item">
		<xsl:param name="document" />
		<item>
			<xsl:attribute name="href" select="concat($dirname, replace($ou:filename, 'xml', $extension))" />
			<xsl:attribute name="dsn" select="ou:pcf-param('dsn')" />
			<xsl:for-each select="$document/item/ouc:div[not(@xml = 'exclude')]">
				<xsl:element name="{translate(./@label, ' ', '_')}"><xsl:apply-templates select="node()[not(self::ouc:multiedit)]" /></xsl:element>
			</xsl:for-each>
			<xsl:if test="ou:pcf-param('dsn') = 'news'">
				<description><xsl:copy-of select="ou:truncate($document/ouc:div[@label='main-content'], 150, '...')"/></description>
			</xsl:if>
			<xsl:if test="$tags != ''">		
				<tags>		
					<xsl:for-each select="tokenize($tags, ',')">
						<xsl:sort select="." />
						<tag>{.}</tag>		
					</xsl:for-each>		
				</tags>		
			</xsl:if>
			<xsl:call-template name="dmc-item-data" />
		</item>
	</xsl:function>
	
	<!-- template for getting all internal items aggregated from staging or production depending on what parameters you pass in -->
	<xsl:function name="ou:get-internal-doc">
		<xsl:param name="path" />  <!-- aggregation starting path -->
		<xsl:variable name="current-path" select="concat($root, $path)" />  <!-- full aggregation path -->
		<xsl:variable name="language" select="$aggregation-language" /> <!-- Configured in variables.xsl - determines what server side language the aggregation will be using -->
		<xsl:variable name="dsn" select="if(ou:pcf-param('dsn') != '') then ou:pcf-param('dsn') else replace($ou:filename, '\..*$', '')" /> <!-- determine what dsn is to be used based on filename without extension -->
		<xsl:variable name="query-string" select="concat('?dir=', encode-for-uri(ou:pcf-param('aggregation-path')), '&#38;dsn=', $dsn)" /> <!-- determine the query string -->
		<xsl:variable name="request-location" select="concat($domain, $dmc-path)"/> <!-- determine the request location string -->
		
		<xsl:choose>
			<xsl:when test="$language = 'php'">
				<!-- path to php script -->
				<xsl:variable name="php-loc" select="concat($request-location, 'php/_core/aggregator.php', $query-string)" />
				<xsl:if test="not($is-pub)">
					<query-path><xsl:value-of select="$php-loc" /></query-path> <!-- output the query path for debugging -->
				</xsl:if>
				<xsl:copy-of select="document($php-loc)" />
			</xsl:when>
			<xsl:when test="$language = 'csharp'">
				<!-- path to c# script -->
				<xsl:variable name="c-loc" select="concat($request-location, 'cs/_core/aggregator.ashx', $query-string)" />
				<xsl:if test="not($is-pub)">
					<query-path><xsl:value-of select="$c-loc" /></query-path> <!-- output the query path for debugging -->
				</xsl:if>
				<xsl:copy-of select="document($c-loc)" />
			</xsl:when>
			<xsl:when test="$language = 'xsl'">
				<xsl:if test="not($is-pub)">
					<query-path>Aggregated via XSL. Starting path: {replace($current-path, '/$', '')}</query-path> <!-- output the query path for debugging -->
				</xsl:if>
				<items>
					<xsl:call-template name="items-with-xsl">
						<xsl:with-param name="current-path" select="replace($current-path, '/$', '')"/> <!-- current path -->
					</xsl:call-template>
				</items>
			</xsl:when>
			<xsl:otherwise>
				<p>Invalid server side language. Please verify/configure <xsl:value-of select="$language" /> is the language you want to use.</p>
			</xsl:otherwise>
		</xsl:choose>

	</xsl:function>
	
	
	<xsl:function name="ou:get-external-doc">
		<xsl:param name="external-xml-url" />
		
		<xsl:variable name="trimmed-url" select="ou:textual-content($external-xml-url)" />
		
		<xsl:choose>
			<xsl:when test="doc-available($trimmed-url)">
				<xsl:copy-of select="doc($trimmed-url)"/>
			</xsl:when>
			<xsl:otherwise>
				{error(QName('http://www.omniupdate.com', 'error'), concat('The external xml: "',$trimmed-url , '" is invalid or not accessible.'))}
			</xsl:otherwise>
		</xsl:choose>
	</xsl:function>
	
	
	<xsl:function name="ou:get-filter-predicate">
		<xsl:param name="filters" />
		<xsl:param name="filter-target" />
		
		<xsl:value-of select="ou:get-filter-predicate($filters, $filter-target, false(), true())" />
		
	</xsl:function>
	
	<xsl:function name="ou:get-filter-predicate">
		<xsl:param name="filters" />
		<xsl:param name="filter-target" />
		<xsl:param name="strict" as="xs:boolean" />
		
		<xsl:value-of select="ou:get-filter-predicate($filters, $filter-target, $strict, true())" />
		
	</xsl:function>
	
	
	<xsl:function name="ou:get-filter-predicate">
		<xsl:param name="filters" />
		<xsl:param name="filter-target" />
		<xsl:param name="strict" as="xs:boolean" />
		<xsl:param name="case-sensitive" as="xs:boolean" />
		
		
		<xsl:variable name="logical-operator" select="if($strict) then ' and ' else ' or '" />


		<xsl:variable name="case-insensitive-start">
			<xsl:if test="not($case-sensitive)">
				<xsl:text>[translate(text(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')</xsl:text>
			</xsl:if>
		</xsl:variable>

		<xsl:variable name="case-insensitive-end">
			<xsl:if test="not($case-sensitive)">
				<xsl:text>]</xsl:text>
			</xsl:if>
		</xsl:variable>

		<xsl:if test="$filters=>normalize-space()!=''">
			<xsl:text>[</xsl:text>
			<xsl:for-each select="tokenize($filters, ',')">
				<xsl:variable name="filter">
					<xsl:choose>
						<xsl:when test="$case-sensitive">
							<xsl:value-of select=".=>normalize-space()" />
						</xsl:when>
						<xsl:otherwise>
							<xsl:value-of select=".=>normalize-space()=>lower-case()" />
						</xsl:otherwise>
					</xsl:choose>
				</xsl:variable>

				<xsl:choose>
					<xsl:when test="contains($filter, '''')">
						<xsl:value-of select="$filter-target || $case-insensitive-start || '=&quot;' || $filter=>replace('&quot;', '') || '&quot;' || $case-insensitive-end" />
					</xsl:when>
					<xsl:otherwise>
						<xsl:value-of select="$filter-target || $case-insensitive-start || '=''' || $filter || '''' || $case-insensitive-end" />
					</xsl:otherwise>
				</xsl:choose>
				<xsl:if test="position() != last()">
					<xsl:value-of select="$logical-operator" />
				</xsl:if>
			</xsl:for-each>
			<xsl:text>]</xsl:text>
		</xsl:if>
	</xsl:function>
	
	
	<!-- template to grab all the item xml files from production with XSL -->
	<xsl:template name="items-with-xsl">
		<xsl:param name="current-path" /> <!-- current path -->
		<!-- calculate the current path to the production server and replace the root with the domain -->
		<xsl:variable name="domain-dir" select="concat(replace($current-path, $root, $domain), '/')" />
		<xsl:variable name="dsn" select="replace($ou:filename, '\..*$', '')" /> <!-- determine what server side language the aggregation will be using -->
		<xsl:for-each select="doc($current-path)/list/file[contains(text(),'.pcf')]">
			<xsl:variable name="file-path" select="concat($domain-dir, replace(text(), 'pcf', 'xml'))" />
			<xsl:if test="doc-available($file-path)">
				<xsl:copy-of select="doc($file-path)/item[@dsn=$dsn]" />
			</xsl:if>
		</xsl:for-each> 
		<!-- get all directories -->
		<xsl:for-each select="doc($current-path)/list/directory">
			<xsl:call-template name="items-with-xsl">
				<xsl:with-param name="current-path" select="concat($current-path,'/',text())" />
			</xsl:call-template>
		</xsl:for-each>
	</xsl:template>
	
	<xsl:template name="dmc">
		<xsl:param name="options" />
		<xsl:param name="script-name" select="'generic'" />
		<xsl:param name="debug" select="false()" />
		
		<xsl:variable name="script-path">
			<xsl:choose>
				<xsl:when test="$server-type = 'php'">
					<xsl:value-of select="$dmc-path || 'php/' || $script-name || '.php'" />
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="$dmc-path || 'cs/' || $script-name || '.ashx'" />
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		
		<xsl:choose>
			<xsl:when test="$ou:action = 'pub'">
				<xsl:variable name="double-quote">"</xsl:variable>
				<xsl:variable name="escaped-double-quote">\\"</xsl:variable>
				
				<xsl:choose>
					<xsl:when test="$server-type = 'php'">

						<xsl:processing-instruction name="php">
							include_once($_SERVER['DOCUMENT_ROOT'] . "{$script-path}");

							$options = array();
							<xsl:for-each select="$options/node()">
								$options["{name()}"] = "<xsl:value-of select="replace(text(), $double-quote, $escaped-double-quote)" disable-output-escaping="yes" />";
							</xsl:for-each>

							get_{$script-name}_dmc_output($options);

							?</xsl:processing-instruction>
					</xsl:when>
					<xsl:otherwise>
						<xsl:text disable-output-escaping="yes" expand-text="no">&lt;% </xsl:text>
							
							<xsl:variable name="option-notation">
								<xsl:for-each select="$options/node()" expand-text="no">
									<option>{"<xsl:value-of select="name()" />","<xsl:value-of select="replace(text(), $double-quote, $escaped-double-quote)" />"}</option>
								</xsl:for-each>
							</xsl:variable>
						
							{$script-name}.GetDMCOutput(new NameValueCollection()<xsl:value-of select="'{' || string-join($option-notation/option, ',') || '}'" disable-output-escaping="yes" />);
						<xsl:text disable-output-escaping="yes" expand-text="no">%&gt;</xsl:text>
					</xsl:otherwise>
				</xsl:choose>
				
			</xsl:when>
			<xsl:otherwise>

				<xsl:variable name="querystring">
					<xsl:for-each select="$options/node()">
						<xsl:value-of select="name() || '=' || encode-for-uri(text())" />
						<xsl:if test="position()!=last()">&amp;</xsl:if>
					</xsl:for-each>
				</xsl:variable>
				
				<xsl:variable name="script-url" select="$domain || $script-path || '?' || $querystring" />
				
				<xsl:if test="$debug">
					<xsl:variable name="available-options" select="tokenize('datasource,distinct,items_per_page,json_always_array,max,max_page_links,metadata,page,querystring_control,returntype,search_case_sensitive,search_columns,search_phrase,select,sort,type,xpath', ',')" />
					
					<br />
					<div class="panel">
						<xsl:element name="style" expand-text="no">
							.dmc-debug { display: none; }
						</xsl:element>
						<xsl:element name="script" expand-text="no">
							var dmc = {
								toggleDebug: function(){
									var displayLabel = event.currentTarget.children[0];
									var debugInfo = event.currentTarget.parentElement.parentElement.nextElementSibling;
									var debugVisible = debugInfo.style.display == 'block';
									
									if(debugVisible){
										debugInfo.style.display = 'none';
										displayLabel.innerHTML = 'Show Details';
									}else{
										debugInfo.style.display = 'block';
										displayLabel.innerHTML = 'Hide Details';
									}
									event.preventDefault();
									event.stopPropagation();
								}
							};
						</xsl:element>

						<h5><strong><a href="#" onclick="dmc.toggleDebug();">Debug Info (<span>Show Details</span>)</a></strong></h5>
						<div class="dmc-debug">
							<p style="word-break: break-all;"><strong>DMC API Endpoint:</strong> <br/> <a href="{$script-url}" target="_blank"><xsl:value-of select="$script-url" /></a></p>
							<p style="word-break: break-all;">
								<strong>Options Used:</strong><br/>
								<xsl:for-each select="$options/node()">
									<xsl:sort select="name()" />
									{name()} = "{text()}"<br/>
								</xsl:for-each>
							</p>
							<p style="word-break: break-all;">
								<strong>Additional Options:</strong><br/>
								<xsl:for-each select="$available-options[not(.=$options/node()/name())]">
									{.} = ""<br/>
								</xsl:for-each>
							</p>
						</div>
					</div>
				</xsl:if>
				<xsl:if test="unparsed-text-available($script-url)">
					<xsl:value-of select="unparsed-text($script-url)" disable-output-escaping="yes" />
				</xsl:if>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<!-- Coldfusion version of the dmc template -->
	<xsl:template name="cf-dmc">
		<xsl:param name="script_path" required="yes" />
		<xsl:param name="xml_path" required="yes" />
		<xsl:param name="type" required="yes" />
		<xsl:param name="items-per-page" select="''" />
		<xsl:param name="featured" select="''" />
		<xsl:param name="max" select="''" />
		<xsl:param name="tags" select="''" />
		<xsl:param name="filter" select="''" />
		<xsl:param name="manual" select="''" />
		<xsl:param name="debug" select="false()" />
		
		<xsl:choose>
			<xsl:when test="$is-pub">
				<cfscript>
					dmcURL = "{substring($ou:httproot, 1, string-length($ou:httproot) - 1) || $xml_path}";
					type = "{$type}";
					featured = "{$featured}";
					max = "{$max}";
					itemsPerPage = "{$items-per-page}";
					tags = "{$tags}";
					filter = "{$filter}";
					manual = "{$manual}";
				</cfscript>
				<xsl:copy-of select="ou:ssi($script_path)" />
			</xsl:when>
			<xsl:otherwise>
				<xsl:variable name="path">
					<xsl:text>{$script_path || '?path=' || substring($ou:httproot, 1, string-length($ou:httproot) - 1) || $xml_path || '&amp;type=' || $type}</xsl:text>
					<xsl:if test="$max != ''">
						<xsl:text>{'&amp;max=' || $max}</xsl:text>
					</xsl:if>
					<xsl:if test="$featured != ''">
						<xsl:text>{'&amp;featured=' || $featured}</xsl:text>
					</xsl:if>
					<xsl:if test="$items-per-page != ''">
						<xsl:text>{'&amp;itemsPerPage=' || $items-per-page}</xsl:text>
					</xsl:if>
					<xsl:if test="$tags != ''">
						<xsl:text>{'&amp;tags=' || encode-for-uri($tags)}</xsl:text>
					</xsl:if>
					<xsl:if test="$filter != ''">
						<xsl:text>{'&amp;filter=' || $filter}</xsl:text>
					</xsl:if>
					<xsl:if test="$manual != ''">
						<xsl:text>{'&amp;manual=' || $manual}</xsl:text>
					</xsl:if>
				</xsl:variable>
				
				<xsl:if test="$debug = true()"> {$path} </xsl:if>
				
				<xsl:call-template name="unparsed-include-file">
					<xsl:with-param name="path" select="$path" />
				</xsl:call-template>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<xsl:function name="ou:to-display-date" as="xs:string">
		<xsl:param name="dateTime"/>
		<xsl:variable name="date" select="ou:to-dateTime($dateTime || (if(string-length($dateTime) = 10) then ' 00:00:00' else ''))"/>
		<!-- Current Format: October 02, 2002 -->
		<xsl:value-of select="format-dateTime($date, '[MNn,*] [D01],  [Y0001]', 'en', 'AD', 'US')"/>
	</xsl:function>
	<xsl:function name="ou:to-dateTime" as="xs:dateTime">
		<xsl:param name="pcf-date"/>
		<!--define time zone-->
		<xsl:variable name="time-zone" select="'-08:00'"/>
		<!--tokenize date from PCF, which uses datetime param-->
		<xsl:variable name="token-date" select="tokenize($pcf-date, ' ')"/>
		<!--calculate date depending on TCF or PCF dateTime-->
		<xsl:variable name="date">
			<xsl:choose>
				<xsl:when test="matches($pcf-date,'^\S+, \S+ \d{1,2}, \d{4} \d{1,2}:\d{2}:\d{2} [AP]M [A-Z]{3}$')">
					<!--TCF format 'Monday, January 26, 2015 2:13:39 PM PST' to '2015-01-26'-->
					<xsl:value-of select="concat($token-date[4], '-', ou:month-num($token-date[2], 'long'), '-', ou:double-digit(substring-before($token-date[3], ',')))"/>
				</xsl:when>
				<xsl:otherwise>
					<!--PCF format '01/26/2015 08:26:39 PM' to '2015-01-26'-->
					<xsl:value-of select="concat(tokenize($token-date[1], '/')[3], '-', ou:double-digit(tokenize($token-date[1], '/')[1]), '-', ou:double-digit(tokenize($token-date[1], '/')[2]))"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		<xsl:variable name="time">
			<xsl:choose>
				<xsl:when test="matches($pcf-date,'^\S+, \S+ \d{1,2}, \d{4} \d{1,2}:\d{2}:\d{2} [AP]M [A-Z]{3}$')">
					<!--convert 'Monday, January 26, 2015 2:13:39 PM PST' to '2015-01-26'-->
					<xsl:value-of select="concat(ou:double-digit(if ($token-date[6] = 'PM' and number(tokenize($token-date[5], ':')[1]) &lt; 12) then number(tokenize($token-date[5], ':')[1]) + 12 else if ($token-date[6] = 'PM' and number(tokenize($token-date[5], ':')[1]) = 12) then '00' else tokenize($token-date[5], ':')[1]), ':', ou:double-digit(tokenize($token-date[5], ':')[2]), ':', ou:double-digit(tokenize($token-date[5], ':')[3]))"/>
				</xsl:when>
				<xsl:otherwise>
					<!--convert '01/26/2015 08:26:39 PM' to '20:26:39'-->
					<xsl:value-of select="concat(ou:double-digit(if ($token-date[3] = 'PM' and number(tokenize($token-date[2], ':')[1]) &lt; 12) then number(tokenize($token-date[2], ':')[1]) + 12 else if ($token-date[3] = 'PM' and number(tokenize($token-date[2], ':')[1]) = 12) then '00' else tokenize($token-date[2], ':')[1]), ':', ou:double-digit(tokenize($token-date[2], ':')[2]), ':', ou:double-digit(tokenize($token-date[2], ':')[3]))"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		<!--new object xs:dateTime('2015-01-01T20:26:39-08:00')-->
		<xsl:value-of select="dateTime(xs:date($date), xs:time(concat($time, $time-zone)))" />
	</xsl:function>
	<xsl:function name="ou:double-digit">
		<xsl:param name="num"/>
		<xsl:value-of select="format-number(number($num), '00')"/>
	</xsl:function>
	<xsl:function name="ou:month-num">
		<xsl:param name="month-name" />
		<xsl:value-of select="ou:month-num($month-name,'long')" />    
	</xsl:function>
	<xsl:function name="ou:month-num">
		<xsl:param name="month-name" />
		<xsl:param name="length" />
		<xsl:variable name="months" select="('January','February','March','April','May','June','July','August','September','October','November','December')" />
		<xsl:variable name="months-short" select="('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')" />
		<xsl:value-of select="ou:double-digit(if ($length = 'short') then index-of($months-short,$month-name) else index-of($months,$month-name))" />
	</xsl:function>

	<!-- TRUNCATE TEXT -->
	<xsl:function name="ou:truncate">
		<xsl:param name="text" as="xs:string"/> <!-- the text to be truncated -->
		<xsl:param name="limit" as="xs:integer"/> <!-- the max number of chars -->
		<xsl:param name="symbol" as="xs:string"/> <!-- the symbol to show after truncating (i.e. '...') -->
		
		<xsl:choose>
			<xsl:when test="string-length(normalize-space($text)) gt $limit">
				<xsl:value-of select="concat(normalize-space(substring($text, 1, $limit - string-length($symbol))), $symbol)" />
			</xsl:when>	
			<xsl:otherwise>
				<xsl:value-of select="normalize-space($text)" />
			</xsl:otherwise>
		</xsl:choose>
	</xsl:function>

</xsl:stylesheet>
