#!/bin/bash

if [ "$#" -ne 2 ]; then
  echo "USAGE: $0 APP_NAME DESCRIPTION"
  exit 1
fi

PROJECT_HOME=~/AndroidStudioProjects
ORG_PATH="$PROJECT_HOME/defaultOrg"
KEY_PROPERTIES_PATH="$PROJECT_HOME/defaultKeyProperties"

appName="$1"
packageName=`echo "$appName" | tr ' ' '_' | tr '[:upper:]' '[:lower:]'`
description="$2"

echo "App Name: $appName"
echo "Package Name: $packageName"
echo "Description: $description"


if [[ -f "$ORG_PATH" ]]; then
  org=`cat "$PROJECT_HOME/defaultOrg"`
else
  echo "Could not find file with default org in $ORG_PATH"
  exit 1
fi

if [[ -f "$KEY_PROPERTIES_PATH" ]]; then
  keyProperties=`cat "$PROJECT_HOME/defaultKeyProperties"`
else
  echo "Could not find file with default key properties in $KEY_PROPERTIES_PATH"
  exit 1
fi

flutter create --android-language java --org "$org" "$packageName" || exit 1

cd "$packageName"

##########################
## append to .gitignore ##
##########################

echo "android/key.properties" >> .gitignore

git init

##################################
## generate empty launcher icon ##
##################################

convert -size 2048x2048 xc:white launcherIcon.png



############################
## overwrite pubspec.yaml ##
############################

cat > pubspec.yaml <<EOF
name: $packageName
description: $description

version: 1.0.0+1

environment:
  sdk: ">=2.2.2 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  intl: ^0.15.7
  shared_preferences: ^0.5.4+8
  cupertino_icons: ^0.1.2

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_launcher_icons: "^0.7.3"

flutter_icons:
  image_path: "launcherIcon.png"
  android: true
  ios: true

flutter:
  uses-material-design: true

EOF



#########################################
## generate key.properties for signing ##
#########################################

cat > android/key.properties <<EOF
$keyProperties
EOF


############################
## overwrite build.gradle ##
############################

cat > android/app/build.gradle <<EOF
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
    localPropertiesFile.withReader('UTF-8') { reader ->
        localProperties.load(reader)
    }
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
    throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
    flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
    flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply from: "\$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}


android {
    compileSdkVersion 28

    lintOptions {
        disable 'InvalidPackage'
    }

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "$org.$packageName"
        minSdkVersion 16
        targetSdkVersion 28
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    signingConfigs {
        release {
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
            storeFile file(keystoreProperties['storeFile'])
            storePassword keystoreProperties['storePassword']
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

flutter {
    source '../..'
}

dependencies {
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

EOF

#######################
## set android label ##
#######################

sed -i "s/android:label=\"$packageName\"/android:label=\"$appName\"/" android/app/src/main/AndroidManifest.xml

#####################
## empty README.md ##
#####################
cat > README.md <<EOF
# $appName

$description

EOF


#########################
## overwrite main.dart ##
#########################
cat > lib/main.dart <<EOF
import 'package:flutter/material.dart';
import 'screens/loading.dart';

void main() {
  runApp(MaterialApp(
    debugShowCheckedModeBanner: false,
    theme: ThemeData(
      primarySwatch: Colors.blue,
    ),
    home: Loading(),
  ));
}

EOF

####################################
## create loading and home screen ##
####################################

mkdir lib/screens

cat > lib/screens/home.dart <<EOF
import 'package:flutter/material.dart';

class Home extends StatefulWidget {
  Home({Key key}) : super(key: key);
  static const title = '$appName';

  static void loadInitial(BuildContext context) async {
    await Future.delayed(Duration.zero, () {});
    // load some stuff here and await results
    Navigator.pushReplacement(context,
        MaterialPageRoute(builder: (context) => Home()));
  }

  static void save(BuildContext context) async {
    showDialog(context: context, barrierDismissible: false,
        builder: (BuildContext context) { return AlertDialog(content: Text("Saving...")); });
    await Future.delayed(Duration.zero, () {});
    Navigator.of(context, rootNavigator: true).pop();
  }

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  int state = 1;

  void _changeState(int s) {
    setState(() {
      state = s;
    });
  }

  List<String> popupMenuItems = ["About"];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(Home.title),
        actions: <Widget>[
          PopupMenuButton<String>(
            onSelected: (String value) => handleClick(context, value),
            itemBuilder: (BuildContext context) {
              return popupMenuItems.map((String choice) {
                return PopupMenuItem<String>(
                  value: choice,
                  child: Text(choice),
                );
              }).toList();
            },
          ),
        ],
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: ListView(children: [
          Text("Lorem ipsum dolor sit amet"),
        ]),
      ),
    );
  }

  void handleClick(BuildContext context, String value) {
    switch (value) {
      case 'About':
        showLicensePage(context: context, applicationName: Home.title);
    }
  }
}

EOF


cat > lib/screens/loading.dart <<EOF
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'home.dart';

class Loading extends StatefulWidget {
  @override
  _LoadingState createState() => _LoadingState();
}

class _LoadingState extends State<Loading> {
  @override
  void initState() {
    super.initState();
    Home.loadInitial(context);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Text("Loading..."),
        alignment: Alignment.center,
      ),
    );
  }
}

EOF


#####################
## create Makefile ##
#####################

cat > Makefile <<EOF
.PHONY: clean all launcherIcon

all: launcherIcon
	flutter pub get
	flutter build appbundle

clean:
	flutter clean

launcherIcon:
	flutter pub get
	flutter pub run "flutter_launcher_icons:main"

EOF


################
## test build ##
################

make clean launcherIcon all
make clean