<?xml version="1.0" encoding="UTF-8"?>

<project name="scala-examples" default="build">

  <description>
    I am SABBUS for ${ant.project.name}, the build system for the Scala compiler
    and core library. Please check the 'docs/README' file for more information
    about me.
  </description>

  <echo level="info" message="Running SABBUS for ${ant.project.name}..."/>

<!-- ===========================================================================
PROPERTIES
============================================================================ -->

  <property environment="env"/>

  <!-- Prevents system classpath from being used -->
  <property name="build.sysclasspath" value="ignore"/>

  <!-- Base properties -->
  <property name="src.dir"            value="${basedir}/docs"/>
  <property name="src.examples.dir"   value="${src.dir}/examples"/>
  <property name="lib.dir"            value="${basedir}/lib"/>
  <!-- User properties -->
  <property file="${basedir}/build.examples.properties"/>
  <!-- Location of pre-compiled libraries properties -->
  <property name="scala.lib.jar"      value="${lib.dir}/scala-library.jar"/>
  <property name="scala.comp.jar"     value="${lib.dir}/scala-compiler.jar"/>
  <property name="fjbg.name"          value="fjbg.jar"/>
  <property name="fjbg.jar"           value="${lib.dir}/${fjbg.name}"/>
  <property name="ant.jar"            value="${ant.home}/lib/ant.jar"/>
  <property name="ant-contrib.jar"    value="${lib.dir}/ant/ant-contrib.jar"/>
  <!-- -->
  <property name="build.dir"          value="${basedir}/build"/>
  <property name="build.examples.dir" value="${build.dir}/examples"/>
  <!-- tbd -->
  <property name="excludes.compile"
            value="**/*current.*,**/parsers2.*,**/typeinf.*"/>
  <property name="excludes.run"
            value="**/Parsers.*"/>

<!-- ===========================================================================
INITIALISATION
============================================================================ -->

  <target name="init" unless="init.avail">
    <tstamp prefix="start">
      <format
        property="human-time"
        pattern="EEEE, d MMMM yyyy, HH:mm:ss (zz)"
      />
    </tstamp>
    <!-- Testing if everything is in place -->
    <echo level="verbose" message="scala.lib.jar=${scala.lib.jar}"/>
    <fail message="Scala library in '${lib.dir}/' is not available">
      <condition><not><and>
        <available
          classname="scala.Predef" 
          classpath="${scala.lib.jar}"
        />
        <available
          classname="scala.List"
          classpath="${scala.lib.jar}"
        />
        <available
          classname="scala.runtime.ObjectRef"
          classpath="${scala.lib.jar}"
        />
      </and></not></condition>
    </fail>
    <echo level="verbose" message="scala.comp.jar=${scala.comp.jar}"/>
    <fail message="Scala compiler in '${lib.dir}/' is not available">
      <condition><not>
        <available
          classname="scala.tools.ant.Scalac"
          classpath="${scala.comp.jar}:${scala.lib.jar}"
        />
      </not></condition>
    </fail>
    <echo level="verbose" message="fjbg.jar=${fjbg.jar}"/>
    <fail message="FJBG library in '${lib.dir}/' is not available">
      <condition><not>
        <available
          classname="ch.epfl.lamp.fjbg.JCode"
          classpath="${fjbg.jar}"
        />
      </not></condition>
    </fail>
    <echo level="verbose" message="ant.jar=${ant.jar}"/>
    <echo level="verbose" message="ant-contrib.jar=${ant-contrib.jar}"/>
    <fail message="Additional Ant tasks in '${lib.dir}/' is not available">
      <condition><not>
        <available
          classname="net.sf.antcontrib.AntContribVersion"
          classpath="${ant-contrib.jar}"
        />
      </not></condition>
    </fail>
    <!-- Creating class-pathes -->
    <path id="common.classpath">
      <pathelement location="${fjbg.jar}"/>
    </path>
    <path id="scala.classpath">
      <pathelement location="${scala.lib.jar}"/>
      <pathelement location="${scala.comp.jar}"/>
      <path refid="common.classpath"/>
    </path>
    <!-- Creating boot-level tasks -->
    <taskdef resource="net/sf/antcontrib/antlib.xml">
      <classpath>
        <pathelement location="${ant-contrib.jar}"/>
      </classpath>
    </taskdef>
    <!-- Finding out what system architecture is being used -->
    <condition property="os.win">
      <os family="windows"/>
    </condition>
    <if><isset property="os.win"/>
      <then>
        <exec
          executable="cygpath"
          vmlauncher="no"
          errorproperty="cygpath.err"
          outputproperty="cygpath.out"
        >
          <arg value="--windir"/>
        </exec>
        <condition property="os.cygwin">
          <equals arg1="${cygpath.err}" arg2=""/>
        </condition>
      </then>
    </if>
    <condition property="os.unix">
      <or>
        <os family="unix"/>
        <os family="mac"/>
        <isset property="os.cygwin"/>
      </or>
    </condition>
    <if><isset property="os.cygwin"/>
      <then><property name="os.type" value="Cygwin"/></then>
      <elseif><isset property="os.win"/>
        <then><property name="os.type" value="Windows"/></then>
      </elseif>
      <elseif><isset property="os.unix"/>
        <then><property name="os.type" value="UNIX"/></then>
      </elseif>
      <else>
        <fail>System environment could not be determined</fail>
      </else>
    </if>
    <echo
      level="info"
      message="OS:   ${os.type} (${os.name} ${os.arch} ${os.version});"
    />
    <echo
      level="info"
      message="Java: ${java.version} ('${java.home}');"
    />
    <echo
      level="info"
      message="JVM:  ${java.vm.name} ${java.vm.version};"
    />
    <echo
      level="info"
      message="Ant:  ${ant.version}."
    />
    <property name="init.avail" value="yes"/>
  </target>

  <target name="setup" depends="init">
    <!-- Creating boot-level tasks -->
    <taskdef
      name="scalac"
      classname="scala.tools.ant.Scalac"
      classpathref="scala.classpath"
    />
    <property name="init.avail" value="yes"/>
  </target>

