/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package #packageName#;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * <p>
 * This class copies a SQLite database from your application's assets directory to 
 * /data/data/<your_application_package>/databases/ so you can access it using the SQLite APIs
 * provided by the Android SDK. Note that {@link #className##copyDatabaseFile()} checks
 * for the existence of the database and only copies it if needed.
 * </p>
 * <p>
 * {@link #className##copyDatabaseFile()} calls {@link SQLiteOpenHelper#getReadableDatabase()}, 
 * which in turn calls {@link SQLiteOpenHelper#onCreate(SQLiteDatabase)}. Be aware that the 
 * implementation of the overridden {@link SQLiteOpenHelper#onCreate(SQLiteDatabase)} must remain 
 * empty in order for the copy operation to work correctly.
 * </p>
 * <p>
 * This class includes a constructor {@link #className###className#(Context, boolean)} which
 * allows you to control whether the database file should be copied when the class is instantiated. 
 * </p>  
 * @see SQLiteOpenHelper
 */
public class #className# extends SQLiteOpenHelper {
	 
    // Android's default system path for your application's database.
    private static String DB_PATH = "/data/data/#applicationPackageNamespace#/databases/";
 
    private static String DB_NAME = "#dbName#";
 
    private final Context myContext;
 
    /**
     * Constructor
     * Keeps a reference to the passed context in order to access the application's assets.
     * @param context Context to be used
     */
    public #className#(Context context) {
 
    	super(context, DB_NAME, null, 1);
        this.myContext = context;
    }	
  	
  	/**
	 * This constructor copies the database file if the copyDatabase argument is <code>true</code>.
	 * It keeps a reference to the passed context in order to access the application's assets.
	 * 
	 * @param context Context to be used
	 * @param copyDatabase If <code>true</code>, the database file is copied (if it does not already exist)
	 */  	
	public #className#(Context context, boolean copyDatabase) {
		// call overloaded constructor
		this(context);
		// copy database file in case desired
		if (copyDatabase) {
			copyDatabaseFile();
		}
	}
  	
 	/*
	 * (non-Javadoc)
	 * @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase)
	 */ 	
	@Override	 
	public void onCreate(SQLiteDatabase db) {
		// Leave this method empty
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite
	 * .SQLiteDatabase, int, int)
	 */
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// fill in your code here
	}
 
 	/**
	 * <p>
	 * Copy the database file from the assets directory to the proper location where the
	 * application can access it. The database location and name is given by the
	 * constants {@link #DB_PATH} and {@link #DB_NAME} respectively.
	 * </p>
	 * <p>
	 * If the database file already exists, it will not be overwritten.
	 *</p>
	 */
	public void copyDatabaseFile() {

		// variables
		InputStream myInput = null;
		OutputStream myOutput = null;
		SQLiteDatabase database = null;

		// only proceed in case the database does not exist
		if (!checkDataBaseExistence()) {
			// get the database
			database = this.getReadableDatabase();
			try {
				// Open your local db as the input stream
				myInput = myContext.getAssets().open(DB_NAME);

				// Path to the just created empty db
				String outFileName = DB_PATH + DB_NAME;

				// Open the empty db as the output stream
				myOutput = new FileOutputStream(outFileName);

				// transfer bytes from the input file to the output file
				byte[] buffer = new byte[1024];
				int length;
				while ((length = myInput.read(buffer)) > 0) {
					myOutput.write(buffer, 0, length);
				}
			} catch (FileNotFoundException e) {
				// handle your exception here
			} catch (IOException e) {
				// handle your exception here
			} finally {
				try {
					// Close the streams
					myOutput.flush();
					myOutput.close();
					myInput.close();
					// close the database in case it is opened
					if (database != null && database.isOpen())
					{
						database.close();
					}
					
				} catch (Exception e) {
					// handle your exception here
				}
			}
		}
	}

	/**
	 * Returns whether the database already exists.
	 * 
	 * @return <code>true</code> if the database exists, <code>false</code>
	 *         otherwise.
	 */
	private boolean checkDataBaseExistence() {

		// database to be verified
		SQLiteDatabase dbToBeVerified = null;

		try {
			// get database path
			String dbPath = DB_PATH + DB_NAME;
			// try to open the database
			dbToBeVerified = SQLiteDatabase.openDatabase(dbPath, null,
					SQLiteDatabase.OPEN_READONLY);

		} catch (SQLiteException e) {
			// do nothing since the database does not exist
		}

		// in case it exists, close it
		if (dbToBeVerified != null) {
			// close DB
			dbToBeVerified.close();

		}

		// in case there is a DB entity, the DB exists
		return dbToBeVerified != null ? true : false;
	}
}
