apply plugin: 'cpp'

import java.nio.file.Paths

String bulletSrcPath = bulletFolder + '/src'

if (!hasProperty('mainClass')) {
    ext.mainClass = ''
}

dependencies {
    compile project(':jme3-bullet')
}

model {
    components {
        bulletjme(NativeLibrarySpec) {
            targetPlatform 'Windows64'
            targetPlatform 'Windows32'
            targetPlatform 'Mac64'
            targetPlatform 'Mac32'
            targetPlatform 'Linux64'
            targetPlatform 'Linux32'

            sources {
                cpp {
                    source {
                        srcDir 'src/native/cpp'
                        srcDir bulletSrcPath
                        exclude 'Bullet3OpenCL/**'
                        include '**/*.cpp'
                    }
                    exportedHeaders {
                        srcDir 'src/native/cpp'
                        srcDir bulletSrcPath
                        exclude 'Bullet3OpenCL/**'
                        include '**/*.h'
                    }
                }
            }
        }
    }

    binaries {
        withType(SharedLibraryBinarySpec) {
            def projectPath = project.projectDir.absolutePath
            def javaHome = org.gradle.internal.jvm.Jvm.current().javaHome
            def os = targetPlatform.operatingSystem.name
            def arch = targetPlatform.architecture.name
            def fileName = sharedLibraryFile.name

            // Gradle decided to change underscores to dashes - fix that.
            arch = arch.replaceAll('-', '_')

            // For all binaries that can't be built on the current system
            if (buildNativeProjects != "true") {
                buildable = false
            }

            if (!buildable) {
                if (sharedLibraryFile.exists()) {
                    // Add binary to jar file if the binary exists in the build folder already,
                    // e.g. when the build of jme3-bullet-native has been run on a virtual box
                    // and the project hasn't been cleaned yet.
                    jar.into("native/${os}/${arch}") {
                        from sharedLibraryFile
                    }
                } else {
                    // Get from libs folder if no fresh build is available in the build folder and add to jar file
                    def precompiledFile = Paths.get(projectPath, 'libs', 'native', os, arch, fileName).toFile()
                    if (precompiledFile.exists()) {
                        jar.into("native/${os}/${arch}") {
                            from precompiledFile
                        }
                    }
                }
                return
            }

            if (toolChain in VisualCpp) {
                cppCompiler.args "/I$javaHome\\include"
            } else{
                cppCompiler.args '-I', "$javaHome/include"
            }

            if (os == "osx") {
                cppCompiler.args '-I', "$javaHome/include/darwin"
                cppCompiler.args "-Ofast"
                cppCompiler.args "-U_FORTIFY_SOURCE"
            } else if (os == "linux") {
                cppCompiler.args "-fvisibility=hidden"
                cppCompiler.args '-I', "$javaHome/include/linux"
                cppCompiler.args "-fPIC"
                cppCompiler.args "-Ofast"
                cppCompiler.args "-U_FORTIFY_SOURCE"
                cppCompiler.args "-fpermissive"
                linker.args "-fvisibility=hidden"
            } else if (os == "windows") {
                if (toolChain in Gcc) {
                    if (toolChain.name.startsWith('mingw')) {
                        cppCompiler.args '-I', "$projectDir/src/native/cpp/fake_win32"
                    } else {
                        cppCompiler.args '-I', "$javaHome/include/win32"
                    }
                    cppCompiler.args "-fpermissive"
                    cppCompiler.args "-static"
                    cppCompiler.args "-Ofast"
                    cppCompiler.args "-U_FORTIFY_SOURCE"
                    linker.args "-static"
                    linker.args "-Wl,--exclude-all-symbols"
                }
                else if (toolChain in VisualCpp) {
                    cppCompiler.args "/I$javaHome\\include\\win32"
                }
                cppCompiler.define('WIN32')
            }

            tasks.all { dependsOn unzipBulletIfNeeded }

            // Add output to jar file
            jar.into("native/${os}/${arch}") {
                from sharedLibraryFile
            }

            // Add depend on build
            jar.dependsOn tasks
            // Add output to libs folder
            task "copyBinaryToLibs${targetPlatform.name}"(type: Copy, dependsOn: tasks) {
                from sharedLibraryFile
                into "libs/native/${os}/${arch}"
            }
            // Add depend on copy
            jar.dependsOn("copyBinaryToLibs${targetPlatform.name}")
        }
        withType(StaticLibraryBinarySpec) {
            buildable = false
        }
    }

    platforms {
        Windows32 {
            architecture "x86"
            operatingSystem "windows"
        }
        Windows64 {
            architecture "x86_64"
            operatingSystem "windows"
        }
        Mac32 {
            architecture "x86"
            operatingSystem "osx"
        }
        Mac64 {
            architecture "x86_64"
            operatingSystem "osx"
        }
        Linux32 {
            architecture "x86"
            operatingSystem "linux"
        }
        Linux64 {
            architecture "x86_64"
            operatingSystem "linux"
        }
    }
}

// Java source sets for IDE access and source jar bundling / mavenization
sourceSets {
    main {
        java {
            srcDir 'src/native/cpp'
        }
    }
}

task downloadBullet(type: MyDownload) {
    sourceUrl = bulletUrl
    target = file(bulletZipFile)
}

task unzipBullet(type: Copy) {
    from zipTree(bulletZipFile)
    into file('.')
}

unzipBullet.dependsOn {
    if (!file(bulletZipFile).exists()) {
        downloadBullet
    }
}

task unzipBulletIfNeeded {
}

unzipBulletIfNeeded.dependsOn {
    if (buildNativeProjects == "true" && !file(bulletFolder).isDirectory()) {
        unzipBullet
    }
}

// Helper class to wrap ant dowload task
class MyDownload extends DefaultTask {
    @Input
    String sourceUrl

    @OutputFile
    File target

    @TaskAction
    void download() {
        ant.get(src: sourceUrl, dest: target)
    }
}