<!-- ===========================================================================
BUILD
============================================================================ -->

  <target name="build" depends="setup">
    <mkdir dir="${build.dir}"/>
    <echo level="verbose">src.dir=${src.dir}</echo>
    <pathconvert property="list" pathsep=",">
      <path>
        <fileset
          dir="${src.dir}"
          includes="examples/*.scala"
          excludes="${excludes.compile}"
        />
      </path>
      <mapper>
        <globmapper from="${src.dir}/*" to="*"/>
      </mapper>
    </pathconvert>
    <for list="${list}" param="file">
      <sequential>
        <scalac srcdir="${src.dir}"
                destdir="${build.dir}">
          <classpath>
            <pathelement location="${scala.lib.jar}"/>
            <pathelement location="${build.dir}"/>
          </classpath>
          <include name="@{file}"/>
        </scalac>
      </sequential>
    </for>
  </target>

<!-- ===========================================================================
RUN
============================================================================ -->

  <target name="run" depends="build">
    <pathconvert property="list" pathsep=",">
      <path>
        <fileset
          dir="${src.dir}"
          includes="examples/*.scala"
          excludes="${excludes.run}"
        />
      </path>
      <mapper>
        <globmapper from="${src.dir}/*" to="*"/>
      </mapper>
    </pathconvert>
    <for list="${list}" param="file">
      <sequential>
        <var name="classname" unset="true"/>
        <basename property="classname" file="@{file}" suffix=".scala"/>
        <echo>Executing Scala program examples.${classname}..</echo>
        <java classname="examples.${classname}" fork="true"
              output="${build.examples.dir}/${classname}.log"
              error="${build.examples.dir}/${classname}.log"
              append="true">
          <classpath>
            <pathelement location="${scala.lib.jar}"/>
            <pathelement location="${build.dir}"/>
          </classpath>
        </java>
      </sequential>
    </for>
  </target>

<!-- ===========================================================================
CLEAN
============================================================================ -->

  <macrodef name="remove">
    <attribute name="dir"/>
    <sequential>
      <delete
        dir="@{dir}"
        includeemptydirs="yes"
        quiet="yes"
        failonerror="no"
      />
    </sequential>
  </macrodef>

  <target name="clean" description="Removes all build examples">
    <remove dir="${build.examples.dir}"/>
  </target>

</project>
