package ca.teamTen.recitopia;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;

/**
 * Basic searching activity. Displays search form and results list.
 * 
 * If this activity is launched with a string in the "QUERY" extra, it will
 * launch a query with the provided string immediately upon starting.
 * 
 * Queries are executed asynchronously using AsyncTask.
 */
public class SearchActivity extends Activity implements OnItemClickListener {

	private Recipe[] recipes;
	private ListView recipeListView;
	private EditText searchField;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_search);
		recipeListView = (ListView)findViewById(R.id.resultsList);
		recipeListView.setOnItemClickListener(this);
		recipeListView.setEmptyView(findViewById(R.id.placeholder));
		searchField = (EditText)findViewById(R.id.searchField);
		
		// TODO: add progress spinner or something

		// check for query extra, launch query if it is present
		Intent intent = getIntent();
		if (intent.hasExtra("QUERY")) {
			String query = intent.getStringExtra("QUERY");
			searchField.setText(query);
			executeQuery(query);
		}
	}

	/**
	 * Called when the search button is pressed
	 * @param button
	 */
	public void onSearch(View button) {
		executeQuery(searchField.getText().toString());
	}
	
	/**
	 * Executes a query asynchronously
	 * @param query
	 */
	private void executeQuery(String query) {
		new QueryTask(ApplicationManager.getInstance(getApplication()))
			.execute(query);
	}
	
	/**
	 * Updates list view with new query results.
	 */
	private void displayQueryResults(Recipe[] recipes) {
		ListAdapter adapter = new ArrayAdapter<String>(
				this,
				android.R.layout.simple_list_item_activated_1,
				android.R.id.text1,
				makeListItems(recipes));

		recipeListView.setAdapter(adapter);
	}

	/**
	 * Launches RecipeViewActivity when a recipe is clicked.
	 */
	@Override
	public void onItemClick(AdapterView<?> adapter, View v, int position, long id) {
		Recipe recipe = this.recipes[position];

		Intent viewIntent = new Intent(this, RecipeViewActivity.class);
		viewIntent.putExtra("RECIPE", recipe);

		startActivity(viewIntent);
	}

	/*
	 * Makes an array of strings for displaying the given recipes.
	 */
	private String[] makeListItems(Recipe[] recipes) {
		String[] result = new String[recipes.length];

		for (int i = 0; i < recipes.length; i++) {
			result[i] = recipes[i].getRecipeName() + "\n" + recipes[i].getAuthor();
		}
		return result;
	}
	
	/*
	 * AsyncTask for running search queries.
	 */
	private class QueryTask extends AsyncTask<String, Void, Recipe[]> {
		ApplicationManager appMgr;
		
		QueryTask(ApplicationManager appMgr) {
			this.appMgr = appMgr;
		}

		@Override
		protected void onPreExecute() {
			// TODO show progress bar or something
		}
		
		@Override
		protected Recipe[] doInBackground(String... queryStrings) {
			return getRecipeBookForQuerying().query(queryStrings[0]);
		}
		
		@Override
		protected void onPostExecute(Recipe[] result) {
			displayQueryResults(result);
		}
		
		/*
		 * Returns a composite recipe book, using CloudRecipeBook.isAvailable() to
		 * determine whether we should use the cloud recipe book.
		 */
		private RecipeBook getRecipeBookForQuerying() {
			CloudRecipeBook cloudBook = (CloudRecipeBook) appMgr.getCloudRecipeBook();
			if (cloudBook.isAvailable()) {
				return new CompositeRecipeBook(
					new RecipeBook[] {cloudBook, appMgr.getUserRecipeBook()});
			} else {
				return new CompositeRecipeBook(new RecipeBook[] { 
					appMgr.getUserRecipeBook(),
					appMgr.getFavoriteRecipesBook(),
					appMgr.getCacheRecipeBook()
				});
			}
		}
	}
	
	/*
	 * RecipeBook implementation that combines the search results of
	 * multiple RecipeBooks.
	 */
	private static class CompositeRecipeBook implements RecipeBook {
		private RecipeBook books[];
		
		CompositeRecipeBook(RecipeBook books[]) {
			this.books = books;
		}

		@Override
		public Recipe[] query(String searchTerms) {
			ArrayList<Recipe[]> results = new ArrayList<Recipe[]>();
			int totalCount = 0;
			
			for (RecipeBook book: books) {
				Recipe[] recipes = book.query(searchTerms);
				totalCount += recipes.length;
				results.add(recipes);
			}
			Recipe[] allRecipes = new Recipe[totalCount];
			int recipesAdded = 0;
			for (Recipe[] singleResult: results) {
				System.arraycopy(singleResult, 0, allRecipes, recipesAdded, singleResult.length);
				recipesAdded += singleResult.length;
			}
			
			return allRecipes;
		}

		@Override
		public void addRecipe(Recipe recipe) {
			throw new UnsupportedOperationException("addRecipe unsupported");			
		}

		@Override
		public void save() {
			throw new UnsupportedOperationException("save unsupported");
		}
	}
}
@@ -1940,30 +1940,15 @@
 %09 * 
-Updates list view with
+Handles
  new
@@ -1982,24 +1982,17 @@
 te void 
-displayQ
+q
 ueryResu
@@ -1994,16 +1994,24 @@
 yResults
+Received
 (Recipe%5B
@@ -2023,16 +2023,42 @@
 ipes) %7B%0A
+%09%09this.recipes = recipes;%0A
 %09%09ListAd
@@ -3450,16 +3450,9 @@
 %0A%09%09%09
-displayQ
+q
 uery
@@ -3458,16 +3458,24 @@
 yResults
+Received
 (result)
@@ -4585,16 +4585,44 @@
 Terms);%0A
+%09%09%09%09if (recipes != null) %7B%0A%09
 %09%09%09%09tota
@@ -4651,16 +4651,17 @@
 th;%0A%09%09%09%09
+%09
 results.
@@ -4674,16 +4674,22 @@
 cipes);%0A
+%09%09%09%09%7D%0A
 %09%09%09%7D%0A%09%09%09

Fix bug: forgot to assign query results to member