/**
 * IEEESurfer
 * 
 * Copyright (c) 2014 Rami Al Halabi
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 * 
 */
/**
 * Sparse rss
 *
 * Copyright (c) 2010-2013 Stefan Handschuh
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

package com.ieeemadcandroid.ieeesurfer.rss.provider;

import java.io.File;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.text.TextUtils;

import com.ieeemadcandroid.ieeesurfer.rss.Strings;

public class FeedDataContentProvider extends ContentProvider {
	private static final String FOLDER = Environment.getExternalStorageDirectory()+"/ieeesurfer/";
	
	private static final String DATABASE_NAME = "ieeenews.db";
	
	private static final int DATABASE_VERSION = 13;
	
	private static final int URI_FEEDS = 1;
	
	private static final int URI_FEED = 2;
	
	private static final int URI_ENTRIES = 3;
	
	private static final int URI_ENTRY= 4;
	
	private static final int URI_ALLENTRIES = 5;
	
	private static final int URI_ALLENTRIES_ENTRY = 6;
	
	private static final int URI_FAVORITES = 7;
	
	private static final int URI_FAVORITES_ENTRY = 8;
	
	protected static final String TABLE_FEEDS = "feeds";
	
	private static final String TABLE_ENTRIES = "entries";
	
	private static final String ALTER_TABLE = "ALTER TABLE ";
	
	private static final String ADD = " ADD ";
	
	private static final String EQUALS_ONE = "=1";

	public static final String IMAGEFOLDER = Environment.getExternalStorageDirectory()+"/ieeesurfer/images/"; // faster than FOLDER+"images/"
	
	public static final File IMAGEFOLDER_FILE = new File(IMAGEFOLDER);
	
	private static final String BACKUPOPML = Environment.getExternalStorageDirectory()+"/ieeesurfer/backup.opml";
	
	private static UriMatcher URI_MATCHER;
	
	private static final String[] PROJECTION_PRIORITY = new String[] {FeedData.FeedColumns.PRIORITY};
	
	static {
		URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
		URI_MATCHER.addURI(FeedData.AUTHORITY, "feeds", URI_FEEDS);
		URI_MATCHER.addURI(FeedData.AUTHORITY, "feeds/#", URI_FEED);
		URI_MATCHER.addURI(FeedData.AUTHORITY, "feeds/#/entries", URI_ENTRIES);
		URI_MATCHER.addURI(FeedData.AUTHORITY, "feeds/#/entries/#", URI_ENTRY);
		URI_MATCHER.addURI(FeedData.AUTHORITY, "entries", URI_ALLENTRIES);
		URI_MATCHER.addURI(FeedData.AUTHORITY, "entries/#", URI_ALLENTRIES_ENTRY);
		URI_MATCHER.addURI(FeedData.AUTHORITY, "favorites", URI_FAVORITES);
		URI_MATCHER.addURI(FeedData.AUTHORITY, "favorites/#", URI_FAVORITES_ENTRY);
		
		IMAGEFOLDER_FILE.mkdirs();
		
		// Create .nomedia file, that will prevent Android image gallery from showing random parts of webpages we've saved
		File nomedia = new File(IMAGEFOLDER+".nomedia");
		
		try {
			if (!nomedia.exists()) {
				nomedia.createNewFile();
			}
		} catch (Exception e) {
		}
	}
	
	private static class DatabaseHelper extends SQLiteOpenHelper {
		private Context context;
		
		public DatabaseHelper(Context context, String name, int version) {
			super(context, name, null, version); // the constructor just sets the values and returns, therefore context cannot be null
			this.context = context;
			context.sendBroadcast(new Intent(Strings.ACTION_UPDATEWIDGET));
		}

		@Override
		public void onCreate(SQLiteDatabase database) {
			database.execSQL(createTable(TABLE_FEEDS, FeedData.FeedColumns.COLUMNS, FeedData.FeedColumns.TYPES));
			database.execSQL(createTable(TABLE_ENTRIES, FeedData.EntryColumns.COLUMNS, FeedData.EntryColumns.TYPES));
			
			File backupFile = new File(BACKUPOPML);
			
			if (backupFile.exists()) {
				/** Perform an automated import of the backup */
				OPML.importFromFile(backupFile, database);
			}
		}
		
		private String createTable(String tableName, String[] columns, String[] types) {
			if (tableName == null || columns == null || types == null || types.length != columns.length || types.length == 0) {
				throw new IllegalArgumentException("Invalid parameters for creating table "+tableName);
			} else {
				StringBuilder stringBuilder = new StringBuilder("CREATE TABLE ");
				
				stringBuilder.append(tableName);
				stringBuilder.append(" (");
				for (int n = 0, i = columns.length; n < i; n++) {
					if (n > 0) {
						stringBuilder.append(", ");
					}
					stringBuilder.append(columns[n]).append(' ').append(types[n]);
				}
				return stringBuilder.append(");").toString();
			}
		}

		@Override
		public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
			if (oldVersion < 2) {
				executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_FEEDS).append(ADD).append(FeedData.FeedColumns.PRIORITY).append(' ').append(FeedData.TYPE_INT).toString());
			}
			if (oldVersion < 3) {
				executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_ENTRIES).append(ADD).append(FeedData.EntryColumns.FAVORITE).append(' ').append(FeedData.TYPE_BOOLEAN).toString());
			}
			if (oldVersion < 4) {
				executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_FEEDS).append(ADD).append(FeedData.FeedColumns.FETCHMODE).append(' ').append(FeedData.TYPE_INT).toString());
			}
			if (oldVersion < 5) {
				executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_FEEDS).append(ADD).append(FeedData.FeedColumns.REALLASTUPDATE).append(' ').append(FeedData.TYPE_DATETIME).toString());
			}
			if (oldVersion < 6) {
				Cursor cursor = database.query(TABLE_FEEDS, new String[] {FeedData.FeedColumns._ID}, null, null, null, null, FeedData.FeedColumns._ID);
				
				int count = 0;
				
				while (cursor.moveToNext()) {
					executeCatchedSQL(database, new StringBuilder("UPDATE ").append(TABLE_FEEDS).append(" SET ").append(FeedData.FeedColumns.PRIORITY).append('=').append(count++).append(" WHERE _ID=").append(cursor.getLong(0)).toString());
				}
				cursor.close();
			}
			if (oldVersion < 7) {
				executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_FEEDS).append(ADD).append(FeedData.FeedColumns.WIFIONLY).append(' ').append(FeedData.TYPE_BOOLEAN).toString());
			}
			// we simply leave the "encoded" column untouched
			if (oldVersion < 9) {
				executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_ENTRIES).append(ADD).append(FeedData.EntryColumns.ENCLOSURE).append(' ').append(FeedData.TYPE_TEXT).toString());
			}
			if (oldVersion < 10) {
				executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_ENTRIES).append(ADD).append(FeedData.EntryColumns.GUID).append(' ').append(FeedData.TYPE_TEXT).toString());
			}
			if (oldVersion < 11) {
				executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_ENTRIES).append(ADD).append(FeedData.EntryColumns.AUTHOR).append(' ').append(FeedData.TYPE_TEXT).toString());
			}
			if (oldVersion < 12) {
				executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_FEEDS).append(ADD).append(FeedData.FeedColumns.IMPOSE_USERAGENT).append(' ').append(FeedData.TYPE_BOOLEAN).toString());
				if (!PreferenceManager.getDefaultSharedPreferences(context).getBoolean(Strings.SETTINGS_STANDARDUSERAGENT, true)) {
					// no "DEFAULT" syntax
					executeCatchedSQL(database, new StringBuilder("UPDATE ").append(TABLE_FEEDS).append(" SET ").append(FeedData.FeedColumns.IMPOSE_USERAGENT).append("='1'").toString());
				}
			}
			if (oldVersion < 13) {
				executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_FEEDS).append(ADD).append(FeedData.FeedColumns.HIDE_READ).append(' ').append(FeedData.TYPE_BOOLEAN).toString());
			}
		}
		
		private void executeCatchedSQL(SQLiteDatabase database, String query) {
			try {
				database.execSQL(query);
			} catch (Exception e) {
				
			}
		}

		@Override
		public synchronized SQLiteDatabase getWritableDatabase() {
			File oldDatabaseFile = new File(Environment.getExternalStorageDirectory()+"/ieeesurfer/ieeenews.db");
			
			if (oldDatabaseFile.exists()) { // get rid of the old structure
				SQLiteDatabase newDatabase = super.getWritableDatabase();
				
				try {
					SQLiteDatabase oldDatabase  = SQLiteDatabase.openDatabase(Environment.getExternalStorageDirectory()+"/ieeesurfer/ieeenews.db", null, SQLiteDatabase.OPEN_READWRITE + SQLiteDatabase.CREATE_IF_NECESSARY);
					
					Cursor cursor = oldDatabase.query(TABLE_ENTRIES, null, null, null, null, null, null);
					
					newDatabase.beginTransaction();
					
					String[] columnNames = cursor.getColumnNames();
					
					int i = columnNames.length;
					
					int[] columnIndices = new int[i];
					
					for (int n = 0; n < i; n++) {
						columnIndices[n] = cursor.getColumnIndex(columnNames[n]);
					}
					
					while (cursor.moveToNext()) {
						ContentValues values = new ContentValues();
						
						for (int n = 0; n < i; n++) {
							if (!cursor.isNull(columnIndices[n])) {
								values.put(columnNames[n], cursor.getString(columnIndices[n]));
							}
						}
						
						newDatabase.insert(TABLE_ENTRIES, null, values);
					}
					cursor.close();
					cursor = oldDatabase.query(TABLE_FEEDS, null, null, null, null, null, FeedData.FeedColumns._ID);
					columnNames = cursor.getColumnNames();
					i = columnNames.length;
					columnIndices = new int[i];
					
					for (int n = 0; n < i; n++) {
						columnIndices[n] = cursor.getColumnIndex(columnNames[n]);
					}
					
					int count = 0;
					
					while (cursor.moveToNext()) {
						ContentValues values = new ContentValues();
						
						for (int n = 0; n < i; n++) {
							if (!cursor.isNull(columnIndices[n])) {
								if (FeedData.FeedColumns.ICON.equals(columnNames[n])) {
									values.put(FeedData.FeedColumns.ICON, cursor.getBlob(columnIndices[n]));
								} else {
									values.put(columnNames[n], cursor.getString(columnIndices[n]));
								}
							}
						}
						values.put(FeedData.FeedColumns.PRIORITY, count++);
						newDatabase.insert(TABLE_FEEDS, null, values);
					}
					cursor.close();
					oldDatabase.close();
					oldDatabaseFile.delete();
					newDatabase.setTransactionSuccessful();
					newDatabase.endTransaction();
					OPML.exportToFile(BACKUPOPML, newDatabase);
				} catch (Exception e) {
					
				}
				return newDatabase;
			} else {
				return super.getWritableDatabase();
			}
		}
	}
	
	private DatabaseHelper databaseHelper;
	
	private String[] MAXPRIORITY = new String[] {"MAX("+FeedData.FeedColumns.PRIORITY+")"};

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		int option = URI_MATCHER.match(uri);
		
		String table = null;
		
		StringBuilder where = new StringBuilder();
		
		SQLiteDatabase database = databaseHelper.getWritableDatabase();
		
		switch(option) {
			case URI_FEED : {
				table = TABLE_FEEDS;
			
				final String feedId = uri.getPathSegments().get(1);
				
				new Thread() {
					public void run() {
						delete(FeedData.EntryColumns.CONTENT_URI(feedId), null, null);
					}
				}.start();
				
				where.append(FeedData.FeedColumns._ID).append('=').append(feedId);
				
				/** Update the priorities */
				Cursor priorityCursor = database.query(TABLE_FEEDS, PROJECTION_PRIORITY, FeedData.FeedColumns._ID+"="+feedId, null, null, null, null);
				
				if (priorityCursor.moveToNext()) {
					database.execSQL("UPDATE "+TABLE_FEEDS+" SET "+FeedData.FeedColumns.PRIORITY+" = "+FeedData.FeedColumns.PRIORITY+"-1 WHERE "+FeedData.FeedColumns.PRIORITY+" > "+priorityCursor.getInt(0));
					priorityCursor.close();
				} else {
					priorityCursor.close();
				}
				break;
			}
			case URI_FEEDS : {
				table = TABLE_FEEDS;
				break;
			}
			case URI_ENTRY : {
				table = TABLE_ENTRIES;
				where.append(FeedData.EntryColumns._ID).append('=').append(uri.getPathSegments().get(3));
				break;
			}
			case URI_ENTRIES : {
				table = TABLE_ENTRIES;
				where.append(FeedData.EntryColumns.FEED_ID).append('=').append(uri.getPathSegments().get(1));
				break;
			}
			case URI_ALLENTRIES : {
				table = TABLE_ENTRIES;
				break;
			}
			case URI_FAVORITES_ENTRY :
			case URI_ALLENTRIES_ENTRY : {
				table = TABLE_ENTRIES;
				where.append(FeedData.EntryColumns._ID).append('=').append(uri.getPathSegments().get(1));
				break;
			}
			case URI_FAVORITES : {
				table = TABLE_ENTRIES;
				where.append(FeedData.EntryColumns.FAVORITE).append(EQUALS_ONE);
				break;
			}
		}
		
		if (!TextUtils.isEmpty(selection)) {
			if (where.length() > 0) {
				where.append(Strings.DB_AND);
			}
			where.append(selection);
		}
		
		int count = database.delete(table, where.toString(), selectionArgs);
		
		if (table == TABLE_FEEDS) { // == is ok here
			OPML.exportToFile(BACKUPOPML, database);
		}
		if (count > 0) {
			getContext().getContentResolver().notifyChange(uri, null);
			getContext().sendBroadcast(new Intent(Strings.ACTION_UPDATEWIDGET));
		}
		return count;
	}

	@Override
	public String getType(Uri uri) {
		int option = URI_MATCHER.match(uri);
		
		switch(option) {
			case URI_FEEDS : return "vnd.android.cursor.dir/vnd.feeddata.feed";
			case URI_FEED : return "vnd.android.cursor.item/vnd.feeddata.feed";
			case URI_FAVORITES :
			case URI_ALLENTRIES :
			case URI_ENTRIES : return "vnd.android.cursor.dir/vnd.feeddata.entry";
			case URI_FAVORITES_ENTRY :
			case URI_ALLENTRIES_ENTRY :
			case URI_ENTRY : return "vnd.android.cursor.item/vnd.feeddata.entry";
			default : throw new IllegalArgumentException("Unknown URI: "+uri);
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		long newId = -1;
		
		int option = URI_MATCHER.match(uri);
		
		SQLiteDatabase database = databaseHelper.getWritableDatabase();
		
		switch (option) {
			case URI_FEEDS : {
				Cursor cursor = database.query(TABLE_FEEDS, MAXPRIORITY, null, null, null, null, null, null);
				
				if (cursor.moveToNext()) {
					values.put(FeedData.FeedColumns.PRIORITY, cursor.getInt(0)+1);
				} else {
					values.put(FeedData.FeedColumns.PRIORITY, 1);
				}
				cursor.close();
				newId = database.insert(TABLE_FEEDS, null, values);
				OPML.exportToFile(BACKUPOPML, database);
				break;
			}
			case URI_ENTRIES : {
				values.put(FeedData.EntryColumns.FEED_ID, uri.getPathSegments().get(1));
				newId = database.insert(TABLE_ENTRIES, null, values);
				break;
			}
			case URI_ALLENTRIES : {
				newId = database.insert(TABLE_ENTRIES, null, values);
				break;
			}
			default : throw new IllegalArgumentException("Illegal insert");
		}
		if (newId > -1) {
			getContext().getContentResolver().notifyChange(uri, null);
			return ContentUris.withAppendedId(uri, newId);
		} else {
			throw new SQLException("Could not insert row into "+uri);
		}
	}

	@Override
	public boolean onCreate() {
		try {
			File folder = new File(FOLDER);
			
			folder.mkdir(); // maybe we use the boolean return value later
		} catch (Exception e) {
			
		}
		databaseHelper = new DatabaseHelper(getContext(), DATABASE_NAME, DATABASE_VERSION);
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
		SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
		
		int option = URI_MATCHER.match(uri);
		
		if ((option == URI_FEED || option == URI_FEEDS) && sortOrder == null) {
			sortOrder = FeedData.FEED_DEFAULTSORTORDER;
		}
		
		switch(option) {
			case URI_FEED : {
				queryBuilder.setTables(TABLE_FEEDS);
				queryBuilder.appendWhere(new StringBuilder(FeedData.FeedColumns._ID).append('=').append(uri.getPathSegments().get(1)));
				break;
			}
			case URI_FEEDS : {
				queryBuilder.setTables(TABLE_FEEDS);
				break;
			}
			case URI_ENTRY : {
				queryBuilder.setTables(TABLE_ENTRIES);
				queryBuilder.appendWhere(new StringBuilder(FeedData.EntryColumns._ID).append('=').append(uri.getPathSegments().get(3)));
				break;
			}
			case URI_ENTRIES : {
				queryBuilder.setTables(TABLE_ENTRIES);
				queryBuilder.appendWhere(new StringBuilder(FeedData.EntryColumns.FEED_ID).append('=').append(uri.getPathSegments().get(1)));
				break;
			}
			case URI_ALLENTRIES : {
				queryBuilder.setTables("entries join (select name, icon, _id as feed_id from feeds) as F on (entries.feedid = F.feed_id)");
				break;
			}
			case URI_FAVORITES_ENTRY :
			case URI_ALLENTRIES_ENTRY : {
				queryBuilder.setTables(TABLE_ENTRIES);
				queryBuilder.appendWhere(new StringBuilder(FeedData.EntryColumns._ID).append('=').append(uri.getPathSegments().get(1)));
				break;
			}
			case URI_FAVORITES : {
				queryBuilder.setTables("entries join (select name, icon, _id as feed_id from feeds) as F on (entries.feedid = F.feed_id)");
				queryBuilder.appendWhere(new StringBuilder(FeedData.EntryColumns.FAVORITE).append(EQUALS_ONE));
				break;
			}
		}
		
		SQLiteDatabase database = databaseHelper.getReadableDatabase();
		
		Cursor cursor = queryBuilder.query(database, projection, selection, selectionArgs, null, null, sortOrder);

		cursor.setNotificationUri(getContext().getContentResolver(), uri);
		return cursor;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
		int option = URI_MATCHER.match(uri);
		
		String table = null;
		
		StringBuilder where = new StringBuilder();
		
		SQLiteDatabase database = databaseHelper.getWritableDatabase();
		
		switch(option) {
			case URI_FEED : {
				table = TABLE_FEEDS;
				
				long feedId = Long.parseLong(uri.getPathSegments().get(1));
				
				where.append(FeedData.FeedColumns._ID).append('=').append(feedId);
				if (values != null && values.containsKey(FeedData.FeedColumns.PRIORITY)) {
					int newPriority = values.getAsInteger(FeedData.FeedColumns.PRIORITY);
					
					Cursor priorityCursor = database.query(TABLE_FEEDS, PROJECTION_PRIORITY, FeedData.FeedColumns._ID+"="+feedId, null, null, null, null);
					
					if (priorityCursor.moveToNext()) {
						int oldPriority = priorityCursor.getInt(0);
						
						priorityCursor.close();
						if (newPriority > oldPriority) {
							database.execSQL("UPDATE "+TABLE_FEEDS+" SET "+FeedData.FeedColumns.PRIORITY+" = "+FeedData.FeedColumns.PRIORITY+"-1 WHERE "+FeedData.FeedColumns.PRIORITY+" BETWEEN "+(oldPriority+1)+" AND "+newPriority);
						} else if (newPriority < oldPriority) {
							database.execSQL("UPDATE "+TABLE_FEEDS+" SET "+FeedData.FeedColumns.PRIORITY+" = "+FeedData.FeedColumns.PRIORITY+"+1 WHERE "+FeedData.FeedColumns.PRIORITY+" BETWEEN "+newPriority+" AND "+(oldPriority-1));
						}
					} else {
						priorityCursor.close();
					}
				}
				break;
			}
			case URI_FEEDS : {
				table = TABLE_FEEDS;
				// maybe this should be disabled
				break;
			}
			case URI_ENTRY : {
				table = TABLE_ENTRIES;
				where.append(FeedData.EntryColumns._ID).append('=').append(uri.getPathSegments().get(3));
				break;
			}
			case URI_ENTRIES : {
				table = TABLE_ENTRIES;
				where.append(FeedData.EntryColumns.FEED_ID).append('=').append(uri.getPathSegments().get(1));
				break;
			}
			case URI_ALLENTRIES: {
				table = TABLE_ENTRIES;
				break;
			}
			case URI_FAVORITES_ENTRY :
			case URI_ALLENTRIES_ENTRY : {
				table = TABLE_ENTRIES;
				where.append(FeedData.EntryColumns._ID).append('=').append(uri.getPathSegments().get(1));
				break;
			}
			case URI_FAVORITES : {
				table = TABLE_ENTRIES;
				where.append(FeedData.EntryColumns.FAVORITE).append(EQUALS_ONE);
				break;
			}
		}
		
		if (!TextUtils.isEmpty(selection)) {
			if (where.length() > 0) {
				where.append(Strings.DB_AND).append(selection);
			} else {
				where.append(selection);
			}
		}
		
		int count = database.update(table, values, where.toString(), selectionArgs);
		
		if (table == TABLE_FEEDS && (values.containsKey(FeedData.FeedColumns.NAME) || values.containsKey(FeedData.FeedColumns.URL) || values.containsKey(FeedData.FeedColumns.PRIORITY))) { // == is ok here
			OPML.exportToFile(BACKUPOPML, database);
		}
		if (count > 0) {
			getContext().getContentResolver().notifyChange(uri, null);
		}
		return count;
	}

}
