/*
 * 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.util.*;

import android.content.*;
import android.database.*;
import android.database.sqlite.*;
import android.net.*;
import android.text.*;

import #databaseOpenHelperPackageName#.*;

public class #className# extends ContentProvider {
		
	private #databaseOpenHelperClassName# dbHelper;	
	private static HashMap<String, String> #tableNameUpperCase#_PROJECTION_MAP;
	private static final String TABLE_NAME = "#tableNameLowerCase#";
	private static final String AUTHORITY = "#authority#";
	
	public static final Uri CONTENT_URI = Uri.parse("content://"+AUTHORITY+"/"+TABLE_NAME);
	#uriConstants#
	
	#defaultSortOrder#
	
	private static final UriMatcher URL_MATCHER;

	#constIndexesProjectMap#
	
	//Content values keys (using column names) 
	#constContentValuesKeys#
		
	public boolean onCreate() {
		dbHelper = new #databaseOpenHelperClassName#(getContext(),true);
		return (dbHelper == null) ? false : true;
	}
	

	public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs, String sort) {
		SQLiteDatabase mDB = dbHelper.getReadableDatabase();
		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
		switch (URL_MATCHER.match(url)) {
			#queryUrlCases#
			default:
				throw new IllegalArgumentException("Unknown URL " + url);
		}
		String orderBy = "";
		if (TextUtils.isEmpty(sort)) {
			orderBy = DEFAULT_SORT_ORDER;
		} else {
			orderBy = sort;
		}
		Cursor c = qb.query(mDB, projection, selection, selectionArgs, null, null, orderBy);
		c.setNotificationUri(getContext().getContentResolver(), url);
		return c;
	}
		
	public String getType(Uri url) {
		switch (URL_MATCHER.match(url)) {			
			#typeRecordCases#							
			default:
				throw new IllegalArgumentException("Unknown URL " + url);
		}
	}

	public Uri insert(Uri url, ContentValues initialValues) {
		SQLiteDatabase mDB = dbHelper.getWritableDatabase();
		long rowID;
		ContentValues values;
		if (initialValues != null) {
			values = new ContentValues(initialValues);
		} else {
			values = new ContentValues();
		}
		if (URL_MATCHER.match(url) != #tableNameUpperCase#) {
			throw new IllegalArgumentException("Unknown URL " + url);
		}
		
		#insertStatementCases#
		
		rowID = mDB.insert("#tableNameLowerCase#", "#tableNameLowerCase#", values);
		if (rowID > 0) {
			Uri uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
			getContext().getContentResolver().notifyChange(uri, null);
			return uri;
		}
		throw new SQLException("Failed to insert row into " + url);
	}
	
	public int delete(Uri url, String where, String[] whereArgs) {
	 	SQLiteDatabase mDB = dbHelper.getWritableDatabase();
		int count;		
		String segment = "";
		switch (URL_MATCHER.match(url)) {
			#deleteStatementCases#
			default:
				throw new IllegalArgumentException("Unknown URL " + url);
		}
		getContext().getContentResolver().notifyChange(url, null);
		return count;
	}
	
	public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
		SQLiteDatabase mDB = dbHelper.getWritableDatabase();
		int count;
		String segment = "";
		switch (URL_MATCHER.match(url)) {
			#updateStatementCases#
			default:
				throw new IllegalArgumentException("Unknown URL " + url);
		}
		getContext().getContentResolver().notifyChange(url, null);
		return count;		
	}
	
	static {
		URL_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
		#UrlMatcherStatementCases#
		
		#tableNameUpperCase#_PROJECTION_MAP = new HashMap<String, String>();
		#ProjectionMapStatementCases#		
	}
}