<project name="BuildCss" default="build" >
	<!--
		Build the CSS (from Sass in SCSS format) for a given implementation.

		This build must be called with the name of the implementation rootdir set in property "implementation.name". If
		 not set then the css from "wcomponents-theme" alone will be used.

		build-images.xml and build-resource.xml needs to be called before this build so that the base64
		task can find images and webfonts to embed
	-->
	<import file="build-import.xml" />
	<property name="excludesfile" location="${impl.src.dir}/excludes.txt"/>
	<!--
		Temp directories used in the build for copy and Sass compile. The copy step is necessary for implementation
		over-rides and ANT property replacement.
	-->
	<!-- The directory into which we place the mon-partial and non-lib Sass files. These will be concated before transpiling. -->
	<property name="sass.concat.dir" location="${tmp.dir}/sass-unbuilt" />
	<!-- The destination directory for CSS after transpile but before base64 encoding media and compression. -->
	<property name="css.tmp.target.dir" location="${tmp.dir}/css-built" />
	<!-- where the Sass source is found. -->
	<property name="sass.rootdir" location="${common.src.rootdir}/sass" />
	<!-- where the Sass for a child implementation is found (if set). -->
	<property name="impl.sass.rootdir" location="${impl.src.main.dir}/sass" />
	<property name="sass.tmp.src.dir" location="${tmp.dir}/sass" />
	<!-- final destination for built CSS. -->
	<property name="css.build.target.dir" location="${target.rootdir}/${css.target.dir.name}"/>
	<!-- The name of the concated main Sass file. The others are autogenerated as they are needed -->
	<property name="wc-main-sass-concated" location="${sass.tmp.src.dir}/${css.target.file.name}${debug.target.file.name.suffix}.scss" />

	<target name="build" depends="init, copySassSrc, concatSass, compileSass, minify" description="Builds CSS artifacts then minifies them"> </target>

	<target name="minify" depends="imagesToDataUrl">
		<stopwatch name="minifyCss" action="start" />
		<for param="file">
			<fileset dir="${css.build.target.dir}">
				<include name="*${debug.target.file.name.suffix}.css" />
			</fileset>
			<sequential>
				<var name="base.name" unset="true" />
				<var name="css.name" unset="true" />
				<basename property="base.name" file="@{file}" />
				<!-- base.name is now the file name without the path -->
				<copy file="@{file}" todir="${tmp.dir}" overwrite="true" />
				<propertyregex property="css.name" input="${base.name}"
								regexp="(.+)${debug.target.file.name.suffix}.css"
								select="\1"
								casesensitive="false" />
				<!-- css.name is now the file name without the ${debug.target.file.name.suffix}.css bit -->
				<minify sourceFile="${tmp.dir}/${base.name}" destFile="${css.build.target.dir}/${css.name}.css" />
			</sequential>
		</for>
		<stopwatch name="minifyCss" action="total" />
	</target>

	<target name="clean" description="Cleans up all artifacts produced by this build">
		<delete dir="${css.build.target.dir}" />
		<delete dir="${sass.concat.dir}" />
		<delete dir="${sass.tmp.src.dir}" />
		<delete dir="${css.tmp.target.dir}" />
	</target>

	<target name="init" depends="clean">
		<property file="${properties.build.constants}" />
		<mkdir dir="${css.build.target.dir}" />
		<mkdir dir="${sass.concat.dir}" />
		<mkdir dir="${sass.tmp.src.dir}" />
		<mkdir dir="${css.tmp.target.dir}" />
		<tempfile property="style.excludesfile.dynamic" destdir="${tmp.dir}" createfile="true" deleteonexit="true" />
	</target>

	<!--
		Concat the Sass files.
		The order matters here as each "pattern" is then auto-excluded from the following
	-->
	<target name="concatSass">
		<!-- CSS used in debug mode. -->
		<concatSassSet pattern="debug*" targetFile="wcdebug" />
		<!-- ie.* Sass -->
		<gatherIeVersionInfo />
		<for list="${ie.version.list}" param="version">
			<sequential>
				<concatSassSet pattern="@{version}" targetFile="${css.target.file.name}.@{version}" />
			</sequential>
		</for>
		<!-- other browser/platform Sass -->
		<getPlatforms sourceDir="${sass.concat.dir}" />
		<for list="${platform.list}" param="platform">
			<sequential>
				<concatSassSet pattern="@{platform}" targetFile="${css.target.file.name}.@{platform}" />
			</sequential>
		</for>
		<!--
			The rest of the CSS in one big file.
			TODO: we eventually want to have per-component CSS is we are not optimizing for http1.
		-->
		<!-- wc.import.scss is for fixed CSS imports so **MUST** be first in the output. -->
		<copy file="${sass.concat.dir}/wc.import.scss"
			tofile="${wc-main-sass-concated}" overwrite="true" quiet="yes" />
		<!-- OK, so here I am calling concat multiple times instead of using multiple filesets. This is to ensure the correct order. -->
		<concat destfile="${wc-main-sass-concated}" fixlastline="yes" encoding="UTF-8" append="true">
			<!-- themes may have fixed imports too using *.import.scss -->
			<fileset dir="${sass.concat.dir}" includes="*.import.scss" excludes="wc.import.scss"/>
		</concat>
		<concat destfile="${wc-main-sass-concated}" fixlastline="yes" encoding="UTF-8" append="true">
			<!-- in CSS source order matters so do wc default CSS before implementation CSS. -->
			<fileset dir="${sass.concat.dir}" includes="wc.*.scss" excludes="*.import.scss">
				<excludesfile name="${style.excludesfile.dynamic}" />
			</fileset>
		</concat>
		<concat destfile="${wc-main-sass-concated}" fixlastline="yes" encoding="UTF-8" append="true">
			<fileset dir="${sass.concat.dir}" includes="*.scss" excludes="wc.*.scss, *.import.scss">
				<excludesfile name="${style.excludesfile.dynamic}" />
			</fileset>
		</concat>
		<!--<concat destfile="${wc-main-sass-concated}" fixlastline="yes" encoding="UTF-8" append="true">
			<fileset dir="${sass.concat.dir}" includes="*.import.scss" excludes="wc.import.scss"/>
			<fileset dir="${sass.concat.dir}" includes="wc.*.scss" excludes="*.import.scss">
				<excludesfile name="${style.excludesfile.dynamic}" />
			</fileset>
			<fileset dir="${sass.concat.dir}" includes="*.scss" excludes="wc.*.scss, *.import.scss">
				<excludesfile name="${style.excludesfile.dynamic}" />
			</fileset>
		</concat>-->
	</target>

	<!--
		Make a copy of the source which the rest of the build will use. This also 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 use multiple copies here because there appears to be an ANT bug which changes the path order and fails to
		overwrite correctly.
	-->
	<target name="copySassSrc">
		<!-- wcomponents-theme SCSS -->
		<copy todir="${sass.tmp.src.dir}" overwrite="true" quiet="true">
			<fileset dir="${sass.rootdir}" includes="**/_*.scss, **/lib/**" excludesfile="${excludesfile}" />
		</copy>
		<copy todir="${sass.concat.dir}" overwrite="true" quiet="true">
			<fileset dir="${sass.rootdir}" includes="**/*.scss" excludes="**/_*.scss, **/lib/**" excludesfile="${excludesfile}" />
		</copy>

		<!-- Implementation SCSS -->
		<copy todir="${sass.tmp.src.dir}" overwrite="true" quiet="true">
			<fileset dir="${impl.sass.rootdir}" includes="**/_*.scss, **/lib/**" erroronmissingdir="false" />
		</copy>
		<copy todir="${sass.concat.dir}" overwrite="true" quiet="true">
			<fileset dir="${impl.sass.rootdir}" includes="**/*.scss" excludes="**/_*.scss, **/lib/**" erroronmissingdir="false"/>
		</copy>
	</target>

	<!--
		Compile Sass to CSS using Vaadin Sass-compiler wrapped by SassTask for efficiency.
	-->
	<target name="compileSass">
		<stopwatch name="compileSass" action="start" />
		<taskdef name="sass" classname="com.github.bordertech.wcomponents.sass.SassTask" classpathref="project.class.path"/>
		<sass in="${sass.tmp.src.dir}" out="${css.tmp.target.dir}" urlmode="absolute"/>
		<stopwatch name="compileSass" action="total" />
	</target>

	<!--
		Trawl the copied (and transpiled) source and find files with pattern_X in their names. Make a list of all these
		patterns and write them to a property for future use in JS.
	-->
	<macrodef name="getPlatforms">
		<attribute name="sourceDir"/>
		<sequential>
			<var name="platform.list" value=""/>
			<for param="file">
				<fileset dir="@{sourceDir}" includes="*.scss" excludes="_*.scss">
					<filename regex="\.pattern_[^\.]+\."/>
				</fileset>
				<sequential>
					<var name="platform.name" unset="true"/>
					<var name="platform.version" unset="true"/>
					<basename suffix=".scss" property="platform.name" file="@{file}"/>
					<propertyregex property="platform.version"
						input="${platform.name}"
						regexp="\.pattern_(.+)$"
						select="\1"
						casesensitive="false" />
					<if>
						<not>
							<contains string="${platform.list}" substring="${platform.version}"/>
						</not>
						<then>
							<if>
								<length string="${platform.list}" length="0"/>
								<then>
									<var name="platform.list" value="${platform.version}"/>
								</then>
								<else>
									<var name="platform.list" value="${platform.list},${platform.version}"/>
								</else>
							</if>
						</then>
					</if>
				</sequential>
			</for>
			<propertyfile file="${properties.build.constants}">
				<entry key="css.pattern.list" value="${platform.list}"/>
			</propertyfile>
		</sequential>
	</macrodef>

	<macrodef name="concatSassSet">
		<attribute name="pattern" />
		<attribute name="targetFile" />
		<attribute name="append" default="false"/>
		<sequential>
			<var name="concat-file-name" value="${sass.tmp.src.dir}/@{targetFile}${debug.target.file.name.suffix}.scss"/>
			<concat destfile="${concat-file-name}" fixlastline="yes" overwrite="true">
				<fileset dir="${sass.concat.dir}" includes="wc.*@{pattern}.scss">
					<excludesfile name="${style.excludesfile.dynamic}" />
				</fileset>
			</concat>
			<concat destfile="${concat-file-name}" fixlastline="yes" append="true">
				<fileset dir="${sass.concat.dir}" includes="*@{pattern}.scss" excludes="wc.*.@{pattern}.scss">
					<excludesfile name="${style.excludesfile.dynamic}" />
				</fileset>
			</concat>
			<!--<concat destfile="${concat-file-name}" fixlastline="yes" overwrite="true">
				<fileset dir="${sass.concat.dir}" includes="wc.*@{pattern}.scss">
					<excludesfile name="${style.excludesfile.dynamic}" />
				</fileset>
				<fileset dir="${sass.concat.dir}" includes="*@{pattern}.scss" excludes="wc.*.@{pattern}.scss">
					<excludesfile name="${style.excludesfile.dynamic}" />
				</fileset>
			</concat>-->
			<simpleAddPatternToExcludes pattern="*@{pattern}.scss" destfile="${style.excludesfile.dynamic}" />
		</sequential>
	</macrodef>

	<macrodef name="minify">
		<attribute name="sourceFile" />
		<attribute name="destFile" />
		<sequential>
			<property name="cleancss.executable" location="${basedir}/node_modules/clean-css/bin/cleancss"/>
			<echo>node ${cleancss.executable} --skip-import --skip-aggressive-merging --skip-rebase --rounding-precision -1 -o @{destFile} @{sourceFile}</echo>
			<nodejs.exec failonerror="true" cwd="${target.rootdir}">
				<arguments>
					<arg value="${cleancss.executable}"/>
					<arg value="--skip-import"/>
