#!/usr/bin/env ruby
require 'fileutils'
class Build
  attr_reader :android_sdk_path, :name, :pkg, :www, :path, :dir
  
  def initialize(*a)
    @android_sdk_path, @name, @pkg, @www, @path = a
	@s = File::SEPARATOR
	@dir = Dir.pwd + @s
  end
  
  # runs the build script
  def run
	puts "Building the JAR..."
    build_jar
	puts "Creating Android project..."
    create_android
	puts "Generating manifest..."
    generate_manifest
	puts "Copying over libraries and assets..."
    copy_libs
	puts "Adding some application name to strings.xml..."
    add_name_to_strings
	puts "Writing application Java code..."
    write_java
	puts "Complete!"
  end 
  
  # removes local.properties and recreates based on android_sdk_path 
  # then generates framework/phonegap.jar
  def build_jar
	FileUtils.rm "#{ @dir }framework#{@s}local.properties" if File.exists? "#{ @dir }framework#{@s}local.properties"
    FileUtils.rm "#{ @dir }framework#{@s}phonegap.js" if File.exists? "#{ @dir }framework#{@s}phonegap.js"
	FileUtils.rm "#{ @dir }framework#{@s}phonegap.jar" if File.exists? "#{ @dir }framework#{@s}phonegap.jar"
    open("#{ @dir }framework#{@s}local.properties", 'w') do |f| 
      f.puts "sdk.dir=#{ @android_sdk_path }"
    end 
	Dir.chdir(@dir + "framework")
    `ant jar`
	Dir.chdir(@dir)
  end

  # runs android create project
  # TODO need to allow more flexible SDK targetting
  # TODO validate Android SDK
  def create_android
    `android create project -t 5 -k #{ @pkg } -a #{ @name } -n #{ @name } -p #{ @path }`
	FileUtils.mkdir_p "#{ @path }#{@s}assets#{@s}www"
    FileUtils.cp_r "#{ @www }#{ @s }.", "#{ @path }#{ @s }assets#{ @s }www#{ @s }"
  end

  # creates an AndroidManifest.xml for the project
  def generate_manifest
    manifest = ""
    open(@dir + 'framework/AndroidManifest.xml', 'r') do |old| 
      manifest = old.read
      manifest.gsub! 'android:versionCode="5"', 'android:versionCode="1"'
      manifest.gsub! 'package="com.phonegap"', "package=\"#{ @pkg }\""
      manifest.gsub! 'android:name=".StandAlone"', "android:name=\".#{ @name }\""
      manifest.gsub! 'android:minSdkVersion="5"', 'android:minSdkVersion="3"'
    end
    open("#{ @path }#{@s}AndroidManifest.xml", 'w') { |x| x.puts manifest }
  end

  # copies stuff from framework into the project
  # TODO need to allow for www import inc icon
  def copy_libs
	FileUtils.cp "#{ @dir }framework#{@s}phonegap.jar", "#{ @path }#{@s}libs"
	FileUtils.cp "#{ @dir }framework#{@s}res#{@s}values#{@s}strings.xml", "#{ @path }#{@s}res#{@s}values#{@s}strings.xml"
	FileUtils.cp "#{ @dir }framework#{@s}res#{@s}layout#{@s}main.xml", "#{ @path }#{@s}res#{@s}layout#{@s}main.xml"
	FileUtils.cp "#{ @dir }framework#{@s}res#{@s}layout#{@s}preview.xml", "#{ @path }#{@s}res#{@s}layout#{@s}preview.xml"
    %w(drawable-hdpi drawable-ldpi drawable-mdpi).each do |e|
	  FileUtils.cp "#{ @dir }framework#{@s}res#{@s}drawable#{@s}icon.png", "#{ @path }#{@s}res#{@s}#{ e }#{@s}icon.png"
    end
  end
  
  # puts app name in strings
  def add_name_to_strings
    x = "<?xml version=\"1.0\" encoding=\"utf-8\"?>
    <resources>
      <string name=\"app_name\">#{ @name }</string>
      <string name=\"go\">Snap</string>
    </resources>
    "
    open("#{ @path }#{@s}res#{@s}values#{@s}strings.xml", 'w') do |f| 
      f.puts x.gsub('    ','')
    end 
  end 

  # this is so fucking unholy yet oddly beautiful
  # not sure if I should thank Ruby or apologize for this abusive use of string interpolation
  def write_java
    j = "
    package #{ @pkg };

    import android.app.Activity;
    import android.os.Bundle;
    import com.phonegap.*;

    public class #{ @name } extends DroidGap
    {
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            super.loadUrl(\"file:///android_asset/www/index.html\");
        }
    }
    "
    dir = "#{ @path }#{@s}src#{@s}#{ @pkg.gsub '.', '/' }";
    cls = "#{ @name }.java"
    pth = File.join(dir,cls)
    open(pth,'w') { |f| f.puts j.gsub('    ','') }
  end
  #
end


if ARGV.length == 5
  Build.new(*ARGV).run
else
  puts <<-EOF
  
  DroidGap: PhoneGap/Android Project Generator
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
  Creates a fresh app for hybrid mobile web hacking. Delicious robot!
  
  Usage:
  
    ./droidgap <android_sdk_path> <name> <package_name> <www> <path>
  
  Params:
  
  android_sdk_path ... The path to your Android SDK install.
  name ............... The name of your application.
  package_name ....... The name of your package (For example: com.nitobi.demo)
  www ................ The path to your www folder. (Wherein your HTML, CSS and JS app is.)
  path ............... The path to generate the application.
  
  EOF
end