<project name="BuildJavaScript" default="build">
	<!--
		Build the scripts for a given implementation. The resulting scripts will contain:
		1. All the scripts from "common" AND
		2. All the scripts for the specific implementation.

		This build must be called with the name of the implementation rootdir set in property:
		"implementation.name". If not set then the scripts from "common" alone will be used.
	-->
	<import file="build-import.xml"/>

	<property name="script.tmp.src.dir" location="${tmp.dir}/src"/>
	<property name="script.rootdir" location="${common.src.rootdir}/js"/>
	<property name="impl.script.rootdir" location="${impl.src.main.dir}/js"/>
	<property name="script.build.target.dir" location="${target.rootdir}/${script.target.dir.name}"/>

	<target name="build"
		depends="init, copySrc, optimizeJS, copyLibs"
		description="Builds Javascript artifacts and minifies them">
	</target>

	<target name="clean" description="Cleans up all artifacts produced by this build">
		<delete dir="${script.debug.build.target.dir}"/>
		<delete dir="${script.build.target.dir}"/>
		<delete dir="${script.tmp.src.dir}"/>
		<echo message="Clean from ${ant.file}"/>
	</target>

	<target name="init" depends="clean">
		<property file="${properties.build.constants}"/>
		<mkdir dir="${script.debug.build.target.dir}"/>
		<mkdir dir="${script.build.target.dir}"/>
		<mkdir dir="${script.tmp.src.dir}"/>
	</target>

	<!--
		Make a copy of the source which the rest of the build will use.
		This is the phase where we replace properties etc.
		Most importantly, this also allows the implementation files to overwrite the core files
		of the same name so the rest of the build script doesn't need to worry about that.

		NOTE: we are copying some externals here so that they are available when building the layer wc/common.
	-->
	<target name="copySrc">
		<!-- Note, this is done in two "copy" steps to work around ANT bugs -->
		<stopwatch name="copySrc" action="start"/>
		<property name="lib.tmp.src.dir" location="${script.tmp.src.dir}/lib"/>
		<copy file="${basedir}/node_modules/requirejs/require.js" tofile="${lib.tmp.src.dir}/require.js"/>
		<copy todir="${lib.tmp.src.dir}/getusermedia-js" overwrite="true">
			<fileset dir="${basedir}/node_modules/getusermedia-js/dist">
				<include name="**/*"/>
			</fileset>
		</copy>
		<copy file="${basedir}/node_modules/i18next/i18next.js" tofile="${lib.tmp.src.dir}/i18next.js"/><!-- This is AMD and will be uglified -->
		<copy file="${basedir}/node_modules/i18next-xhr-backend/i18nextXHRBackend.js" tofile="${lib.tmp.src.dir}/i18nextXHRBackend.js"/><!-- This is AMD and will be uglified -->
		<copy file="${basedir}/node_modules/sprintf-js/src/sprintf.js" tofile="${lib.tmp.src.dir}/sprintf.js"/>
		<copy file="${basedir}/node_modules/timezone-js/src/date.js" tofile="${lib.tmp.src.dir}/date.js"/>
		<copy file="${basedir}/node_modules/requirejs-domready/domReady.js" tofile="${lib.tmp.src.dir}/requirejs/domReady.js"/>
		<copy todir="${lib.tmp.src.dir}/dojo" overwrite="true">
			<fileset dir="${basedir}/node_modules/dojo">
				<include name="domReady.js"/>
				<include name="sniff.js"/>
				<include name="has.js"/>
			</fileset>
		</copy>
		<copy todir="${lib.tmp.src.dir}/mustache" overwrite="true">
			<fileset dir="${basedir}/node_modules/mustache" includes="**/*.js">
				<exclude name="*wrappers*"/>
			</fileset>
		</copy>
		<copy todir="${lib.tmp.src.dir}/handlebars" overwrite="true">
			<fileset dir="${basedir}/node_modules/handlebars/dist/amd"/>
		</copy>
		<!-- main js -->
		<copy todir="${script.tmp.src.dir}" overwrite="true">
			<fileset dir="${script.rootdir}" includes="**/*.js"/>
			<filterchain>
				<expandproperties/>
			</filterchain>
		</copy>
		<!-- implementation js -->
		<copy todir="${script.tmp.src.dir}" overwrite="true">
			<fileset dir="${impl.script.rootdir}" includes="**/*.js" erroronmissingdir="false"/>
			<filterchain>
				<expandproperties/>
			</filterchain>
		</copy>

		<javascript.lint jsdir="${script.tmp.src.dir}"/>
		<stopwatch name="copySrc" action="total"/>
	</target>

	<target name="copyLibs">
		<!--
			Syncs directories from "scripts" to "scripts_debug".
		-->
		<property name="lib.build.target.dir" location="${script.build.target.dir}/lib"/>
		<property name="lib.debug.build.target.dir" location="${script.debug.build.target.dir}/lib"/>
		<copy todir="${lib.build.target.dir}/tinymce" >
			<fileset dir="${basedir}/node_modules/tinymce" includes="**">
				<exclude name="*jquery*"/>
			</fileset>
		</copy>
		<copy todir="${lib.build.target.dir}/mustache" >
			<fileset dir="${basedir}/node_modules/mustache" includes="**">
				<exclude name="*wrappers*"/>
			</fileset>
		</copy>
		<copy todir="${lib.build.target.dir}/tracking" >
			<fileset dir="${basedir}/node_modules/tracking" includes="build/**"/>
		</copy>
		<copy todir="${lib.build.target.dir}/bower_components" failonerror="false"><!-- Optionally copy any bower components to the lib dir -->
			<fileset dir="${basedir}/bower_components" includes="**"/>
		</copy>
		<copy file="${basedir}/node_modules/promise-polyfill/Promise.min.js" tofile="${lib.build.target.dir}/Promise.min.js"/>
		<copy file="${basedir}/node_modules/axe-core/axe.min.js" tofile="${lib.build.target.dir}/axe.min.js"/>
		<for param="dir">
			<dirset dir="${lib.build.target.dir}">
				<include name="*"/>
			</dirset>
			<sequential>
				<var name="dir.name" unset="true"/>
				<basename property="dir.name" file="@{dir}"/>
				<if>
					<not>
						<available file="${lib.debug.build.target.dir}/${dir.name}" type="dir"/>
					</not>
					<then>
						<copy todir="${lib.debug.build.target.dir}/${dir.name}">
							<fileset dir="@{dir}"/>
						</copy>
					</then>
				</if>
			</sequential>
		</for>
		<for param="file">
			<fileset dir="${lib.build.target.dir}">
				<include name="*"/>
			</fileset>
			<sequential>
				<var name="file.name" unset="true"/>
				<basename property="file.name" file="@{file}"/>
				<if>
					<not>
						<available file="${lib.debug.build.target.dir}/${file.name}" type="file"/>
					</not>
					<then>
						<copy todir="${lib.debug.build.target.dir}">
							<fileset file="@{file}"/>
						</copy>
					</then>
				</if>
			</sequential>
		</for>
	</target>

	<property name="r.js" value="${basedir}/node_modules/requirejs/bin/r.js" />
	<property name="js.build" value="build-js.js" />
	<property name="optimized.script.tmp.src.dir" location="${tmp.dir}/rjs_output"/>

	<target name="optimizeJS" description="Combine and minify files.">
		<stopwatch name="optimizeJS" action="start"/>

		<pathconvert targetos="unix" property="optimized.script.tmp.src.dir.unix">
			<path>
				<pathelement location="${optimized.script.tmp.src.dir}"/>
			</path>
		</pathconvert>
		<writeRjsConfig optimizer="uglify2"/>
		<echo>node ${r.js} -o ${tmp.dir}${file.separator}build-js.js</echo>
		<nodejs.exec failonerror="true" cwd="${target.rootdir}">
			<arguments>
				<arg value="${r.js}"/>
				<arg value="-o"/>
				<arg value="${tmp.dir}${file.separator}build-js.js"/>
			</arguments>
		</nodejs.exec>