<!--					<arg value="-\-skip-advanced"/>-->
					<arg value="--skip-aggressive-merging"/>
<!--					<arg value="-\-skip-media-merging"/>-->
					<arg value="--skip-rebase"/>
<!--					<arg value="-\-skip-restructuring"/>
					<arg value="-\-skip-shorthand-compacting"/> -->
					<arg value="--rounding-precision"/>
					<arg value="-1"/>
					<arg value="-o"/>
					<arg value="@{destFile}"/>
					<arg value="@{sourceFile}"/>
				</arguments>
			</nodejs.exec>
		</sequential>
	</macrodef>

	<!-- NOTE: base64 encoding of svg is not supported in firefox before version 5 -->
	<target name="imagesToDataUrl" description="Convert images urls to base64 data urls in CSS files">
		<if>
			<and>
				<istrue value="${build.optimise.http1}"/>
				<istrue value="${images.to.base64.dataurls}" />
			</and>
			<then>
				<stopwatch name="imagesToDataUrl" action="start" />
				<!--
					IE7 and IE6 - why are these still in the build scripts?
					It may be offensive to thine eye but not so fast with the delete key...
					Regardless of what WComponents supports we should always leave these ie7 and ie6
					excludes in place to facilitate any users of WComponents adding legacy support.
					Remember that the implementation mechanism does not allow custom build scripts,
					so the build scripts need to cater for it all.
					The fact that IE7 and earlier did not support data URLs is a constant that won't
					change and can therefore be safely hardcoded in place here.
				-->
				<nodejs.exec failonerror="true" cwd="${target.rootdir}">
					<arguments>
						<arg value="${component.rootdir}/base64.js"/>
						<arg value="${target.rootdir}"/>
						<arg value="${css.target.file.name}ie6${debug.target.file.name.suffix}.css,${css.target.file.name}ie7${debug.target.file.name.suffix}.css"/>
						<arg value="${css.tmp.target.dir}"/>
						<arg value="${css.build.target.dir}"/>
					</arguments>
				</nodejs.exec>
				<!-- copy the legacy stuff -->
				<copy todir="${css.build.target.dir}" overwrite="true">
					<fileset dir="${css.tmp.target.dir}">
						<include name="${css.target.file.name}ie6${debug.target.file.name.suffix}.css" />
						<include name="${css.target.file.name}ie7${debug.target.file.name.suffix}.css" />
					</fileset>
				</copy>
				<stopwatch name="imagesToDataUrl" action="total" />
			</then>
			<else>
				<copy todir="${css.build.target.dir}" overwrite="true">
					<fileset dir="${css.tmp.target.dir}" includes="*.css" />
				</copy>
			</else>
		</if>
	</target>

	<!--
		Sets the property ie.version.list with a list of the versions of ie specific source files in the sourceDir
		 For example if you have: foo.ie8.scss, bar.ie8.scss, bar.ie9.scss files in your sourceDir you will get a list like this: "ie8,ie9"
	-->
	<macrodef name="gatherIeVersionInfo">
		<sequential>
			<var name="ie.version.list" value=""/>
			<for param="file">
				<fileset dir="${sass.concat.dir}" includes="*.scss">
					<filename regex="\.ie[0-9]{1,2}\."/>
				</fileset>
				<sequential>
					<var name="base.name" unset="true"/>
					<var name="ie.version" unset="true"/>
					<basename suffix=".scss" property="base.name" file="@{file}"/><!-- base.name is now the file name without the path and the extension -->
					<propertyregex property="ie.version"
						input="${base.name}"
						regexp="^.+\.(.+)$"
						select="\1"
						casesensitive="false" />
					<if>
						<not>
							<contains string="${ie.version.list}" substring="${ie.version}"/>
						</not>
						<then>
							<if>
								<length string="${ie.version.list}" length="0"/>
								<then>
									<var name="ie.version.list" value="${ie.version}"/>
								</then>
								<else>
									<var name="ie.version.list" value="${ie.version.list},${ie.version}"/>
								</else>
							</if>
						</then>
					</if>
				</sequential>
			</for>
			<propertyfile file="${properties.build.constants}">
				<entry key="ie.css.list" value="${ie.version.list}"/>
			</propertyfile>
		</sequential>
	</macrodef>

	<macrodef name="simpleAddPatternToExcludes">
		<attribute name="destfile"/>
		<attribute name="pattern"/>
		<sequential>
			<echo message="${line.separator}@{pattern}" append="true" file="@{destfile}"/>
		</sequential>
	</macrodef>
</project>
