apply plugin: 'android-library'
archivesBaseName = 'support-v4'

// create a jar task for the code internal implementation
tasks.create(name: "internalJar", type: Jar) {
    baseName "internal_impl"
}

// --------------------------
// TO ADD NEW PLATFORM SPECIFIC CODE, UPDATE THIS:
// create and configure the sourcesets/dependencies for platform-specific code.
// values are: sourceset name, source folder name, api level, previous sourceset.

ext.allSS = []

def baseSS         = createApiSourceset('donut',         'donut',          '4',       null)
def eclairSS       = createApiSourceset('eclair',       'eclair',        '5',       baseSS)
def eclairMr1SS    = createApiSourceset('eclairmr1',    'eclair-mr1',    '7',       eclairSS)
def froyoSS        = createApiSourceset('froyo',        'froyo',         '8',       eclairMr1SS)
def gingerbreadSS  = createApiSourceset('gingerbread',  'gingerbread',   '9',       froyoSS)
def honeycombSS    = createApiSourceset('honeycomb',    'honeycomb',     '11',      gingerbreadSS)
def honeycombMr1SS = createApiSourceset('honeycombmr1', 'honeycomb_mr1', '12',      honeycombSS)
def honeycombMr2SS = createApiSourceset('honeycombmr2', 'honeycomb_mr2', '13',      honeycombMr1SS)
def icsSS          = createApiSourceset('ics',          'ics',           '14',      honeycombMr2SS)
def icsMr1SS       = createApiSourceset('icsmr1',       'ics-mr1',       '15',      icsSS)
def jbSS           = createApiSourceset('jellybean',    'jellybean',     '16',      icsMr1SS)
def jbMr1SS        = createApiSourceset('jellybeanmr1', 'jellybean-mr1', '17',      jbSS)
def jbMr2SS        = createApiSourceset('jellybeanmr2', 'jellybean-mr2', '18',      jbMr1SS)
def kitkatSS       = createApiSourceset('kitkat',       'kitkat',        '19',      jbMr2SS)
def api20SS        = createApiSourceset('api20',        'api20',         '20', kitkatSS)
def api21SS        = createApiSourceset('api21',        'api21',         '21', api20SS)
def api22SS        = createApiSourceset('api22',        'api22',         'current', api21SS)


def createApiSourceset(String name, String folder, String apiLevel, SourceSet previousSource) {
    def sourceSet = sourceSets.create(name)
    sourceSet.java.srcDirs = [folder]

    def configName = sourceSet.getCompileConfigurationName()

    project.getDependencies().add(configName, getAndroidPrebuilt(apiLevel))
    if (previousSource != null) {
        setupDependencies(configName, previousSource)
    }
    ext.allSS.add(sourceSet)

    internalJar.from sourceSet.output

    return sourceSet
}

def setupDependencies(String configName, SourceSet previousSourceSet) {
    project.getDependencies().add(configName, previousSourceSet.output)
    project.getDependencies().add(configName, previousSourceSet.compileClasspath)
}

dependencies {
    compile project(':support-annotations')
    donutCompile project(':support-annotations')

    // add the internal implementation as a dependency.
    // this is not enough to make the regular compileJava task
    // depend on the generation of this jar. This is done below
    // when manipulating the libraryVariants.
    compile files(internalJar.archivePath)
}

android {
    compileSdkVersion 4

    defaultConfig {
        minSdkVersion 4
        // TODO: get target from branch
        //targetSdkVersion 19
    }

    sourceSets {
        main.manifest.srcFile 'AndroidManifest.xml'
        main.java.srcDirs = ['java']
        main.aidl.srcDirs = ['java']

        androidTest.setRoot('tests')
        androidTest.java.srcDir 'tests/java'
    }

    lintOptions {
        // TODO: fix errors and reenable.
        abortOnError false
    }
}

android.libraryVariants.all { variant ->
    variant.javaCompile.dependsOn internalJar

    def name = variant.buildType.name

    if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
        return; // Skip debug builds.
    }
    def suffix = name.capitalize()

    def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
        dependsOn variant.javaCompile
        from variant.javaCompile.destinationDir
        from 'LICENSE.txt'
    }
    def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
        source android.sourceSets.main.java
        classpath = files(variant.javaCompile.classpath.files) + files(
                "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
    }

    def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
        classifier = 'javadoc'
        from 'build/docs/javadoc'
    }

    def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
        classifier = 'sources'
        from android.sourceSets.main.java.srcDirs
    }

    project.ext.allSS.each { ss ->
        javadocTask.source ss.java
        sourcesJarTask.from ss.java.srcDirs
    }

    artifacts.add('archives', javadocJarTask);
    artifacts.add('archives', sourcesJarTask);
}

uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: uri(rootProject.ext.supportRepoOut)) {
            }

            pom.project {
                name 'Android Support Library v4'
                description "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 4 or later."
                url 'http://developer.android.com/tools/extras/support-library.html'
                inceptionYear '2011'

                licenses {
                    license {
                        name 'The Apache Software License, Version 2.0'
                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                        distribution 'repo'
                    }
                }

                scm {
                    url "http://source.android.com"
                    connection "scm:git:https://android.googlesource.com/platform/frameworks/support"
                }
                developers {
                    developer {
                        name 'The Android Open Source Project'
                    }
                }
            }
        }
    }
}