<!--		<copy todir="${script.debug.build.target.dir}">
			 Copy the unminified files produced by r.js + uglify2 to the target directory, renaming them to what we expect.
			<fileset dir="${optimized.script.tmp.src.dir}" includes="**/*.js.src.js"/>
			<globmapper from="*.js.src.js" to="*.js"/>
		</copy>
		<copy todir="${script.debug.build.target.dir}">
			 Copy the unminified files produced by r.js + closure compiler to the target directory, renaming them to what we expect.
			<fileset dir="${optimized.script.tmp.src.dir}" includes="**/*.js.src"/>
			<globmapper from="*.js.src" to="*.js"/>
		</copy>-->
		<copy todir="${script.debug.build.target.dir}">
			<!-- Copy the unminified files to the target directory -->
			<fileset dir="${script.tmp.src.dir}" includes="**/*"/>
		</copy>
		<copy todir="${script.build.target.dir}">
			<!-- Copy the minified files to the target directory. -->
			<fileset dir="${optimized.script.tmp.src.dir}" includes="**/*"/>
		</copy>
		<stopwatch name="optimizeJS" action="total"/>
	</target>

	<!--
	Why are some of the paths "empty:"? They are used in debug mode (therefore never need to be added to the layer) or
	are polyfills which should never be added to the layer.
	-->
	<macrodef name="writeRjsConfig">
		<attribute name="optimizer"/>
		<sequential>
			<echo file="${tmp.dir}/build-js.js">
({
	preserveLicenseComments: false,
	appDir: "src",
	baseUrl: ".",
	optimize: "@{optimizer}",
	optimizeAllPluginResources: true,
	generateSourceMaps: false,
	dir: "${optimized.script.tmp.src.dir.unix}",
	modules: [{
		name: "wc/common"
	}],
	paths: {
		tinyMCE: "lib/tinymce/tinymce.min",
		Promise: "empty:",
		fabric: "lib/fabric",
		axs: "empty:",
		axe: "empty:"
		}
})
			</echo>
		</sequential>
	</macrodef>

</project>

